diff --git a/src/Makefile.am b/src/Makefile.am
index ca5a722c72..67f5576aee 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,678 +1,679 @@
 # Copyright (c) 2013-2016 The Bitcoin Core developers
 # Distributed under the MIT software license, see the accompanying
 # file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 DIST_SUBDIRS = secp256k1 univalue
 
 AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) $(SANITIZER_LDFLAGS)
 AM_CXXFLAGS = $(DEBUG_CXXFLAGS) $(HARDENED_CXXFLAGS) $(ERROR_CXXFLAGS) $(SANITIZER_CXXFLAGS)
 AM_CPPFLAGS = $(DEBUG_CPPFLAGS) $(HARDENED_CPPFLAGS)
 AM_LIBTOOLFLAGS = --preserve-dup-deps
 EXTRA_LIBRARIES =
 
 if EMBEDDED_UNIVALUE
 LIBUNIVALUE = univalue/libunivalue.la
 
 $(LIBUNIVALUE): $(wildcard univalue/lib/*) $(wildcard univalue/include/*)
 	$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F)
 else
 LIBUNIVALUE = $(UNIVALUE_LIBS)
 endif
 
 BITCOIN_INCLUDES=-I$(builddir) $(BDB_CPPFLAGS) $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS)
 
 BITCOIN_INCLUDES += -I$(srcdir)/secp256k1/include
 BITCOIN_INCLUDES += $(UNIVALUE_CFLAGS)
 
 BITCOIN_SEEDER_INCLUDES = -I$(srcdir)/seeder
 BITCOIN_SEEDER_INCLUDES += $(BITCOIN_INCLUDES)
 
 LIBBITCOIN_SERVER=libbitcoin_server.a
 LIBBITCOIN_COMMON=libbitcoin_common.a
 LIBBITCOIN_CONSENSUS=libbitcoin_consensus.a
 LIBBITCOIN_CLI=libbitcoin_cli.a
 LIBBITCOIN_UTIL=libbitcoin_util.a
 LIBBITCOIN_CRYPTO_BASE=crypto/libbitcoin_crypto_base.a
 LIBBITCOINQT=qt/libbitcoinqt.a
 LIBSECP256K1=secp256k1/libsecp256k1.la
 
 if ENABLE_ZMQ
 LIBBITCOIN_ZMQ=libbitcoin_zmq.a
 endif
 if BUILD_BITCOIN_LIBS
 LIBBITCOINCONSENSUS=libbitcoinconsensus.la
 endif
 if BUILD_BITCOIN_SEEDER
 LIBBITCOIN_SEEDER=libbitcoin_seeder.a
 endif
 if ENABLE_WALLET
 LIBBITCOIN_WALLET=libbitcoin_wallet.a
 endif
 
 LIBBITCOIN_CRYPTO= $(LIBBITCOIN_CRYPTO_BASE)
 if ENABLE_SSE41
 LIBBITCOIN_CRYPTO_SSE41 = crypto/libbitcoin_crypto_sse41.a
 LIBBITCOIN_CRYPTO += $(LIBBITCOIN_CRYPTO_SSE41)
 endif
 if ENABLE_AVX2
 LIBBITCOIN_CRYPTO_AVX2 = crypto/libbitcoin_crypto_avx2.a
 LIBBITCOIN_CRYPTO += $(LIBBITCOIN_CRYPTO_AVX2)
 endif
 if ENABLE_SHANI
 LIBBITCOIN_CRYPTO_SHANI = crypto/libbitcoin_crypto_shani.a
 LIBBITCOIN_CRYPTO += $(LIBBITCOIN_CRYPTO_SHANI)
 endif
 
 $(LIBSECP256K1): $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*)
 	$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F)
 
 # Make is not made aware of per-object dependencies to avoid limiting building parallelization
 # But to build the less dependent modules first, we manually select their order here:
 EXTRA_LIBRARIES += \
   $(LIBBITCOIN_CRYPTO) \
   $(LIBBITCOIN_UTIL) \
   $(LIBBITCOIN_COMMON) \
   $(LIBBITCOIN_CONSENSUS) \
   $(LIBBITCOIN_SERVER) \
   $(LIBBITCOIN_CLI) \
   $(LIBBITCOIN_SEEDER) \
   $(LIBBITCOIN_WALLET) \
   $(LIBBITCOIN_ZMQ)
 
 lib_LTLIBRARIES = $(LIBBITCOINCONSENSUS)
 
 bin_PROGRAMS =
 noinst_PROGRAMS =
 TESTS =
 BENCHMARKS =
 
 if BUILD_BITCOIND
   bin_PROGRAMS += bitcoind
 endif
 
 if BUILD_BITCOIN_SEEDER
   bin_PROGRAMS += bitcoin-seeder
 endif
 
 if BUILD_BITCOIN_UTILS
   bin_PROGRAMS += bitcoin-cli bitcoin-tx
 endif
 
 .PHONY: FORCE check-symbols check-security
 # bitcoin core #
 BITCOIN_CORE_H = \
   addrdb.h \
   addrman.h \
   avalanche.h \
   base58.h \
   bloom.h \
   blockencodings.h \
   blockfileinfo.h \
   blockfilter.h \
   blockindexworkcomparator.h \
   blockstatus.h \
   blockvalidity.h \
   cashaddr.h \
   cashaddrenc.h \
   chain.h \
   chainparams.h \
   chainparamsbase.h \
   chainparamsseeds.h \
   checkpoints.h \
   checkqueue.h \
   clientversion.h \
   coins.h \
   compat.h \
   compat/byteswap.h \
   compat/endian.h \
   compat/sanity.h \
   compat/setenv.h \
   compressor.h \
   config.h \
   consensus/activation.h \
   consensus/consensus.h \
   consensus/tx_verify.h \
   core_io.h \
   core_memusage.h \
   cuckoocache.h \
   flatfile.h \
   fs.h \
   globals.h \
   httprpc.h \
   httpserver.h \
   index/base.h \
   index/txindex.h \
   indirectmap.h \
   init.h \
   interfaces/handler.h \
   interfaces/node.h \
   interfaces/wallet.h \
   key.h \
   key_io.h \
   keystore.h \
   dbwrapper.h \
   limitedmap.h \
   logging.h \
   memusage.h \
   merkleblock.h \
   miner.h \
   net.h \
   net_processing.h \
   netaddress.h \
   netbase.h \
   netmessagemaker.h \
   noui.h \
   policy/fees.h \
   policy/policy.h \
   pow.h \
   protocol.h \
   radix.h \
   random.h \
   rcu.h \
   reverse_iterator.h \
   reverselock.h \
   rpc/blockchain.h \
   rpc/client.h \
   rpc/command.h \
   rpc/jsonrpcrequest.h \
   rpc/mining.h \
   rpc/misc.h \
   rpc/protocol.h \
   rpc/rawtransaction.h \
   rpc/server.h \
   rpc/register.h \
   rpc/util.h \
   rwcollection.h \
   scheduler.h \
   script/scriptcache.h \
   script/ismine.h \
   script/sigcache.h \
   script/sign.h \
   script/standard.h \
   streams.h \
   support/allocators/secure.h \
   support/allocators/zeroafterfree.h \
   support/cleanse.h \
   support/events.h \
   support/lockedpool.h \
   sync.h \
   threadsafety.h \
   threadinterrupt.h \
   timedata.h \
   torcontrol.h \
   txdb.h \
   txmempool.h \
   ui_interface.h \
   undo.h \
   util.h \
   utilmoneystr.h \
   utiltime.h \
+  util/bitmanip.h \
   util/bytevectorhash.h \
   validation.h \
   validationinterface.h \
   versionbits.h \
   walletinitinterface.h \
   wallet/coincontrol.h \
   wallet/coinselection.h \
   wallet/crypter.h \
   wallet/db.h \
   wallet/finaltx.h \
   wallet/rpcdump.h \
   wallet/fees.h \
   wallet/rpcwallet.h \
   wallet/wallet.h \
   wallet/walletdb.h \
   wallet/walletutil.h \
   warnings.h \
   zmq/zmqabstractnotifier.h \
   zmq/zmqconfig.h\
   zmq/zmqnotificationinterface.h \
   zmq/zmqpublishnotifier.h
 
 
 obj/build.h: FORCE
 	@$(MKDIR_P) "$(builddir)/obj"
 	@$(top_srcdir)/share/genbuild.sh "$(abs_top_builddir)/src/obj/build.h" \
 	  "$(abs_top_srcdir)"
 libbitcoin_util_a-clientversion.$(OBJEXT): obj/build.h
 
 # server: shared between bitcoind and bitcoin-qt
 libbitcoin_server_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS)
 libbitcoin_server_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
 libbitcoin_server_a_SOURCES = \
   addrman.cpp \
   addrdb.cpp \
   avalanche.cpp \
   bloom.cpp \
   blockencodings.cpp \
   blockfilter.cpp \
   chain.cpp \
   checkpoints.cpp \
   config.cpp \
   consensus/activation.cpp \
   consensus/tx_verify.cpp \
   flatfile.cpp \
   globals.cpp \
   httprpc.cpp \
   httpserver.cpp \
   index/base.cpp \
   index/txindex.cpp \
   init.cpp \
   interfaces/handler.cpp \
   interfaces/node.cpp \
   dbwrapper.cpp \
   merkleblock.cpp \
   miner.cpp \
   net.cpp \
   net_processing.cpp \
   noui.cpp \
   policy/fees.cpp \
   policy/policy.cpp \
   pow.cpp \
   rest.cpp \
   rpc/abc.cpp \
   rpc/blockchain.cpp \
   rpc/command.cpp \
   rpc/jsonrpcrequest.cpp \
   rpc/mining.cpp \
   rpc/misc.cpp \
   rpc/net.cpp \
   rpc/rawtransaction.cpp \
   rpc/server.cpp \
   script/scriptcache.cpp \
   script/sigcache.cpp \
   timedata.cpp \
   torcontrol.cpp \
   txdb.cpp \
   txmempool.cpp \
   ui_interface.cpp \
   validation.cpp \
   validationinterface.cpp \
   $(BITCOIN_CORE_H)
 
 if ENABLE_ZMQ
 libbitcoin_zmq_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(ZMQ_CFLAGS)
 libbitcoin_zmq_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
 libbitcoin_zmq_a_SOURCES = \
   zmq/zmqabstractnotifier.cpp \
   zmq/zmqnotificationinterface.cpp \
   zmq/zmqpublishnotifier.cpp
 endif
 
 
 # wallet: shared between bitcoind and bitcoin-qt, but only linked
 # when wallet enabled
 libbitcoin_wallet_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
 libbitcoin_wallet_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
 libbitcoin_wallet_a_SOURCES = \
   interfaces/wallet.cpp \
   wallet/coincontrol.cpp \
   wallet/crypter.cpp \
   wallet/coinselection.cpp \
   wallet/db.cpp \
   wallet/finaltx.cpp \
   wallet/fees.cpp \
   wallet/init.cpp \
   wallet/rpcdump.cpp \
   wallet/rpcwallet.cpp \
   wallet/wallet.cpp \
   wallet/walletdb.cpp \
   wallet/walletutil.cpp \
   $(BITCOIN_CORE_H)
 
 # crypto primitives library
 crypto_libbitcoin_crypto_base_a_CPPFLAGS = $(AM_CPPFLAGS)
 crypto_libbitcoin_crypto_base_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
 crypto_libbitcoin_crypto_base_a_SOURCES = \
   crypto/aes.cpp \
   crypto/aes.h \
   crypto/chacha20.h \
   crypto/chacha20.cpp \
   crypto/common.h \
   crypto/hmac_sha256.cpp \
   crypto/hmac_sha256.h \
   crypto/hmac_sha512.cpp \
   crypto/hmac_sha512.h \
   crypto/ripemd160.cpp \
   crypto/ripemd160.h \
   crypto/sha1.cpp \
   crypto/sha1.h \
   crypto/sha256.cpp \
   crypto/sha256.h \
   crypto/sha512.cpp \
   crypto/sha512.h \
   crypto/siphash.cpp \
   crypto/siphash.h
 
 if USE_ASM
 crypto_libbitcoin_crypto_base_a_SOURCES += crypto/sha256_sse4.cpp
 endif
 
 crypto_libbitcoin_crypto_sse41_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
 crypto_libbitcoin_crypto_sse41_a_CPPFLAGS = $(AM_CPPFLAGS)
 crypto_libbitcoin_crypto_sse41_a_CXXFLAGS += $(SSE41_CXXFLAGS)
 crypto_libbitcoin_crypto_sse41_a_CPPFLAGS += -DENABLE_SSE41
 crypto_libbitcoin_crypto_sse41_a_SOURCES = crypto/sha256_sse41.cpp
 
 crypto_libbitcoin_crypto_avx2_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
 crypto_libbitcoin_crypto_avx2_a_CPPFLAGS = $(AM_CPPFLAGS)
 crypto_libbitcoin_crypto_avx2_a_CXXFLAGS += $(AVX2_CXXFLAGS)
 crypto_libbitcoin_crypto_avx2_a_CPPFLAGS += -DENABLE_AVX2
 crypto_libbitcoin_crypto_avx2_a_SOURCES = crypto/sha256_avx2.cpp
 
 crypto_libbitcoin_crypto_shani_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
 crypto_libbitcoin_crypto_shani_a_CPPFLAGS = $(AM_CPPFLAGS)
 crypto_libbitcoin_crypto_shani_a_CXXFLAGS += $(SHANI_CXXFLAGS)
 crypto_libbitcoin_crypto_shani_a_CPPFLAGS += -DENABLE_SHANI
 crypto_libbitcoin_crypto_shani_a_SOURCES = crypto/sha256_shani.cpp
 
 # consensus: shared between all executables that validate any consensus rules.
 libbitcoin_consensus_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
 libbitcoin_consensus_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
 libbitcoin_consensus_a_SOURCES = \
   amount.h \
   arith_uint256.cpp \
   arith_uint256.h \
   consensus/merkle.cpp \
   consensus/merkle.h \
   consensus/params.h \
   consensus/validation.h \
   feerate.h \
   hash.cpp \
   hash.h \
   prevector.h \
   primitives/block.cpp \
   primitives/block.h \
   primitives/transaction.cpp \
   primitives/transaction.h \
   primitives/txid.h \
   pubkey.cpp \
   pubkey.h \
   script/bitcoinconsensus.cpp \
   script/bitfield.cpp \
   script/bitfield.h \
   script/sighashtype.h \
   script/interpreter.cpp \
   script/interpreter.h \
   script/script.cpp \
   script/script.h \
   script/script_error.cpp \
   script/script_error.h \
   script/script_flags.h \
   script/sigencoding.cpp \
   script/sigencoding.h \
   serialize.h \
   tinyformat.h \
   uint256.cpp \
   uint256.h \
   utilstrencodings.cpp \
   utilstrencodings.h \
   version.h
 
 # common: shared between bitcoind, and bitcoin-qt and non-server tools
 libbitcoin_common_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
 libbitcoin_common_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
 libbitcoin_common_a_SOURCES = \
   amount.cpp \
   base58.cpp \
   cashaddr.cpp \
   cashaddrenc.cpp \
   chainparams.cpp \
   config.cpp \
   coins.cpp \
   compressor.cpp \
   feerate.cpp \
   globals.cpp \
   core_read.cpp \
   core_write.cpp \
   key.cpp \
   key_io.cpp \
   keystore.cpp \
   netaddress.cpp \
   netbase.cpp \
   protocol.cpp \
   scheduler.cpp \
   script/ismine.cpp \
   script/sign.cpp \
   script/standard.cpp \
   warnings.cpp \
   $(BITCOIN_CORE_H)
 
 # util: shared between all executables.
 # This library *must* be included to make sure that the glibc
 # backward-compatibility objects and their sanity checks are linked.
 libbitcoin_util_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
 libbitcoin_util_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
 libbitcoin_util_a_SOURCES = \
   support/lockedpool.cpp \
   chainparamsbase.cpp \
   clientversion.cpp \
   compat/glibc_sanity.cpp \
   compat/glibcxx_sanity.cpp \
   compat/strnlen.cpp \
   fs.cpp \
   logging.cpp \
   random.cpp \
   rcu.cpp \
   rpc/protocol.cpp \
   rpc/util.cpp \
   support/cleanse.cpp \
   sync.cpp \
   threadinterrupt.cpp \
   uint256.cpp \
   uint256.h \
   util.cpp \
   utilmoneystr.cpp \
   utilstrencodings.cpp \
   utiltime.cpp \
   util/bytevectorhash.cpp \
   $(BITCOIN_CORE_H)
 
 if GLIBC_BACK_COMPAT
 libbitcoin_util_a_SOURCES += compat/glibc_compat.cpp
 AM_LDFLAGS += $(COMPAT_LDFLAGS)
 endif
 
 # cli: shared between bitcoin-cli and bitcoin-qt
 libbitcoin_cli_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
 libbitcoin_cli_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
 libbitcoin_cli_a_SOURCES = \
   rpc/client.cpp \
   $(BITCOIN_CORE_H)
 
 # seeder library
 libbitcoin_seeder_a_CPPFLAGS = $(AM_CPPFLAGS) $(PIE_FLAGS) $(BITCOIN_SEEDER_INCLUDES)
 libbitcoin_seeder_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
 libbitcoin_seeder_a_SOURCES = \
   seeder/bitcoin.cpp \
   seeder/bitcoin.h \
   seeder/db.cpp \
   seeder/db.h \
   seeder/dns.cpp \
   seeder/dns.h \
   seeder/strlcpy.h \
   seeder/util.h
 
 nodist_libbitcoin_util_a_SOURCES = $(srcdir)/obj/build.h
 #
 
 # bitcoind binary #
 bitcoind_SOURCES = bitcoind.cpp
 bitcoind_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
 bitcoind_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
 bitcoind_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
 
 if TARGET_WINDOWS
 bitcoind_SOURCES += bitcoind-res.rc
 endif
 
 bitcoind_LDADD = \
   $(LIBBITCOIN_SERVER) \
   $(LIBBITCOIN_WALLET) \
   $(LIBBITCOIN_COMMON) \
   $(LIBUNIVALUE) \
   $(LIBBITCOIN_UTIL) \
   $(LIBBITCOIN_ZMQ) \
   $(LIBBITCOIN_CONSENSUS) \
   $(LIBBITCOIN_CRYPTO) \
   $(LIBLEVELDB) \
   $(LIBLEVELDB_SSE42) \
   $(LIBMEMENV) \
   $(LIBSECP256K1)
 
 bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS)
 
 # bitcoin-cli binary #
 bitcoin_cli_SOURCES = bitcoin-cli.cpp
 bitcoin_cli_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CFLAGS)
 bitcoin_cli_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
 bitcoin_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
 
 if TARGET_WINDOWS
 bitcoin_cli_SOURCES += bitcoin-cli-res.rc
 endif
 
 bitcoin_cli_LDADD = \
   $(LIBBITCOIN_CLI) \
   $(LIBUNIVALUE) \
   $(LIBBITCOIN_UTIL) \
   $(LIBBITCOIN_CRYPTO)
 
 bitcoin_cli_LDADD += $(BOOST_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_LIBS)
 #
 
 # bitcoin-seeder binary #
 bitcoin_seeder_SOURCES = seeder/main.cpp
 bitcoin_seeder_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_SEEDER_INCLUDES)
 bitcoin_seeder_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
 bitcoin_seeder_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
 
 bitcoin_seeder_LDADD = \
   $(LIBBITCOIN_SEEDER) \
   $(LIBBITCOIN_COMMON) \
   $(LIBBITCOIN_UTIL) \
   $(LIBBITCOIN_CRYPTO)
 
 bitcoin_seeder_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS)
 #
 
 # bitcoin-tx binary #
 bitcoin_tx_SOURCES = bitcoin-tx.cpp
 bitcoin_tx_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
 bitcoin_tx_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
 bitcoin_tx_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
 
 if TARGET_WINDOWS
 bitcoin_tx_SOURCES += bitcoin-tx-res.rc
 endif
 
 bitcoin_tx_LDADD = \
   $(LIBUNIVALUE) \
   $(LIBBITCOIN_COMMON) \
   $(LIBBITCOIN_UTIL) \
   $(LIBBITCOIN_CONSENSUS) \
   $(LIBBITCOIN_CRYPTO) \
   $(LIBSECP256K1)
 
 bitcoin_tx_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS)
 #
 
 # bitcoinconsensus library #
 if BUILD_BITCOIN_LIBS
 include_HEADERS = script/bitcoinconsensus.h
 libbitcoinconsensus_la_SOURCES = $(crypto_libbitcoin_crypto_base_a_SOURCES) $(libbitcoin_consensus_a_SOURCES)
 
 if GLIBC_BACK_COMPAT
   libbitcoinconsensus_la_SOURCES += compat/glibc_compat.cpp
 endif
 
 libbitcoinconsensus_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined $(RELDFLAGS)
 libbitcoinconsensus_la_LIBADD = $(LIBSECP256K1)
 libbitcoinconsensus_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(builddir)/obj -I$(srcdir)/secp256k1/include -DBUILD_BITCOIN_INTERNAL
 libbitcoinconsensus_la_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
 
 endif
 #
 
 CTAES_DIST =  crypto/ctaes/bench.c
 CTAES_DIST += crypto/ctaes/ctaes.c
 CTAES_DIST += crypto/ctaes/ctaes.h
 CTAES_DIST += crypto/ctaes/README.md
 CTAES_DIST += crypto/ctaes/test.c
 
 CLEANFILES = $(EXTRA_LIBRARIES)
 
 CLEANFILES += *.gcda *.gcno
 CLEANFILES += compat/*.gcda compat/*.gcno
 CLEANFILES += consensus/*.gcda consensus/*.gcno
 CLEANFILES += crypto/*.gcda crypto/*.gcno
 CLEANFILES += policy/*.gcda policy/*.gcno
 CLEANFILES += primitives/*.gcda primitives/*.gcno
 CLEANFILES += script/*.gcda script/*.gcno
 CLEANFILES += support/*.gcda support/*.gcno
 CLEANFILES += univalue/*.gcda univalue/*.gcno
 CLEANFILES += wallet/*.gcda wallet/*.gcno
 CLEANFILES += wallet/test/*.gcda wallet/test/*.gcno
 CLEANFILES += zmq/*.gcda zmq/*.gcno
 CLEANFILES += obj/build.h
 
 EXTRA_DIST = $(CTAES_DIST)
 
 
 config/bitcoin-config.h: config/stamp-h1
 	@$(MAKE) -C $(top_builddir) $(subdir)/$(@)
 config/stamp-h1: $(top_srcdir)/$(subdir)/config/bitcoin-config.h.in $(top_builddir)/config.status
 	$(AM_V_at)$(MAKE) -C $(top_builddir) $(subdir)/$(@)
 $(top_srcdir)/$(subdir)/config/bitcoin-config.h.in:  $(am__configure_deps)
 	$(AM_V_at)$(MAKE) -C $(top_srcdir) $(subdir)/config/bitcoin-config.h.in
 
 clean-local:
 	-$(MAKE) -C secp256k1 clean
 	-$(MAKE) -C univalue clean
 	-rm -f leveldb/*/*.gcda leveldb/*/*.gcno leveldb/helpers/memenv/*.gcda leveldb/helpers/memenv/*.gcno
 	-rm -rf test/__pycache__
 
 .rc.o:
 	@test -f $(WINDRES)
 	## FIXME: How to get the appropriate modulename_CPPFLAGS in here?
 	$(AM_V_GEN) $(WINDRES) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) -DWINDRES_PREPROC -i $< -o $@
 
 .mm.o:
 	$(AM_V_CXX) $(OBJCXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
 	  $(CPPFLAGS) $(AM_CXXFLAGS) $(QT_INCLUDES) $(AM_CXXFLAGS) $(PIE_FLAGS) $(CXXFLAGS) -c -o $@ $<
 
 check-symbols: $(bin_PROGRAMS)
 if GLIBC_BACK_COMPAT
 	@echo "Checking glibc back compat..."
 	$(AM_V_at) READELF=$(READELF) CPPFILT=$(CPPFILT) $(top_srcdir)/contrib/devtools/symbol-check.py < $(bin_PROGRAMS)
 endif
 
 check-security: $(bin_PROGRAMS)
 if HARDEN
 	@echo "Checking binary security..."
 	$(AM_V_at) READELF=$(READELF) OBJDUMP=$(OBJDUMP) $(top_srcdir)/contrib/devtools/security-check.py < $(bin_PROGRAMS)
 endif
 
 %.pb.cc %.pb.h: %.proto
 	@test -f $(PROTOC)
 	$(AM_V_GEN) $(PROTOC) --cpp_out=$(@D) --proto_path=$(<D) $<
 
 if EMBEDDED_LEVELDB
 include Makefile.leveldb.include
 endif
 
 if ENABLE_TESTS
 include Makefile.test.include
 endif
 
 if ENABLE_BENCH
 include Makefile.bench.include
 endif
 
 if ENABLE_QT
 include Makefile.qt.include
 endif
 
 if ENABLE_QT_TESTS
 include Makefile.qttest.include
 endif
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index 68aac9fadc..d75a642fe2 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -1,220 +1,221 @@
 # Copyright (c) 2013-2016 The Bitcoin Core developers
 # Distributed under the MIT software license, see the accompanying
 # file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 bin_PROGRAMS += test/test_bitcoin
 noinst_PROGRAMS += test/test_bitcoin_fuzzy
 TEST_SRCDIR = test
 TEST_BINARY=test/test_bitcoin$(EXEEXT)
 
 JSON_TEST_FILES = \
   test/data/base58_encode_decode.json \
   test/data/blockfilters.json \
   test/data/key_io_valid.json \
   test/data/key_io_invalid.json \
   test/data/script_tests.json \
   test/data/sighash.json \
   test/data/tx_invalid.json \
   test/data/tx_valid.json
 
 RAW_TEST_FILES =
 
 GENERATED_TEST_FILES = $(JSON_TEST_FILES:.json=.json.h) $(RAW_TEST_FILES:.raw=.raw.h)
 
 BITCOIN_TEST_SUITE = \
   test/jsonutil.cpp \
   test/scriptflags.cpp \
   test/sigutil.cpp \
   test/test_bitcoin_main.cpp \
   test/test_bitcoin.h \
   test/test_bitcoin.cpp
 
 # test_bitcoin binary #
 BITCOIN_TESTS =\
   test/scriptnum10.h \
   test/activation_tests.cpp \
   test/addrman_tests.cpp \
   test/allocator_tests.cpp \
   test/amount_tests.cpp \
   test/arith_uint256_tests.cpp \
   test/avalanche_tests.cpp \
   test/base32_tests.cpp \
   test/base58_tests.cpp \
   test/base64_tests.cpp \
   test/bip32_tests.cpp \
+  test/bitmanip_tests.cpp \
   test/blockchain_tests.cpp \
   test/blockcheck_tests.cpp \
   test/blockencodings_tests.cpp \
   test/blockfilter_tests.cpp \
   test/blockindex_tests.cpp \
   test/blockstatus_tests.cpp \
   test/bloom_tests.cpp \
   test/bswap_tests.cpp \
   test/cashaddr_tests.cpp \
   test/cashaddrenc_tests.cpp \
   test/checkdatasig_tests.cpp \
   test/checkpoints_tests.cpp \
   test/checkqueue_tests.cpp \
   test/coins_tests.cpp \
   test/compress_tests.cpp \
   test/config_tests.cpp \
   test/core_io_tests.cpp \
   test/crypto_tests.cpp \
   test/cuckoocache_tests.cpp \
   test/dbwrapper_tests.cpp \
   test/denialofservice_tests.cpp \
   test/dstencode_tests.cpp \
   test/excessiveblock_tests.cpp \
   test/feerate_tests.cpp \
   test/finalization_tests.cpp \
   test/flatfile_tests.cpp \
   test/getarg_tests.cpp \
   test/hash_tests.cpp \
   test/inv_tests.cpp \
   test/jsonutil.h \
   test/key_io_tests.cpp \
   test/key_tests.cpp \
   test/lcg_tests.cpp \
   test/lcg.h \
   test/limitedmap_tests.cpp \
   test/main_tests.cpp \
   test/mempool_tests.cpp \
   test/merkle_tests.cpp \
   test/miner_tests.cpp \
   test/monolith_opcodes_tests.cpp \
   test/multisig_tests.cpp \
   test/net_tests.cpp \
   test/netbase_tests.cpp \
   test/pmt_tests.cpp \
   test/policyestimator_tests.cpp \
   test/pow_tests.cpp \
   test/prevector_tests.cpp \
   test/radix_tests.cpp \
   test/raii_event_tests.cpp \
   test/random_tests.cpp \
   test/rcu_tests.cpp \
   test/reverselock_tests.cpp \
   test/rpc_tests.cpp \
   test/rpc_server_tests.cpp \
   test/rwcollection_tests.cpp \
   test/sanity_tests.cpp \
   test/scheduler_tests.cpp \
   test/schnorr_tests.cpp \
   test/script_commitment_tests.cpp \
   test/script_bitfield_tests.cpp \
   test/script_p2sh_tests.cpp \
   test/script_standard_tests.cpp \
   test/script_tests.cpp \
   test/scriptflags.h \
   test/scriptnum_tests.cpp \
   test/serialize_tests.cpp \
   test/sigcache_tests.cpp \
   test/sigencoding_tests.cpp \
   test/sighash_tests.cpp \
   test/sighashtype_tests.cpp \
   test/sigopcount_tests.cpp \
   test/sigutil.h \
   test/skiplist_tests.cpp \
   test/streams_tests.cpp \
   test/sync_tests.cpp \
   test/timedata_tests.cpp \
   test/torcontrol_tests.cpp \
   test/transaction_tests.cpp \
   test/txindex_tests.cpp \
   test/txvalidation_tests.cpp \
   test/txvalidationcache_tests.cpp \
   test/uint256_tests.cpp \
   test/undo_tests.cpp \
   test/util_tests.cpp \
   test/validation_block_tests.cpp \
   test/validation_tests.cpp \
   test/work_comparator_tests.cpp \
   rpc/test/server_tests.cpp
 
 if ENABLE_WALLET
 BITCOIN_TESTS += \
   wallet/test/accounting_tests.cpp \
   wallet/test/wallet_tests.cpp \
   wallet/test/walletdb_tests.cpp \
   wallet/test/wallet_crypto_tests.cpp \
   wallet/test/coinselector_tests.cpp
 
 BITCOIN_TEST_SUITE += \
   wallet/test/wallet_test_fixture.cpp \
   wallet/test/wallet_test_fixture.h
 endif
 
 test_test_bitcoin_SOURCES = $(BITCOIN_TEST_SUITE) $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES)
 test_test_bitcoin_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(TESTDEFS) $(EVENT_CFLAGS)
 test_test_bitcoin_LDADD =
 if ENABLE_WALLET
 test_test_bitcoin_LDADD += $(LIBBITCOIN_WALLET)
 endif
 
 test_test_bitcoin_LDADD += $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) \
   $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS)
 test_test_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
 
 test_test_bitcoin_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS)
 test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static
 
 if ENABLE_ZMQ
 test_test_bitcoin_LDADD += $(ZMQ_LIBS)
 endif
 #
 
 # test_bitcoin_fuzzy binary #
 test_test_bitcoin_fuzzy_SOURCES = test/test_bitcoin_fuzzy.cpp
 test_test_bitcoin_fuzzy_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
 test_test_bitcoin_fuzzy_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
 test_test_bitcoin_fuzzy_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
 
 test_test_bitcoin_fuzzy_LDADD = \
   $(LIBUNIVALUE) \
   $(LIBBITCOIN_SERVER) \
   $(LIBBITCOIN_COMMON) \
   $(LIBBITCOIN_UTIL) \
   $(LIBBITCOIN_CONSENSUS) \
   $(LIBBITCOIN_CRYPTO) \
   $(LIBSECP256K1)
 
 test_test_bitcoin_fuzzy_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS)
 #
 
 nodist_test_test_bitcoin_SOURCES = $(GENERATED_TEST_FILES)
 
 $(BITCOIN_TESTS): $(GENERATED_TEST_FILES)
 
 CLEAN_BITCOIN_TEST = test/*.gcda test/*.gcno $(GENERATED_TEST_FILES)
 
 CLEANFILES += $(CLEAN_BITCOIN_TEST)
 
 bitcoin_test: $(TEST_BINARY)
 
 bitcoin_test_check: $(TEST_BINARY) FORCE
 	$(MAKE) check-TESTS TESTS=$^
 
 bitcoin_test_clean : FORCE
 	rm -f $(CLEAN_BITCOIN_TEST) $(test_test_bitcoin_OBJECTS) $(TEST_BINARY)
 
 check-local: $(BITCOIN_TESTS:.cpp=.cpp.test)
 	@echo "Running test/util/bitcoin-util-test.py..."
 	$(top_builddir)/test/util/bitcoin-util-test.py
 	$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C secp256k1 check
 if EMBEDDED_UNIVALUE
 	$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C univalue check
 endif
 
 %.cpp.test: %.cpp
 	@echo Running tests: `cat $< | grep "BOOST_FIXTURE_TEST_SUITE(\|BOOST_AUTO_TEST_SUITE(" | cut -d '(' -f 2 | cut -d ',' -f 1 | cut -d ')' -f 1` from $<
 	$(AM_V_at)$(TEST_BINARY) -l test_suite -t "`cat $< | grep "BOOST_FIXTURE_TEST_SUITE(\|BOOST_AUTO_TEST_SUITE(" | cut -d '(' -f 2 | cut -d ',' -f 1 | cut -d ')' -f 1`" > $@.log 2>&1 || (cat $@.log && false)
 
 %.json.h: %.json
 	@$(MKDIR_P) $(@D)
 	@{ \
 	 echo "namespace json_tests{" && \
 	 echo "static unsigned const char $(*F)[] = {" && \
 	 $(HEXDUMP) -v -e '8/1 "0x%02x, "' -e '"\n"' $< | $(SED) -e 's/0x  ,//g' && \
 	 echo "};};"; \
 	} > "$@.new" && mv -f "$@.new" "$@"
 	@echo "Generated $@"
diff --git a/src/avalanche.cpp b/src/avalanche.cpp
index 75f7f50957..9d5603bff5 100644
--- a/src/avalanche.cpp
+++ b/src/avalanche.cpp
@@ -1,511 +1,494 @@
 // Copyright (c) 2018 The Bitcoin developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #include <avalanche.h>
 
 #include <chain.h>
-#include <config/bitcoin-config.h>
 #include <netmessagemaker.h>
 #include <reverse_iterator.h>
 #include <scheduler.h>
+#include <util/bitmanip.h>
 #include <validation.h>
 
 #include <tuple>
 
 /**
  * Run the avalanche event loop every 10ms.
  */
 static const int64_t AVALANCHE_TIME_STEP_MILLISECONDS = 10;
 
 /**
  * Maximum item count that can be polled at once.
  */
 static const size_t AVALANCHE_MAX_ELEMENT_POLL = 4096;
 
-static uint32_t countBits(uint32_t v) {
-#if HAVE_DECL___BUILTIN_POPCOUNT
-    return __builtin_popcount(v);
-#else
-    /**
-     * Computes the number of bits set in each group of 8bits then uses a
-     * multiplication to sum all of them in the 8 most significant bits and
-     * return these.
-     * More detailed explanation can be found at
-     * https://www.playingwithpointers.com/blog/swar.html
-     */
-    v = v - ((v >> 1) & 0x55555555);
-    v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
-    return (((v + (v >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
-#endif
-}
-
 bool VoteRecord::registerVote(NodeId nodeid, uint32_t error) {
     // We just got a new vote, so there is one less inflight request.
     clearInflightRequest();
 
     // We want to avoid having the same node voting twice in a quorum.
     if (!addNodeToQuorum(nodeid)) {
         return false;
     }
 
     /**
      * The result of the vote is determined from the error code. If the error
      * code is 0, there is no error and therefore the vote is yes. If there is
      * an error, we check the most significant bit to decide if the vote is a no
      * (for instance, the block is invalid) or is the vote inconclusive (for
      * instance, the queried node does not have the block yet).
      */
     votes = (votes << 1) | (error == 0);
     consider = (consider << 1) | (int32_t(error) >= 0);
 
     /**
      * We compute the number of yes and/or no votes as follow:
      *
      * votes:     1010
      * consider:  1100
      *
      * yes votes: 1000 using votes & consider
      * no votes:  0100 using ~votes & consider
      */
     bool yes = countBits(votes & consider & 0xff) > 6;
     if (!yes) {
         bool no = countBits(~votes & consider & 0xff) > 6;
         if (!no) {
             // The round is inconclusive.
             return false;
         }
     }
 
     // If the round is in agreement with previous rounds, increase confidence.
     if (isAccepted() == yes) {
         confidence += 2;
         return getConfidence() == AVALANCHE_FINALIZATION_SCORE;
     }
 
     // The round changed our state. We reset the confidence.
     confidence = yes;
     return true;
 }
 
 bool VoteRecord::addNodeToQuorum(NodeId nodeid) {
     if (nodeid == NO_NODE) {
         // Helpful for testing.
         return true;
     }
 
     // MMIX Linear Congruent Generator.
     const uint64_t r1 =
         6364136223846793005 * uint64_t(nodeid) + 1442695040888963407;
     // Fibonacci hashing.
     const uint64_t r2 = 11400714819323198485ull * (nodeid ^ seed);
     // Combine and extract hash.
     const uint16_t h = (r1 + r2) >> 48;
 
     /**
      * Check if the node is in the filter.
      */
     for (size_t i = 1; i < nodeFilter.size(); i++) {
         if (nodeFilter[(successfulVotes + i) % nodeFilter.size()] == h) {
             return false;
         }
     }
 
     /**
      * Add the node which just voted to the filter.
      */
     nodeFilter[successfulVotes % nodeFilter.size()] = h;
     successfulVotes++;
     return true;
 }
 
 bool VoteRecord::registerPoll() const {
     uint8_t count = inflight.load();
     while (count < AVALANCHE_MAX_INFLIGHT_POLL) {
         if (inflight.compare_exchange_weak(count, count + 1)) {
             return true;
         }
     }
 
     return false;
 }
 
 static bool IsWorthPolling(const CBlockIndex *pindex) {
     AssertLockHeld(cs_main);
 
     if (pindex->nStatus.isInvalid()) {
         // No point polling invalid blocks.
         return false;
     }
 
     if (IsBlockFinalized(pindex)) {
         // There is no point polling finalized block.
         return false;
     }
 
     return true;
 }
 
 bool AvalancheProcessor::addBlockToReconcile(const CBlockIndex *pindex) {
     bool isAccepted;
 
     {
         LOCK(cs_main);
         if (!IsWorthPolling(pindex)) {
             // There is no point polling this block.
             return false;
         }
 
         isAccepted = chainActive.Contains(pindex);
     }
 
     return vote_records.getWriteView()
         ->insert(std::make_pair(pindex, VoteRecord(isAccepted)))
         .second;
 }
 
 bool AvalancheProcessor::isAccepted(const CBlockIndex *pindex) const {
     auto r = vote_records.getReadView();
     auto it = r->find(pindex);
     if (it == r.end()) {
         return false;
     }
 
     return it->second.isAccepted();
 }
 
 int AvalancheProcessor::getConfidence(const CBlockIndex *pindex) const {
     auto r = vote_records.getReadView();
     auto it = r->find(pindex);
     if (it == r.end()) {
         return -1;
     }
 
     return it->second.getConfidence();
 }
 
 bool AvalancheProcessor::registerVotes(
     NodeId nodeid, const AvalancheResponse &response,
     std::vector<AvalancheBlockUpdate> &updates) {
     {
         // Save the time at which we can query again.
         auto w = peerSet.getWriteView();
         auto it = w->find(nodeid);
         if (it != w->end()) {
             w->modify(it, [&response](Peer &p) {
                 // FIXME: This will override the time even when we received an
                 // old stale message. This should check that the message is
                 // indeed the most up to date one before updating the time.
                 p.nextRequestTime =
                     std::chrono::steady_clock::now() +
                     std::chrono::milliseconds(response.getCooldown());
             });
         }
     }
 
     std::vector<CInv> invs;
 
     {
         // Check that the query exists.
         auto w = queries.getWriteView();
         auto it = w->find(std::make_tuple(nodeid, response.getRound()));
         if (it == w.end()) {
             // NB: The request may be old, so we don't increase banscore.
             return false;
         }
 
         invs = std::move(it->invs);
         w->erase(it);
     }
 
     // Verify that the request and the vote are consistent.
     const std::vector<AvalancheVote> &votes = response.GetVotes();
     size_t size = invs.size();
     if (votes.size() != size) {
         // TODO: increase banscore for inconsistent response.
         // NB: This isn't timeout but actually node misbehaving.
         return false;
     }
 
     for (size_t i = 0; i < size; i++) {
         if (invs[i].hash != votes[i].GetHash()) {
             // TODO: increase banscore for inconsistent response.
             // NB: This isn't timeout but actually node misbehaving.
             return false;
         }
     }
 
     std::map<CBlockIndex *, AvalancheVote> responseIndex;
 
     {
         LOCK(cs_main);
         for (auto &v : votes) {
             BlockMap::iterator mi = mapBlockIndex.find(v.GetHash());
             if (mi == mapBlockIndex.end()) {
                 // This should not happen, but just in case...
                 continue;
             }
 
             CBlockIndex *pindex = mi->second;
             if (!IsWorthPolling(pindex)) {
                 // There is no point polling this block.
                 continue;
             }
 
             responseIndex.insert(std::make_pair(pindex, v));
         }
     }
 
     {
         // Register votes.
         auto w = vote_records.getWriteView();
         for (auto &p : responseIndex) {
             CBlockIndex *pindex = p.first;
             const AvalancheVote &v = p.second;
 
             auto it = w->find(pindex);
             if (it == w.end()) {
                 // We are not voting on that item anymore.
                 continue;
             }
 
             auto &vr = it->second;
             if (!vr.registerVote(nodeid, v.GetError())) {
                 // This vote did not provide any extra information, move on.
                 continue;
             }
 
             if (!vr.hasFinalized()) {
                 // This item has note been finalized, so we have nothing more to
                 // do.
                 updates.emplace_back(
                     pindex, vr.isAccepted()
                                 ? AvalancheBlockUpdate::Status::Accepted
                                 : AvalancheBlockUpdate::Status::Rejected);
                 continue;
             }
 
             // We just finalized a vote. If it is valid, then let the caller
             // know. Either way, remove the item from the map.
             updates.emplace_back(pindex,
                                  vr.isAccepted()
                                      ? AvalancheBlockUpdate::Status::Finalized
                                      : AvalancheBlockUpdate::Status::Invalid);
             w->erase(it);
         }
     }
 
     return true;
 }
 
 bool AvalancheProcessor::addPeer(NodeId nodeid, int64_t score) {
     return peerSet.getWriteView()
         ->insert({nodeid, score, std::chrono::steady_clock::now()})
         .second;
 }
 
 bool AvalancheProcessor::startEventLoop(CScheduler &scheduler) {
     LOCK(cs_running);
     if (running) {
         // Do not start the event loop twice.
         return false;
     }
 
     running = true;
 
     // Start the event loop.
     scheduler.scheduleEvery(
         [this]() -> bool {
             runEventLoop();
             if (!stopRequest) {
                 return true;
             }
 
             LOCK(cs_running);
             running = false;
 
             cond_running.notify_all();
 
             // A stop request was made.
             return false;
         },
         AVALANCHE_TIME_STEP_MILLISECONDS);
 
     return true;
 }
 
 bool AvalancheProcessor::stopEventLoop() {
     WAIT_LOCK(cs_running, lock);
     if (!running) {
         return false;
     }
 
     // Request avalanche to stop.
     stopRequest = true;
 
     // Wait for avalanche to stop.
     cond_running.wait(lock, [this]() EXCLUSIVE_LOCKS_REQUIRED(cs_running) {
         return !running;
     });
 
     stopRequest = false;
     return true;
 }
 
 std::vector<CInv> AvalancheProcessor::getInvsForNextPoll(bool forPoll) const {
     std::vector<CInv> invs;
 
     auto r = vote_records.getReadView();
     for (const std::pair<const CBlockIndex *const, VoteRecord> &p :
          reverse_iterate(r)) {
         const CBlockIndex *pindex = p.first;
 
         {
             LOCK(cs_main);
             if (!IsWorthPolling(pindex)) {
                 // Obviously do not poll if the block is not worth polling.
                 continue;
             }
         }
 
         // Check if we can run poll.
         const bool shouldPoll =
             forPoll ? p.second.registerPoll() : p.second.shouldPoll();
         if (!shouldPoll) {
             continue;
         }
 
         // We don't have a decision, we need more votes.
         invs.emplace_back(MSG_BLOCK, pindex->GetBlockHash());
         if (invs.size() >= AVALANCHE_MAX_ELEMENT_POLL) {
             // Make sure we do not produce more invs than specified by the
             // protocol.
             return invs;
         }
     }
 
     return invs;
 }
 
 NodeId AvalancheProcessor::getSuitableNodeToQuery() {
     auto r = peerSet.getReadView();
     auto it = r->get<next_request_time>().begin();
     if (it == r->get<next_request_time>().end()) {
         return NO_NODE;
     }
 
     if (it->nextRequestTime <= std::chrono::steady_clock::now()) {
         return it->nodeid;
     }
 
     return NO_NODE;
 }
 
 void AvalancheProcessor::clearTimedoutRequests() {
     auto now = std::chrono::steady_clock::now();
     std::map<CInv, uint8_t> timedout_items{};
 
     {
         // Clear expired requests.
         auto w = queries.getWriteView();
         auto it = w->get<query_timeout>().begin();
         while (it != w->get<query_timeout>().end() && it->timeout < now) {
             for (auto &i : it->invs) {
                 timedout_items[i]++;
             }
 
             w->get<query_timeout>().erase(it++);
         }
     }
 
     if (timedout_items.empty()) {
         return;
     }
 
     // In flight request accounting.
     for (const auto &p : timedout_items) {
         const CInv &inv = p.first;
         assert(inv.type == MSG_BLOCK);
 
         CBlockIndex *pindex;
 
         {
             LOCK(cs_main);
             BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
             if (mi == mapBlockIndex.end()) {
                 continue;
             }
 
             pindex = mi->second;
         }
 
         auto w = vote_records.getWriteView();
         auto it = w->find(pindex);
         if (it == w.end()) {
             continue;
         }
 
         it->second.clearInflightRequest(p.second);
     }
 }
 
 void AvalancheProcessor::runEventLoop() {
     // First things first, check if we have requests that timed out and clear
     // them.
     clearTimedoutRequests();
 
     while (true) {
         NodeId nodeid = getSuitableNodeToQuery();
         if (nodeid == NO_NODE) {
             return;
         }
 
         /**
          * If we lost contact to that node, then we remove it from nodeids, but
          * never add the request to queries, which ensures bad nodes get cleaned
          * up over time.
          */
         std::vector<CInv> invs;
         bool hasSent = connman->ForNode(nodeid, [this, &invs](CNode *pnode) {
             invs = getInvsForNextPoll();
             if (invs.empty()) {
                 return false;
             }
 
             uint64_t current_round = round++;
 
             {
                 // Compute the time at which this requests times out.
                 auto timeout =
                     std::chrono::steady_clock::now() + queryTimeoutDuration;
                 // Register the query.
                 queries.getWriteView()->insert(
                     {pnode->GetId(), current_round, timeout, invs});
                 // Set the timeout.
                 auto w = peerSet.getWriteView();
                 auto it = w->find(pnode->GetId());
                 if (it != w->end()) {
                     w->modify(it, [&timeout](Peer &p) {
                         p.nextRequestTime = timeout;
                     });
                 }
             }
 
             // Send the query to the node.
             connman->PushMessage(
                 pnode,
                 CNetMsgMaker(pnode->GetSendVersion())
                     .Make(NetMsgType::AVAPOLL,
                           AvalanchePoll(current_round, std::move(invs))));
             return true;
         });
 
         // Success!
         if (hasSent || invs.empty()) {
             return;
         }
 
         // This node is obsolete, delete it.
         peerSet.getWriteView()->erase(nodeid);
     }
 }
diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt
index 170519a333..7731540fdb 100644
--- a/src/test/CMakeLists.txt
+++ b/src/test/CMakeLists.txt
@@ -1,180 +1,181 @@
 # Copyright (c) 2018 The Bitcoin developers
 
 project(bitcoin-test)
 
 # Process json files.
 file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/data")
 
 find_program(PYTHON python)
 function(gen_json_header NAME)
 	set(HEADERS "")
 	foreach(f ${ARGN})
 		set(h "${CMAKE_CURRENT_BINARY_DIR}/${f}.h")
 
 		# Get the proper name for the test variable.
 		get_filename_component(TEST_NAME ${f} NAME_WE)
 		add_custom_command(OUTPUT ${h}
 			COMMAND ${PYTHON}
 			ARGS
 				"${CMAKE_CURRENT_SOURCE_DIR}/data/generate_header.py"
 				"${TEST_NAME}"
 				"${CMAKE_CURRENT_SOURCE_DIR}/${f}" > ${h}
 			MAIN_DEPENDENCY ${f}
 			DEPENDS
 				"data/generate_header.py"
 			VERBATIM
 		)
 		list(APPEND HEADERS ${h})
 	endforeach(f)
 	set(${NAME} "${HEADERS}" PARENT_SCOPE)
 endfunction()
 
 gen_json_header(JSON_HEADERS
 	data/base58_encode_decode.json
 	data/blockfilters.json
 	data/key_io_valid.json
 	data/key_io_invalid.json
 	data/script_tests.json
 	data/sighash.json
 	data/tx_invalid.json
 	data/tx_valid.json
 )
 
 include(TestSuite)
 create_test_suite(bitcoin)
 add_dependencies(check check-bitcoin)
 
 add_test_to_suite(bitcoin test_bitcoin
 	activation_tests.cpp
 	addrman_tests.cpp
 	allocator_tests.cpp
 	amount_tests.cpp
 	arith_uint256_tests.cpp
 	avalanche_tests.cpp
 	base32_tests.cpp
 	base58_tests.cpp
 	base64_tests.cpp
 	bip32_tests.cpp
+	bitmanip_tests.cpp
 	blockchain_tests.cpp
 	blockcheck_tests.cpp
 	blockencodings_tests.cpp
 	blockfilter_tests.cpp
 	blockindex_tests.cpp
 	blockstatus_tests.cpp
 	bloom_tests.cpp
 	bswap_tests.cpp
 	cashaddr_tests.cpp
 	cashaddrenc_tests.cpp
 	checkdatasig_tests.cpp
 	checkpoints_tests.cpp
 	checkqueue_tests.cpp
 	coins_tests.cpp
 	compress_tests.cpp
 	config_tests.cpp
 	core_io_tests.cpp
 	crypto_tests.cpp
 	cuckoocache_tests.cpp
 	dbwrapper_tests.cpp
 	denialofservice_tests.cpp
 	dstencode_tests.cpp
 	excessiveblock_tests.cpp
 	feerate_tests.cpp
 	finalization_tests.cpp
 	flatfile_tests.cpp
 	getarg_tests.cpp
 	hash_tests.cpp
 	inv_tests.cpp
 	jsonutil.cpp
 	key_io_tests.cpp
 	key_tests.cpp
 	lcg_tests.cpp
 	limitedmap_tests.cpp
 	main_tests.cpp
 	mempool_tests.cpp
 	merkle_tests.cpp
 	miner_tests.cpp
 	monolith_opcodes_tests.cpp
 	multisig_tests.cpp
 	net_tests.cpp
 	netbase_tests.cpp
 	pmt_tests.cpp
 	policyestimator_tests.cpp
 	pow_tests.cpp
 	prevector_tests.cpp
 	radix_tests.cpp
 	raii_event_tests.cpp
 	random_tests.cpp
 	rcu_tests.cpp
 	reverselock_tests.cpp
 	rpc_tests.cpp
 	rpc_server_tests.cpp
 	rwcollection_tests.cpp
 	sanity_tests.cpp
 	scheduler_tests.cpp
 	schnorr_tests.cpp
 	script_bitfield_tests.cpp
 	script_commitment_tests.cpp
 	script_p2sh_tests.cpp
 	script_standard_tests.cpp
 	script_tests.cpp
 	scriptflags.cpp
 	scriptnum_tests.cpp
 	serialize_tests.cpp
 	sigcache_tests.cpp
 	sigencoding_tests.cpp
 	sighash_tests.cpp
 	sighashtype_tests.cpp
 	sigopcount_tests.cpp
 	sigutil.cpp
 	skiplist_tests.cpp
 	streams_tests.cpp
 	sync_tests.cpp
 	test_bitcoin.cpp
 	test_bitcoin_main.cpp
 	timedata_tests.cpp
 	torcontrol_tests.cpp
 	transaction_tests.cpp
 	txindex_tests.cpp
 	txvalidation_tests.cpp
 	txvalidationcache_tests.cpp
 	uint256_tests.cpp
 	undo_tests.cpp
 	util_tests.cpp
 	validation_block_tests.cpp
 	validation_tests.cpp
 	work_comparator_tests.cpp
 
 	# RPC Tests
 	../rpc/test/server_tests.cpp
 
 	# Tests generated from JSON
 	${JSON_HEADERS}
 )
 
 find_package(Boost 1.58 REQUIRED unit_test_framework)
 
 target_link_libraries(test_bitcoin Boost::unit_test_framework rpcclient server)
 
 # We need to detect if the BOOST_TEST_DYN_LINK flag is required.
 set(CMAKE_REQUIRED_LIBRARIES Boost::unit_test_framework)
 check_cxx_source_compiles("
 	#define BOOST_TEST_DYN_LINK
 	#define BOOST_TEST_MAIN
 	#include <boost/test/unit_test.hpp>
 " BOOST_TEST_DYN_LINK)
 
 if(BOOST_TEST_DYN_LINK)
 	target_compile_definitions(test_bitcoin PRIVATE BOOST_TEST_DYN_LINK)
 endif(BOOST_TEST_DYN_LINK)
 
 if(BUILD_BITCOIN_WALLET)
 	target_sources(test_bitcoin
 		PRIVATE
 			../wallet/test/wallet_test_fixture.cpp
 			../wallet/test/accounting_tests.cpp
 			../wallet/test/wallet_tests.cpp
 			../wallet/test/walletdb_tests.cpp
 			../wallet/test/wallet_crypto_tests.cpp
 			../wallet/test/coinselector_tests.cpp
 	)
 endif()
diff --git a/src/test/bitmanip_tests.cpp b/src/test/bitmanip_tests.cpp
new file mode 100644
index 0000000000..3d321fb03e
--- /dev/null
+++ b/src/test/bitmanip_tests.cpp
@@ -0,0 +1,60 @@
+// Copyright (c) 2019 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <test/test_bitcoin.h>
+#include <util/bitmanip.h>
+
+#include <boost/test/unit_test.hpp>
+
+BOOST_FIXTURE_TEST_SUITE(bitmanip_tests, BasicTestingSetup)
+
+static void CheckBitCount(uint32_t value, uint32_t expected_count) {
+    // Count are rotation invariant.
+    for (int i = 0; i < 32; i++) {
+        BOOST_CHECK_EQUAL(countBits(value), expected_count);
+        value = (value << 1) | (value >> 31);
+    }
+}
+
+static uint32_t countBitsNaive(uint32_t value) {
+    uint32_t ret = 0;
+    while (value != 0) {
+        ret += (value & 0x01);
+        value >>= 1;
+    }
+
+    return ret;
+}
+
+#define COUNT 4096
+
+BOOST_AUTO_TEST_CASE(bit_count) {
+    // Check various known values.
+    CheckBitCount(0, 0);
+    CheckBitCount(1, 1);
+    CheckBitCount(0xffffffff, 32);
+    CheckBitCount(0x01234567, 12);
+    CheckBitCount(0x12345678, 13);
+    CheckBitCount(0xfedcba98, 20);
+    CheckBitCount(0x5a55aaa5, 16);
+    CheckBitCount(0xdeadbeef, 24);
+
+    for (uint32_t i = 2; i != 0; i <<= 1) {
+        // Check two bit set for all combinations.
+        CheckBitCount(i | 0x01, 2);
+    }
+
+    // Check many small values against a naive implementation.
+    for (uint32_t v = 0; v <= 0xfff; v++) {
+        CheckBitCount(v, countBitsNaive(v));
+    }
+
+    // Check random values against a naive implementation.
+    for (int i = 0; i < COUNT; i++) {
+        uint32_t v = InsecureRand32();
+        CheckBitCount(v, countBitsNaive(v));
+    }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/util/bitmanip.h b/src/util/bitmanip.h
new file mode 100644
index 0000000000..26e1df89ef
--- /dev/null
+++ b/src/util/bitmanip.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2019 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_UTIL_BITMANIP_H
+#define BITCOIN_UTIL_BITMANIP_H
+
+#include <config/bitcoin-config.h>
+
+#include <cstdint>
+
+inline uint32_t countBits(uint32_t v) {
+#if HAVE_DECL___BUILTIN_POPCOUNT
+    return __builtin_popcount(v);
+#else
+    /**
+     * Computes the number of bits set in each group of 8bits then uses a
+     * multiplication to sum all of them in the 8 most significant bits and
+     * return these.
+     * More detailed explanation can be found at
+     * https://www.playingwithpointers.com/blog/swar.html
+     */
+    v = v - ((v >> 1) & 0x55555555);
+    v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
+    return (((v + (v >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
+#endif
+}
+
+#endif // BITCOIN_UTIL_BITMANIP_H