diff --git a/src/addrdb.cpp b/src/addrdb.cpp
index b96748542..a6f45aa9f 100644
--- a/src/addrdb.cpp
+++ b/src/addrdb.cpp
@@ -1,204 +1,204 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #include "addrdb.h"
 
 #include "addrman.h"
 #include "chainparams.h"
 #include "clientversion.h"
 #include "hash.h"
 #include "random.h"
 #include "streams.h"
 #include "tinyformat.h"
 #include "util.h"
 
 #include <boost/filesystem.hpp>
 
 CBanDB::CBanDB() {
     pathBanlist = GetDataDir() / "banlist.dat";
 }
 
 bool CBanDB::Write(const banmap_t &banSet) {
     // Generate random temporary filename
     unsigned short randv = 0;
-    GetRandBytes((unsigned char *)&randv, sizeof(randv));
+    GetRandBytes((uint8_t *)&randv, sizeof(randv));
     std::string tmpfn = strprintf("banlist.dat.%04x", randv);
 
     // serialize banlist, checksum data up to that point, then append csum
     CDataStream ssBanlist(SER_DISK, CLIENT_VERSION);
     ssBanlist << FLATDATA(Params().MessageStart());
     ssBanlist << banSet;
     uint256 hash = Hash(ssBanlist.begin(), ssBanlist.end());
     ssBanlist << hash;
 
     // open temp output file, and associate with CAutoFile
     boost::filesystem::path pathTmp = GetDataDir() / tmpfn;
     FILE *file = fopen(pathTmp.string().c_str(), "wb");
     CAutoFile fileout(file, SER_DISK, CLIENT_VERSION);
     if (fileout.IsNull())
         return error("%s: Failed to open file %s", __func__, pathTmp.string());
 
     // Write and commit header, data
     try {
         fileout << ssBanlist;
     } catch (const std::exception &e) {
         return error("%s: Serialize or I/O error - %s", __func__, e.what());
     }
     FileCommit(fileout.Get());
     fileout.fclose();
 
     // replace existing banlist.dat, if any, with new banlist.dat.XXXX
     if (!RenameOver(pathTmp, pathBanlist))
         return error("%s: Rename-into-place failed", __func__);
 
     return true;
 }
 
 bool CBanDB::Read(banmap_t &banSet) {
     // open input file, and associate with CAutoFile
     FILE *file = fopen(pathBanlist.string().c_str(), "rb");
     CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
     if (filein.IsNull())
         return error("%s: Failed to open file %s", __func__,
                      pathBanlist.string());
 
     // use file size to size memory buffer
     uint64_t fileSize = boost::filesystem::file_size(pathBanlist);
     uint64_t dataSize = 0;
     // Don't try to resize to a negative number if file is small
     if (fileSize >= sizeof(uint256)) dataSize = fileSize - sizeof(uint256);
-    std::vector<unsigned char> vchData;
+    std::vector<uint8_t> vchData;
     vchData.resize(dataSize);
     uint256 hashIn;
 
     // read data and checksum from file
     try {
         filein.read((char *)&vchData[0], dataSize);
         filein >> hashIn;
     } catch (const std::exception &e) {
         return error("%s: Deserialize or I/O error - %s", __func__, e.what());
     }
     filein.fclose();
 
     CDataStream ssBanlist(vchData, SER_DISK, CLIENT_VERSION);
 
     // verify stored checksum matches input data
     uint256 hashTmp = Hash(ssBanlist.begin(), ssBanlist.end());
     if (hashIn != hashTmp)
         return error("%s: Checksum mismatch, data corrupted", __func__);
 
-    unsigned char pchMsgTmp[4];
+    uint8_t pchMsgTmp[4];
     try {
         // de-serialize file header (network specific magic number) and ..
         ssBanlist >> FLATDATA(pchMsgTmp);
 
         // ... verify the network matches ours
         if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
             return error("%s: Invalid network magic number", __func__);
 
         // de-serialize ban data
         ssBanlist >> banSet;
     } catch (const std::exception &e) {
         return error("%s: Deserialize or I/O error - %s", __func__, e.what());
     }
 
     return true;
 }
 
 CAddrDB::CAddrDB() {
     pathAddr = GetDataDir() / "peers.dat";
 }
 
 bool CAddrDB::Write(const CAddrMan &addr) {
     // Generate random temporary filename
     unsigned short randv = 0;
-    GetRandBytes((unsigned char *)&randv, sizeof(randv));
+    GetRandBytes((uint8_t *)&randv, sizeof(randv));
     std::string tmpfn = strprintf("peers.dat.%04x", randv);
 
     // serialize addresses, checksum data up to that point, then append csum
     CDataStream ssPeers(SER_DISK, CLIENT_VERSION);
     ssPeers << FLATDATA(Params().MessageStart());
     ssPeers << addr;
     uint256 hash = Hash(ssPeers.begin(), ssPeers.end());
     ssPeers << hash;
 
     // open temp output file, and associate with CAutoFile
     boost::filesystem::path pathTmp = GetDataDir() / tmpfn;
     FILE *file = fopen(pathTmp.string().c_str(), "wb");
     CAutoFile fileout(file, SER_DISK, CLIENT_VERSION);
     if (fileout.IsNull())
         return error("%s: Failed to open file %s", __func__, pathTmp.string());
 
     // Write and commit header, data
     try {
         fileout << ssPeers;
     } catch (const std::exception &e) {
         return error("%s: Serialize or I/O error - %s", __func__, e.what());
     }
     FileCommit(fileout.Get());
     fileout.fclose();
 
     // replace existing peers.dat, if any, with new peers.dat.XXXX
     if (!RenameOver(pathTmp, pathAddr))
         return error("%s: Rename-into-place failed", __func__);
 
     return true;
 }
 
 bool CAddrDB::Read(CAddrMan &addr) {
     // open input file, and associate with CAutoFile
     FILE *file = fopen(pathAddr.string().c_str(), "rb");
     CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
     if (filein.IsNull())
         return error("%s: Failed to open file %s", __func__, pathAddr.string());
 
     // use file size to size memory buffer
     uint64_t fileSize = boost::filesystem::file_size(pathAddr);
     uint64_t dataSize = 0;
     // Don't try to resize to a negative number if file is small
     if (fileSize >= sizeof(uint256)) dataSize = fileSize - sizeof(uint256);
-    std::vector<unsigned char> vchData;
+    std::vector<uint8_t> vchData;
     vchData.resize(dataSize);
     uint256 hashIn;
 
     // read data and checksum from file
     try {
         filein.read((char *)&vchData[0], dataSize);
         filein >> hashIn;
     } catch (const std::exception &e) {
         return error("%s: Deserialize or I/O error - %s", __func__, e.what());
     }
     filein.fclose();
 
     CDataStream ssPeers(vchData, SER_DISK, CLIENT_VERSION);
 
     // verify stored checksum matches input data
     uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end());
     if (hashIn != hashTmp)
         return error("%s: Checksum mismatch, data corrupted", __func__);
 
     return Read(addr, ssPeers);
 }
 
 bool CAddrDB::Read(CAddrMan &addr, CDataStream &ssPeers) {
-    unsigned char pchMsgTmp[4];
+    uint8_t pchMsgTmp[4];
     try {
         // de-serialize file header (network specific magic number) and ..
         ssPeers >> FLATDATA(pchMsgTmp);
 
         // ... verify the network matches ours
         if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
             return error("%s: Invalid network magic number", __func__);
 
         // de-serialize address data into one CAddrMan object
         ssPeers >> addr;
     } catch (const std::exception &e) {
         // de-serialization has failed, ensure addrman is left in a clean state
         addr.Clear();
         return error("%s: Deserialize or I/O error - %s", __func__, e.what());
     }
 
     return true;
 }
diff --git a/src/addrman.cpp b/src/addrman.cpp
index 1b16ab69c..31f9a28e1 100644
--- a/src/addrman.cpp
+++ b/src/addrman.cpp
@@ -1,506 +1,506 @@
 // Copyright (c) 2012 Pieter Wuille
 // Copyright (c) 2012-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.
 
 #include "addrman.h"
 
 #include "hash.h"
 #include "serialize.h"
 #include "streams.h"
 
 int CAddrInfo::GetTriedBucket(const uint256 &nKey) const {
     uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << GetKey())
                          .GetHash()
                          .GetCheapHash();
     uint64_t hash2 =
         (CHashWriter(SER_GETHASH, 0)
          << nKey << GetGroup() << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP))
             .GetHash()
             .GetCheapHash();
     return hash2 % ADDRMAN_TRIED_BUCKET_COUNT;
 }
 
 int CAddrInfo::GetNewBucket(const uint256 &nKey, const CNetAddr &src) const {
-    std::vector<unsigned char> vchSourceGroupKey = src.GetGroup();
+    std::vector<uint8_t> vchSourceGroupKey = src.GetGroup();
     uint64_t hash1 =
         (CHashWriter(SER_GETHASH, 0) << nKey << GetGroup() << vchSourceGroupKey)
             .GetHash()
             .GetCheapHash();
     uint64_t hash2 = (CHashWriter(SER_GETHASH, 0)
                       << nKey << vchSourceGroupKey
                       << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP))
                          .GetHash()
                          .GetCheapHash();
     return hash2 % ADDRMAN_NEW_BUCKET_COUNT;
 }
 
 int CAddrInfo::GetBucketPosition(const uint256 &nKey, bool fNew,
                                  int nBucket) const {
     uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << (fNew ? 'N' : 'K')
                                                   << nBucket << GetKey())
                          .GetHash()
                          .GetCheapHash();
     return hash1 % ADDRMAN_BUCKET_SIZE;
 }
 
 bool CAddrInfo::IsTerrible(int64_t nNow) const {
     // never remove things tried in the last minute
     if (nLastTry && nLastTry >= nNow - 60) return false;
 
     // came in a flying DeLorean
     if (nTime > nNow + 10 * 60) return true;
 
     // not seen in recent history
     if (nTime == 0 || nNow - nTime > ADDRMAN_HORIZON_DAYS * 24 * 60 * 60)
         return true;
 
     // tried N times and never a success
     if (nLastSuccess == 0 && nAttempts >= ADDRMAN_RETRIES) return true;
 
     if (nNow - nLastSuccess > ADDRMAN_MIN_FAIL_DAYS * 24 * 60 * 60 &&
         nAttempts >=
             ADDRMAN_MAX_FAILURES) // N successive failures in the last week
         return true;
 
     return false;
 }
 
 double CAddrInfo::GetChance(int64_t nNow) const {
     double fChance = 1.0;
     int64_t nSinceLastTry = std::max<int64_t>(nNow - nLastTry, 0);
 
     // deprioritize very recent attempts away
     if (nSinceLastTry < 60 * 10) fChance *= 0.01;
 
     // deprioritize 66% after each failed attempt, but at most 1/28th to avoid
     // the search taking forever or overly penalizing outages.
     fChance *= pow(0.66, std::min(nAttempts, 8));
 
     return fChance;
 }
 
 CAddrInfo *CAddrMan::Find(const CNetAddr &addr, int *pnId) {
     std::map<CNetAddr, int>::iterator it = mapAddr.find(addr);
     if (it == mapAddr.end()) return nullptr;
     if (pnId) *pnId = (*it).second;
     std::map<int, CAddrInfo>::iterator it2 = mapInfo.find((*it).second);
     if (it2 != mapInfo.end()) return &(*it2).second;
     return nullptr;
 }
 
 CAddrInfo *CAddrMan::Create(const CAddress &addr, const CNetAddr &addrSource,
                             int *pnId) {
     int nId = nIdCount++;
     mapInfo[nId] = CAddrInfo(addr, addrSource);
     mapAddr[addr] = nId;
     mapInfo[nId].nRandomPos = vRandom.size();
     vRandom.push_back(nId);
     if (pnId) *pnId = nId;
     return &mapInfo[nId];
 }
 
 void CAddrMan::SwapRandom(unsigned int nRndPos1, unsigned int nRndPos2) {
     if (nRndPos1 == nRndPos2) return;
 
     assert(nRndPos1 < vRandom.size() && nRndPos2 < vRandom.size());
 
     int nId1 = vRandom[nRndPos1];
     int nId2 = vRandom[nRndPos2];
 
     assert(mapInfo.count(nId1) == 1);
     assert(mapInfo.count(nId2) == 1);
 
     mapInfo[nId1].nRandomPos = nRndPos2;
     mapInfo[nId2].nRandomPos = nRndPos1;
 
     vRandom[nRndPos1] = nId2;
     vRandom[nRndPos2] = nId1;
 }
 
 void CAddrMan::Delete(int nId) {
     assert(mapInfo.count(nId) != 0);
     CAddrInfo &info = mapInfo[nId];
     assert(!info.fInTried);
     assert(info.nRefCount == 0);
 
     SwapRandom(info.nRandomPos, vRandom.size() - 1);
     vRandom.pop_back();
     mapAddr.erase(info);
     mapInfo.erase(nId);
     nNew--;
 }
 
 void CAddrMan::ClearNew(int nUBucket, int nUBucketPos) {
     // if there is an entry in the specified bucket, delete it.
     if (vvNew[nUBucket][nUBucketPos] != -1) {
         int nIdDelete = vvNew[nUBucket][nUBucketPos];
         CAddrInfo &infoDelete = mapInfo[nIdDelete];
         assert(infoDelete.nRefCount > 0);
         infoDelete.nRefCount--;
         vvNew[nUBucket][nUBucketPos] = -1;
         if (infoDelete.nRefCount == 0) {
             Delete(nIdDelete);
         }
     }
 }
 
 void CAddrMan::MakeTried(CAddrInfo &info, int nId) {
     // remove the entry from all new buckets
     for (int bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
         int pos = info.GetBucketPosition(nKey, true, bucket);
         if (vvNew[bucket][pos] == nId) {
             vvNew[bucket][pos] = -1;
             info.nRefCount--;
         }
     }
     nNew--;
 
     assert(info.nRefCount == 0);
 
     // which tried bucket to move the entry to
     int nKBucket = info.GetTriedBucket(nKey);
     int nKBucketPos = info.GetBucketPosition(nKey, false, nKBucket);
 
     // first make space to add it (the existing tried entry there is moved to
     // new, deleting whatever is there).
     if (vvTried[nKBucket][nKBucketPos] != -1) {
         // find an item to evict
         int nIdEvict = vvTried[nKBucket][nKBucketPos];
         assert(mapInfo.count(nIdEvict) == 1);
         CAddrInfo &infoOld = mapInfo[nIdEvict];
 
         // Remove the to-be-evicted item from the tried set.
         infoOld.fInTried = false;
         vvTried[nKBucket][nKBucketPos] = -1;
         nTried--;
 
         // find which new bucket it belongs to
         int nUBucket = infoOld.GetNewBucket(nKey);
         int nUBucketPos = infoOld.GetBucketPosition(nKey, true, nUBucket);
         ClearNew(nUBucket, nUBucketPos);
         assert(vvNew[nUBucket][nUBucketPos] == -1);
 
         // Enter it into the new set again.
         infoOld.nRefCount = 1;
         vvNew[nUBucket][nUBucketPos] = nIdEvict;
         nNew++;
     }
     assert(vvTried[nKBucket][nKBucketPos] == -1);
 
     vvTried[nKBucket][nKBucketPos] = nId;
     nTried++;
     info.fInTried = true;
 }
 
 void CAddrMan::Good_(const CService &addr, int64_t nTime) {
     int nId;
 
     nLastGood = nTime;
 
     CAddrInfo *pinfo = Find(addr, &nId);
 
     // if not found, bail out
     if (!pinfo) return;
 
     CAddrInfo &info = *pinfo;
 
     // check whether we are talking about the exact same CService (including
     // same port)
     if (info != addr) return;
 
     // update info
     info.nLastSuccess = nTime;
     info.nLastTry = nTime;
     info.nAttempts = 0;
     // nTime is not updated here, to avoid leaking information about
     // currently-connected peers.
 
     // if it is already in the tried set, don't do anything else
     if (info.fInTried) return;
 
     // find a bucket it is in now
     int nRnd = RandomInt(ADDRMAN_NEW_BUCKET_COUNT);
     int nUBucket = -1;
     for (unsigned int n = 0; n < ADDRMAN_NEW_BUCKET_COUNT; n++) {
         int nB = (n + nRnd) % ADDRMAN_NEW_BUCKET_COUNT;
         int nBpos = info.GetBucketPosition(nKey, true, nB);
         if (vvNew[nB][nBpos] == nId) {
             nUBucket = nB;
             break;
         }
     }
 
     // if no bucket is found, something bad happened;
     // TODO: maybe re-add the node, but for now, just bail out
     if (nUBucket == -1) return;
 
     LogPrint("addrman", "Moving %s to tried\n", addr.ToString());
 
     // move nId to the tried tables
     MakeTried(info, nId);
 }
 
 bool CAddrMan::Add_(const CAddress &addr, const CNetAddr &source,
                     int64_t nTimePenalty) {
     if (!addr.IsRoutable()) return false;
 
     bool fNew = false;
     int nId;
     CAddrInfo *pinfo = Find(addr, &nId);
 
     // Do not set a penalty for a source's self-announcement
     if (addr == source) {
         nTimePenalty = 0;
     }
 
     if (pinfo) {
         // periodically update nTime
         bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
         int64_t nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
         if (addr.nTime &&
             (!pinfo->nTime ||
              pinfo->nTime < addr.nTime - nUpdateInterval - nTimePenalty))
             pinfo->nTime = std::max((int64_t)0, addr.nTime - nTimePenalty);
 
         // add services
         pinfo->nServices = ServiceFlags(pinfo->nServices | addr.nServices);
 
         // do not update if no new information is present
         if (!addr.nTime || (pinfo->nTime && addr.nTime <= pinfo->nTime))
             return false;
 
         // do not update if the entry was already in the "tried" table
         if (pinfo->fInTried) return false;
 
         // do not update if the max reference count is reached
         if (pinfo->nRefCount == ADDRMAN_NEW_BUCKETS_PER_ADDRESS) return false;
 
         // stochastic test: previous nRefCount == N: 2^N times harder to
         // increase it
         int nFactor = 1;
         for (int n = 0; n < pinfo->nRefCount; n++)
             nFactor *= 2;
         if (nFactor > 1 && (RandomInt(nFactor) != 0)) return false;
     } else {
         pinfo = Create(addr, source, &nId);
         pinfo->nTime =
             std::max((int64_t)0, (int64_t)pinfo->nTime - nTimePenalty);
         nNew++;
         fNew = true;
     }
 
     int nUBucket = pinfo->GetNewBucket(nKey, source);
     int nUBucketPos = pinfo->GetBucketPosition(nKey, true, nUBucket);
     if (vvNew[nUBucket][nUBucketPos] != nId) {
         bool fInsert = vvNew[nUBucket][nUBucketPos] == -1;
         if (!fInsert) {
             CAddrInfo &infoExisting = mapInfo[vvNew[nUBucket][nUBucketPos]];
             if (infoExisting.IsTerrible() ||
                 (infoExisting.nRefCount > 1 && pinfo->nRefCount == 0)) {
                 // Overwrite the existing new table entry.
                 fInsert = true;
             }
         }
         if (fInsert) {
             ClearNew(nUBucket, nUBucketPos);
             pinfo->nRefCount++;
             vvNew[nUBucket][nUBucketPos] = nId;
         } else {
             if (pinfo->nRefCount == 0) {
                 Delete(nId);
             }
         }
     }
     return fNew;
 }
 
 void CAddrMan::Attempt_(const CService &addr, bool fCountFailure,
                         int64_t nTime) {
     CAddrInfo *pinfo = Find(addr);
 
     // if not found, bail out
     if (!pinfo) return;
 
     CAddrInfo &info = *pinfo;
 
     // check whether we are talking about the exact same CService (including
     // same port)
     if (info != addr) return;
 
     // update info
     info.nLastTry = nTime;
     if (fCountFailure && info.nLastCountAttempt < nLastGood) {
         info.nLastCountAttempt = nTime;
         info.nAttempts++;
     }
 }
 
 CAddrInfo CAddrMan::Select_(bool newOnly) {
     if (size() == 0) return CAddrInfo();
 
     if (newOnly && nNew == 0) return CAddrInfo();
 
     // Use a 50% chance for choosing between tried and new table entries.
     if (!newOnly && (nTried > 0 && (nNew == 0 || RandomInt(2) == 0))) {
         // use a tried node
         double fChanceFactor = 1.0;
         while (1) {
             int nKBucket = RandomInt(ADDRMAN_TRIED_BUCKET_COUNT);
             int nKBucketPos = RandomInt(ADDRMAN_BUCKET_SIZE);
             while (vvTried[nKBucket][nKBucketPos] == -1) {
                 nKBucket = (nKBucket + insecure_rand.rand32()) %
                            ADDRMAN_TRIED_BUCKET_COUNT;
                 nKBucketPos = (nKBucketPos + insecure_rand.rand32()) %
                               ADDRMAN_BUCKET_SIZE;
             }
             int nId = vvTried[nKBucket][nKBucketPos];
             assert(mapInfo.count(nId) == 1);
             CAddrInfo &info = mapInfo[nId];
             if (RandomInt(1 << 30) <
                 fChanceFactor * info.GetChance() * (1 << 30))
                 return info;
             fChanceFactor *= 1.2;
         }
     } else {
         // use a new node
         double fChanceFactor = 1.0;
         while (1) {
             int nUBucket = RandomInt(ADDRMAN_NEW_BUCKET_COUNT);
             int nUBucketPos = RandomInt(ADDRMAN_BUCKET_SIZE);
             while (vvNew[nUBucket][nUBucketPos] == -1) {
                 nUBucket = (nUBucket + insecure_rand.rand32()) %
                            ADDRMAN_NEW_BUCKET_COUNT;
                 nUBucketPos = (nUBucketPos + insecure_rand.rand32()) %
                               ADDRMAN_BUCKET_SIZE;
             }
             int nId = vvNew[nUBucket][nUBucketPos];
             assert(mapInfo.count(nId) == 1);
             CAddrInfo &info = mapInfo[nId];
             if (RandomInt(1 << 30) <
                 fChanceFactor * info.GetChance() * (1 << 30))
                 return info;
             fChanceFactor *= 1.2;
         }
     }
 }
 
 #ifdef DEBUG_ADDRMAN
 int CAddrMan::Check_() {
     std::set<int> setTried;
     std::map<int, int> mapNew;
 
     if (vRandom.size() != nTried + nNew) return -7;
 
     for (std::map<int, CAddrInfo>::iterator it = mapInfo.begin();
          it != mapInfo.end(); it++) {
         int n = (*it).first;
         CAddrInfo &info = (*it).second;
         if (info.fInTried) {
             if (!info.nLastSuccess) return -1;
             if (info.nRefCount) return -2;
             setTried.insert(n);
         } else {
             if (info.nRefCount < 0 ||
                 info.nRefCount > ADDRMAN_NEW_BUCKETS_PER_ADDRESS)
                 return -3;
             if (!info.nRefCount) return -4;
             mapNew[n] = info.nRefCount;
         }
         if (mapAddr[info] != n) return -5;
         if (info.nRandomPos < 0 || info.nRandomPos >= vRandom.size() ||
             vRandom[info.nRandomPos] != n)
             return -14;
         if (info.nLastTry < 0) return -6;
         if (info.nLastSuccess < 0) return -8;
     }
 
     if (setTried.size() != nTried) return -9;
     if (mapNew.size() != nNew) return -10;
 
     for (int n = 0; n < ADDRMAN_TRIED_BUCKET_COUNT; n++) {
         for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
             if (vvTried[n][i] != -1) {
                 if (!setTried.count(vvTried[n][i])) return -11;
                 if (mapInfo[vvTried[n][i]].GetTriedBucket(nKey) != n)
                     return -17;
                 if (mapInfo[vvTried[n][i]].GetBucketPosition(nKey, false, n) !=
                     i)
                     return -18;
                 setTried.erase(vvTried[n][i]);
             }
         }
     }
 
     for (int n = 0; n < ADDRMAN_NEW_BUCKET_COUNT; n++) {
         for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
             if (vvNew[n][i] != -1) {
                 if (!mapNew.count(vvNew[n][i])) return -12;
                 if (mapInfo[vvNew[n][i]].GetBucketPosition(nKey, true, n) != i)
                     return -19;
                 if (--mapNew[vvNew[n][i]] == 0) mapNew.erase(vvNew[n][i]);
             }
         }
     }
 
     if (setTried.size()) return -13;
     if (mapNew.size()) return -15;
     if (nKey.IsNull()) return -16;
 
     return 0;
 }
 #endif
 
 void CAddrMan::GetAddr_(std::vector<CAddress> &vAddr) {
     unsigned int nNodes = ADDRMAN_GETADDR_MAX_PCT * vRandom.size() / 100;
     if (nNodes > ADDRMAN_GETADDR_MAX) nNodes = ADDRMAN_GETADDR_MAX;
 
     // gather a list of random nodes, skipping those of low quality
     for (unsigned int n = 0; n < vRandom.size(); n++) {
         if (vAddr.size() >= nNodes) break;
 
         int nRndPos = RandomInt(vRandom.size() - n) + n;
         SwapRandom(n, nRndPos);
         assert(mapInfo.count(vRandom[n]) == 1);
 
         const CAddrInfo &ai = mapInfo[vRandom[n]];
         if (!ai.IsTerrible()) vAddr.push_back(ai);
     }
 }
 
 void CAddrMan::Connected_(const CService &addr, int64_t nTime) {
     CAddrInfo *pinfo = Find(addr);
 
     // if not found, bail out
     if (!pinfo) return;
 
     CAddrInfo &info = *pinfo;
 
     // check whether we are talking about the exact same CService (including
     // same port)
     if (info != addr) return;
 
     // update info
     int64_t nUpdateInterval = 20 * 60;
     if (nTime - info.nTime > nUpdateInterval) info.nTime = nTime;
 }
 
 void CAddrMan::SetServices_(const CService &addr, ServiceFlags nServices) {
     CAddrInfo *pinfo = Find(addr);
 
     // if not found, bail out
     if (!pinfo) return;
 
     CAddrInfo &info = *pinfo;
 
     // check whether we are talking about the exact same CService (including
     // same port)
     if (info != addr) return;
 
     // update info
     info.nServices = nServices;
 }
 
 int CAddrMan::RandomInt(int nMax) {
     return GetRandInt(nMax);
 }
diff --git a/src/addrman.h b/src/addrman.h
index 515900489..4c82db130 100644
--- a/src/addrman.h
+++ b/src/addrman.h
@@ -1,612 +1,612 @@
 // Copyright (c) 2012 Pieter Wuille
 // Copyright (c) 2012-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.
 
 #ifndef BITCOIN_ADDRMAN_H
 #define BITCOIN_ADDRMAN_H
 
 #include "netaddress.h"
 #include "protocol.h"
 #include "random.h"
 #include "sync.h"
 #include "timedata.h"
 #include "util.h"
 
 #include <cstdint>
 #include <map>
 #include <set>
 #include <vector>
 
 /**
  * Extended statistics about a CAddress
  */
 class CAddrInfo : public CAddress {
 
 public:
     //! last try whatsoever by us (memory only)
     int64_t nLastTry;
 
     //! last counted attempt (memory only)
     int64_t nLastCountAttempt;
 
 private:
     //! where knowledge about this address first came from
     CNetAddr source;
 
     //! last successful connection by us
     int64_t nLastSuccess;
 
     //! connection attempts since last successful attempt
     int nAttempts;
 
     //! reference count in new sets (memory only)
     int nRefCount;
 
     //! in tried set? (memory only)
     bool fInTried;
 
     //! position in vRandom
     int nRandomPos;
 
     friend class CAddrMan;
 
 public:
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
     inline void SerializationOp(Stream &s, Operation ser_action) {
         READWRITE(*(CAddress *)this);
         READWRITE(source);
         READWRITE(nLastSuccess);
         READWRITE(nAttempts);
     }
 
     void Init() {
         nLastSuccess = 0;
         nLastTry = 0;
         nLastCountAttempt = 0;
         nAttempts = 0;
         nRefCount = 0;
         fInTried = false;
         nRandomPos = -1;
     }
 
     CAddrInfo(const CAddress &addrIn, const CNetAddr &addrSource)
         : CAddress(addrIn), source(addrSource) {
         Init();
     }
 
     CAddrInfo() : CAddress(), source() { Init(); }
 
     //! Calculate in which "tried" bucket this entry belongs
     int GetTriedBucket(const uint256 &nKey) const;
 
     //! Calculate in which "new" bucket this entry belongs, given a certain
     //! source
     int GetNewBucket(const uint256 &nKey, const CNetAddr &src) const;
 
     //! Calculate in which "new" bucket this entry belongs, using its default
     //! source
     int GetNewBucket(const uint256 &nKey) const {
         return GetNewBucket(nKey, source);
     }
 
     //! Calculate in which position of a bucket to store this entry.
     int GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const;
 
     //! Determine whether the statistics about this entry are bad enough so that
     //! it can just be deleted
     bool IsTerrible(int64_t nNow = GetAdjustedTime()) const;
 
     //! Calculate the relative chance this entry should be given when selecting
     //! nodes to connect to
     double GetChance(int64_t nNow = GetAdjustedTime()) const;
 };
 
 /** Stochastic address manager
  *
  * Design goals:
  *  * Keep the address tables in-memory, and asynchronously dump the entire
  * table to peers.dat.
  *  * Make sure no (localized) attacker can fill the entire table with his
  * nodes/addresses.
  *
  * To that end:
  *  * Addresses are organized into buckets.
  *    * Addresses that have not yet been tried go into 1024 "new" buckets.
  *      * Based on the address range (/16 for IPv4) of the source of
  * information, 64 buckets are selected at random.
  *      * The actual bucket is chosen from one of these, based on the range in
  * which the address itself is located.
  *      * One single address can occur in up to 8 different buckets to increase
  * selection chances for addresses that
  *        are seen frequently. The chance for increasing this multiplicity
  * decreases exponentially.
  *      * When adding a new address to a full bucket, a randomly chosen entry
  * (with a bias favoring less recently seen
  *        ones) is removed from it first.
  *    * Addresses of nodes that are known to be accessible go into 256 "tried"
  * buckets.
  *      * Each address range selects at random 8 of these buckets.
  *      * The actual bucket is chosen from one of these, based on the full
  * address.
  *      * When adding a new good address to a full bucket, a randomly chosen
  * entry (with a bias favoring less recently
  *        tried ones) is evicted from it, back to the "new" buckets.
  *    * Bucket selection is based on cryptographic hashing, using a
  * randomly-generated 256-bit key, which should not
  *      be observable by adversaries.
  *    * Several indexes are kept for high performance. Defining DEBUG_ADDRMAN
  * will introduce frequent (and expensive)
  *      consistency checks for the entire data structure.
  */
 
 //! total number of buckets for tried addresses
 #define ADDRMAN_TRIED_BUCKET_COUNT 256
 
 //! total number of buckets for new addresses
 #define ADDRMAN_NEW_BUCKET_COUNT 1024
 
 //! maximum allowed number of entries in buckets for new and tried addresses
 #define ADDRMAN_BUCKET_SIZE 64
 
 //! over how many buckets entries with tried addresses from a single group (/16
 //! for IPv4) are spread
 #define ADDRMAN_TRIED_BUCKETS_PER_GROUP 8
 
 //! over how many buckets entries with new addresses originating from a single
 //! group are spread
 #define ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP 64
 
 //! in how many buckets for entries with new addresses a single address may
 //! occur
 #define ADDRMAN_NEW_BUCKETS_PER_ADDRESS 8
 
 //! how old addresses can maximally be
 #define ADDRMAN_HORIZON_DAYS 30
 
 //! after how many failed attempts we give up on a new node
 #define ADDRMAN_RETRIES 3
 
 //! how many successive failures are allowed ...
 #define ADDRMAN_MAX_FAILURES 10
 
 //! ... in at least this many days
 #define ADDRMAN_MIN_FAIL_DAYS 7
 
 //! the maximum percentage of nodes to return in a getaddr call
 #define ADDRMAN_GETADDR_MAX_PCT 23
 
 //! the maximum number of nodes to return in a getaddr call
 #define ADDRMAN_GETADDR_MAX 2500
 
 /**
  * Stochastical (IP) address manager
  */
 class CAddrMan {
 private:
     //! critical section to protect the inner data structures
     mutable CCriticalSection cs;
 
     //! last used nId
     int nIdCount;
 
     //! table with information about all nIds
     std::map<int, CAddrInfo> mapInfo;
 
     //! find an nId based on its network address
     std::map<CNetAddr, int> mapAddr;
 
     //! randomly-ordered vector of all nIds
     std::vector<int> vRandom;
 
     // number of "tried" entries
     int nTried;
 
     //! list of "tried" buckets
     int vvTried[ADDRMAN_TRIED_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE];
 
     //! number of (unique) "new" entries
     int nNew;
 
     //! list of "new" buckets
     int vvNew[ADDRMAN_NEW_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE];
 
     //! last time Good was called (memory only)
     int64_t nLastGood;
 
 protected:
     //! secret key to randomize bucket select with
     uint256 nKey;
 
     //! Source of random numbers for randomization in inner loops
     FastRandomContext insecure_rand;
 
     //! Find an entry.
     CAddrInfo *Find(const CNetAddr &addr, int *pnId = nullptr);
 
     //! find an entry, creating it if necessary.
     //! nTime and nServices of the found node are updated, if necessary.
     CAddrInfo *Create(const CAddress &addr, const CNetAddr &addrSource,
                       int *pnId = nullptr);
 
     //! Swap two elements in vRandom.
     void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2);
 
     //! Move an entry from the "new" table(s) to the "tried" table
     void MakeTried(CAddrInfo &info, int nId);
 
     //! Delete an entry. It must not be in tried, and have refcount 0.
     void Delete(int nId);
 
     //! Clear a position in a "new" table. This is the only place where entries
     //! are actually deleted.
     void ClearNew(int nUBucket, int nUBucketPos);
 
     //! Mark an entry "good", possibly moving it from "new" to "tried".
     void Good_(const CService &addr, int64_t nTime);
 
     //! Add an entry to the "new" table.
     bool Add_(const CAddress &addr, const CNetAddr &source,
               int64_t nTimePenalty);
 
     //! Mark an entry as attempted to connect.
     void Attempt_(const CService &addr, bool fCountFailure, int64_t nTime);
 
     //! Select an address to connect to, if newOnly is set to true, only the new
     //! table is selected from.
     CAddrInfo Select_(bool newOnly);
 
     //! Wraps GetRandInt to allow tests to override RandomInt and make it
     //! determinismistic.
     virtual int RandomInt(int nMax);
 
 #ifdef DEBUG_ADDRMAN
     //! Perform consistency check. Returns an error code or zero.
     int Check_();
 #endif
 
     //! Select several addresses at once.
     void GetAddr_(std::vector<CAddress> &vAddr);
 
     //! Mark an entry as currently-connected-to.
     void Connected_(const CService &addr, int64_t nTime);
 
     //! Update an entry's service bits.
     void SetServices_(const CService &addr, ServiceFlags nServices);
 
 public:
     /**
      * serialized format:
      * * version byte (currently 1)
      * * 0x20 + nKey (serialized as if it were a vector, for backward
      * compatibility)
      * * nNew
      * * nTried
      * * number of "new" buckets XOR 2**30
      * * all nNew addrinfos in vvNew
      * * all nTried addrinfos in vvTried
      * * for each bucket:
      *   * number of elements
      *   * for each element: index
      *
      * 2**30 is xorred with the number of buckets to make addrman deserializer
      * v0 detect it as incompatible. This is necessary because it did not check
      * the version number on deserialization.
      *
      * Notice that vvTried, mapAddr and vVector are never encoded explicitly;
      * they are instead reconstructed from the other information.
      *
      * vvNew is serialized, but only used if ADDRMAN_UNKNOWN_BUCKET_COUNT didn't
      * change, otherwise it is reconstructed as well.
      *
      * This format is more complex, but significantly smaller (at most 1.5 MiB),
      * and supports changes to the ADDRMAN_ parameters without breaking the
      * on-disk structure.
      *
      * We don't use ADD_SERIALIZE_METHODS since the serialization and
      * deserialization code has very little in common.
      */
     template <typename Stream> void Serialize(Stream &s) const {
         LOCK(cs);
 
-        unsigned char nVersion = 1;
+        uint8_t nVersion = 1;
         s << nVersion;
-        s << ((unsigned char)32);
+        s << uint8_t(32);
         s << nKey;
         s << nNew;
         s << nTried;
 
         int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30);
         s << nUBuckets;
         std::map<int, int> mapUnkIds;
         int nIds = 0;
         for (std::map<int, CAddrInfo>::const_iterator it = mapInfo.begin();
              it != mapInfo.end(); it++) {
             mapUnkIds[(*it).first] = nIds;
             const CAddrInfo &info = (*it).second;
             if (info.nRefCount) {
                 // this means nNew was wrong, oh ow
                 assert(nIds != nNew);
                 s << info;
                 nIds++;
             }
         }
         nIds = 0;
         for (std::map<int, CAddrInfo>::const_iterator it = mapInfo.begin();
              it != mapInfo.end(); it++) {
             const CAddrInfo &info = (*it).second;
             if (info.fInTried) {
                 // this means nTried was wrong, oh ow
                 assert(nIds != nTried);
                 s << info;
                 nIds++;
             }
         }
         for (int bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
             int nSize = 0;
             for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
                 if (vvNew[bucket][i] != -1) nSize++;
             }
             s << nSize;
             for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
                 if (vvNew[bucket][i] != -1) {
                     int nIndex = mapUnkIds[vvNew[bucket][i]];
                     s << nIndex;
                 }
             }
         }
     }
 
     template <typename Stream> void Unserialize(Stream &s) {
         LOCK(cs);
 
         Clear();
 
-        unsigned char nVersion;
+        uint8_t nVersion;
         s >> nVersion;
-        unsigned char nKeySize;
+        uint8_t nKeySize;
         s >> nKeySize;
         if (nKeySize != 32)
             throw std::ios_base::failure(
                 "Incorrect keysize in addrman deserialization");
         s >> nKey;
         s >> nNew;
         s >> nTried;
         int nUBuckets = 0;
         s >> nUBuckets;
         if (nVersion != 0) {
             nUBuckets ^= (1 << 30);
         }
 
         if (nNew > ADDRMAN_NEW_BUCKET_COUNT * ADDRMAN_BUCKET_SIZE) {
             throw std::ios_base::failure(
                 "Corrupt CAddrMan serialization, nNew exceeds limit.");
         }
 
         if (nTried > ADDRMAN_TRIED_BUCKET_COUNT * ADDRMAN_BUCKET_SIZE) {
             throw std::ios_base::failure(
                 "Corrupt CAddrMan serialization, nTried exceeds limit.");
         }
 
         // Deserialize entries from the new table.
         for (int n = 0; n < nNew; n++) {
             CAddrInfo &info = mapInfo[n];
             s >> info;
             mapAddr[info] = n;
             info.nRandomPos = vRandom.size();
             vRandom.push_back(n);
             if (nVersion != 1 || nUBuckets != ADDRMAN_NEW_BUCKET_COUNT) {
                 // In case the new table data cannot be used (nVersion unknown,
                 // or bucket count wrong), immediately try to give them a
                 // reference based on their primary source address.
                 int nUBucket = info.GetNewBucket(nKey);
                 int nUBucketPos = info.GetBucketPosition(nKey, true, nUBucket);
                 if (vvNew[nUBucket][nUBucketPos] == -1) {
                     vvNew[nUBucket][nUBucketPos] = n;
                     info.nRefCount++;
                 }
             }
         }
         nIdCount = nNew;
 
         // Deserialize entries from the tried table.
         int nLost = 0;
         for (int n = 0; n < nTried; n++) {
             CAddrInfo info;
             s >> info;
             int nKBucket = info.GetTriedBucket(nKey);
             int nKBucketPos = info.GetBucketPosition(nKey, false, nKBucket);
             if (vvTried[nKBucket][nKBucketPos] == -1) {
                 info.nRandomPos = vRandom.size();
                 info.fInTried = true;
                 vRandom.push_back(nIdCount);
                 mapInfo[nIdCount] = info;
                 mapAddr[info] = nIdCount;
                 vvTried[nKBucket][nKBucketPos] = nIdCount;
                 nIdCount++;
             } else {
                 nLost++;
             }
         }
         nTried -= nLost;
 
         // Deserialize positions in the new table (if possible).
         for (int bucket = 0; bucket < nUBuckets; bucket++) {
             int nSize = 0;
             s >> nSize;
             for (int n = 0; n < nSize; n++) {
                 int nIndex = 0;
                 s >> nIndex;
                 if (nIndex >= 0 && nIndex < nNew) {
                     CAddrInfo &info = mapInfo[nIndex];
                     int nUBucketPos =
                         info.GetBucketPosition(nKey, true, bucket);
                     if (nVersion == 1 &&
                         nUBuckets == ADDRMAN_NEW_BUCKET_COUNT &&
                         vvNew[bucket][nUBucketPos] == -1 &&
                         info.nRefCount < ADDRMAN_NEW_BUCKETS_PER_ADDRESS) {
                         info.nRefCount++;
                         vvNew[bucket][nUBucketPos] = nIndex;
                     }
                 }
             }
         }
 
         // Prune new entries with refcount 0 (as a result of collisions).
         int nLostUnk = 0;
         for (std::map<int, CAddrInfo>::const_iterator it = mapInfo.begin();
              it != mapInfo.end();) {
             if (it->second.fInTried == false && it->second.nRefCount == 0) {
                 std::map<int, CAddrInfo>::const_iterator itCopy = it++;
                 Delete(itCopy->first);
                 nLostUnk++;
             } else {
                 it++;
             }
         }
         if (nLost + nLostUnk > 0) {
             LogPrint("addrman", "addrman lost %i new and %i tried addresses "
                                 "due to collisions\n",
                      nLostUnk, nLost);
         }
 
         Check();
     }
 
     void Clear() {
         std::vector<int>().swap(vRandom);
         nKey = GetRandHash();
         for (size_t bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
             for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) {
                 vvNew[bucket][entry] = -1;
             }
         }
         for (size_t bucket = 0; bucket < ADDRMAN_TRIED_BUCKET_COUNT; bucket++) {
             for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) {
                 vvTried[bucket][entry] = -1;
             }
         }
 
         nIdCount = 0;
         nTried = 0;
         nNew = 0;
         // Initially at 1 so that "never" is strictly worse.
         nLastGood = 1;
     }
 
     CAddrMan() { Clear(); }
 
     ~CAddrMan() { nKey.SetNull(); }
 
     //! Return the number of (unique) addresses in all tables.
     size_t size() const {
         // TODO: Cache this in an atomic to avoid this overhead
         LOCK(cs);
         return vRandom.size();
     }
 
     //! Consistency check
     void Check() {
 #ifdef DEBUG_ADDRMAN
         {
             LOCK(cs);
             int err;
             if ((err = Check_()))
                 LogPrintf("ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err);
         }
 #endif
     }
 
     //! Add a single address.
     bool Add(const CAddress &addr, const CNetAddr &source,
              int64_t nTimePenalty = 0) {
         LOCK(cs);
         bool fRet = false;
         Check();
         fRet |= Add_(addr, source, nTimePenalty);
         Check();
         if (fRet)
             LogPrint("addrman", "Added %s from %s: %i tried, %i new\n",
                      addr.ToStringIPPort(), source.ToString(), nTried, nNew);
         return fRet;
     }
 
     //! Add multiple addresses.
     bool Add(const std::vector<CAddress> &vAddr, const CNetAddr &source,
              int64_t nTimePenalty = 0) {
         LOCK(cs);
         int nAdd = 0;
         Check();
         for (std::vector<CAddress>::const_iterator it = vAddr.begin();
              it != vAddr.end(); it++)
             nAdd += Add_(*it, source, nTimePenalty) ? 1 : 0;
         Check();
         if (nAdd)
             LogPrint("addrman",
                      "Added %i addresses from %s: %i tried, %i new\n", nAdd,
                      source.ToString(), nTried, nNew);
         return nAdd > 0;
     }
 
     //! Mark an entry as accessible.
     void Good(const CService &addr, int64_t nTime = GetAdjustedTime()) {
         LOCK(cs);
         Check();
         Good_(addr, nTime);
         Check();
     }
 
     //! Mark an entry as connection attempted to.
     void Attempt(const CService &addr, bool fCountFailure,
                  int64_t nTime = GetAdjustedTime()) {
         LOCK(cs);
         Check();
         Attempt_(addr, fCountFailure, nTime);
         Check();
     }
 
     /**
      * Choose an address to connect to.
      */
     CAddrInfo Select(bool newOnly = false) {
         CAddrInfo addrRet;
         {
             LOCK(cs);
             Check();
             addrRet = Select_(newOnly);
             Check();
         }
         return addrRet;
     }
 
     //! Return a bunch of addresses, selected at random.
     std::vector<CAddress> GetAddr() {
         Check();
         std::vector<CAddress> vAddr;
         {
             LOCK(cs);
             GetAddr_(vAddr);
         }
         Check();
         return vAddr;
     }
 
     //! Mark an entry as currently-connected-to.
     void Connected(const CService &addr, int64_t nTime = GetAdjustedTime()) {
         LOCK(cs);
         Check();
         Connected_(addr, nTime);
         Check();
     }
 
     void SetServices(const CService &addr, ServiceFlags nServices) {
         LOCK(cs);
         Check();
         SetServices_(addr, nServices);
         Check();
     }
 };
 
 #endif // BITCOIN_ADDRMAN_H
diff --git a/src/base58.cpp b/src/base58.cpp
index 63fa6e6b7..cf6a9fd34 100644
--- a/src/base58.cpp
+++ b/src/base58.cpp
@@ -1,313 +1,310 @@
 // Copyright (c) 2014-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.
 
 #include "base58.h"
 
 #include "hash.h"
 #include "uint256.h"
 
 #include <boost/variant/apply_visitor.hpp>
 #include <boost/variant/static_visitor.hpp>
 #include <cassert>
 #include <cstdint>
 #include <cstring>
 #include <string>
 #include <vector>
 
 /** All alphanumeric characters except for "0", "I", "O", and "l" */
 static const char *pszBase58 =
     "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
 
-bool DecodeBase58(const char *psz, std::vector<unsigned char> &vch) {
+bool DecodeBase58(const char *psz, std::vector<uint8_t> &vch) {
     // Skip leading spaces.
     while (*psz && isspace(*psz)) {
         psz++;
     }
     // Skip and count leading '1's.
     int zeroes = 0;
     int length = 0;
     while (*psz == '1') {
         zeroes++;
         psz++;
     }
     // Allocate enough space in big-endian base256 representation.
     // log(58) / log(256), rounded up.
     int size = strlen(psz) * 733 / 1000 + 1;
-    std::vector<unsigned char> b256(size);
+    std::vector<uint8_t> b256(size);
     // Process the characters.
     while (*psz && !isspace(*psz)) {
         // Decode base58 character
         const char *ch = strchr(pszBase58, *psz);
         if (ch == nullptr) {
             return false;
         }
         // Apply "b256 = b256 * 58 + ch".
         int carry = ch - pszBase58;
         int i = 0;
-        for (std::vector<unsigned char>::reverse_iterator it = b256.rbegin();
+        for (std::vector<uint8_t>::reverse_iterator it = b256.rbegin();
              (carry != 0 || i < length) && (it != b256.rend()); ++it, ++i) {
             carry += 58 * (*it);
             *it = carry % 256;
             carry /= 256;
         }
         assert(carry == 0);
         length = i;
         psz++;
     }
     // Skip trailing spaces.
     while (isspace(*psz)) {
         psz++;
     }
     if (*psz != 0) {
         return false;
     }
     // Skip leading zeroes in b256.
-    std::vector<unsigned char>::iterator it = b256.begin() + (size - length);
+    std::vector<uint8_t>::iterator it = b256.begin() + (size - length);
     while (it != b256.end() && *it == 0)
         it++;
     // Copy result into output vector.
     vch.reserve(zeroes + (b256.end() - it));
     vch.assign(zeroes, 0x00);
     while (it != b256.end()) {
         vch.push_back(*(it++));
     }
     return true;
 }
 
-std::string EncodeBase58(const unsigned char *pbegin,
-                         const unsigned char *pend) {
+std::string EncodeBase58(const uint8_t *pbegin, const uint8_t *pend) {
     // Skip & count leading zeroes.
     int zeroes = 0;
     int length = 0;
     while (pbegin != pend && *pbegin == 0) {
         pbegin++;
         zeroes++;
     }
     // Allocate enough space in big-endian base58 representation.
     // log(256) / log(58), rounded up.
     int size = (pend - pbegin) * 138 / 100 + 1;
-    std::vector<unsigned char> b58(size);
+    std::vector<uint8_t> b58(size);
     // Process the bytes.
     while (pbegin != pend) {
         int carry = *pbegin;
         int i = 0;
         // Apply "b58 = b58 * 256 + ch".
-        for (std::vector<unsigned char>::reverse_iterator it = b58.rbegin();
+        for (std::vector<uint8_t>::reverse_iterator it = b58.rbegin();
              (carry != 0 || i < length) && (it != b58.rend()); it++, i++) {
             carry += 256 * (*it);
             *it = carry % 58;
             carry /= 58;
         }
 
         assert(carry == 0);
         length = i;
         pbegin++;
     }
     // Skip leading zeroes in base58 result.
-    std::vector<unsigned char>::iterator it = b58.begin() + (size - length);
+    std::vector<uint8_t>::iterator it = b58.begin() + (size - length);
     while (it != b58.end() && *it == 0) {
         it++;
     }
     // Translate the result into a string.
     std::string str;
     str.reserve(zeroes + (b58.end() - it));
     str.assign(zeroes, '1');
     while (it != b58.end()) {
         str += pszBase58[*(it++)];
     }
     return str;
 }
 
-std::string EncodeBase58(const std::vector<unsigned char> &vch) {
+std::string EncodeBase58(const std::vector<uint8_t> &vch) {
     return EncodeBase58(&vch[0], &vch[0] + vch.size());
 }
 
-bool DecodeBase58(const std::string &str, std::vector<unsigned char> &vchRet) {
+bool DecodeBase58(const std::string &str, std::vector<uint8_t> &vchRet) {
     return DecodeBase58(str.c_str(), vchRet);
 }
 
-std::string EncodeBase58Check(const std::vector<unsigned char> &vchIn) {
+std::string EncodeBase58Check(const std::vector<uint8_t> &vchIn) {
     // add 4-byte hash check to the end
-    std::vector<unsigned char> vch(vchIn);
+    std::vector<uint8_t> vch(vchIn);
     uint256 hash = Hash(vch.begin(), vch.end());
-    vch.insert(vch.end(), (unsigned char *)&hash, (unsigned char *)&hash + 4);
+    vch.insert(vch.end(), (uint8_t *)&hash, (uint8_t *)&hash + 4);
     return EncodeBase58(vch);
 }
 
-bool DecodeBase58Check(const char *psz, std::vector<unsigned char> &vchRet) {
+bool DecodeBase58Check(const char *psz, std::vector<uint8_t> &vchRet) {
     if (!DecodeBase58(psz, vchRet) || (vchRet.size() < 4)) {
         vchRet.clear();
         return false;
     }
     // re-calculate the checksum, insure it matches the included 4-byte checksum
     uint256 hash = Hash(vchRet.begin(), vchRet.end() - 4);
     if (memcmp(&hash, &vchRet.end()[-4], 4) != 0) {
         vchRet.clear();
         return false;
     }
     vchRet.resize(vchRet.size() - 4);
     return true;
 }
 
-bool DecodeBase58Check(const std::string &str,
-                       std::vector<unsigned char> &vchRet) {
+bool DecodeBase58Check(const std::string &str, std::vector<uint8_t> &vchRet) {
     return DecodeBase58Check(str.c_str(), vchRet);
 }
 
 CBase58Data::CBase58Data() {
     vchVersion.clear();
     vchData.clear();
 }
 
-void CBase58Data::SetData(const std::vector<unsigned char> &vchVersionIn,
+void CBase58Data::SetData(const std::vector<uint8_t> &vchVersionIn,
                           const void *pdata, size_t nSize) {
     vchVersion = vchVersionIn;
     vchData.resize(nSize);
     if (!vchData.empty()) {
         memcpy(&vchData[0], pdata, nSize);
     }
 }
 
-void CBase58Data::SetData(const std::vector<unsigned char> &vchVersionIn,
-                          const unsigned char *pbegin,
-                          const unsigned char *pend) {
+void CBase58Data::SetData(const std::vector<uint8_t> &vchVersionIn,
+                          const uint8_t *pbegin, const uint8_t *pend) {
     SetData(vchVersionIn, (void *)pbegin, pend - pbegin);
 }
 
 bool CBase58Data::SetString(const char *psz, unsigned int nVersionBytes) {
-    std::vector<unsigned char> vchTemp;
+    std::vector<uint8_t> vchTemp;
     bool rc58 = DecodeBase58Check(psz, vchTemp);
     if ((!rc58) || (vchTemp.size() < nVersionBytes)) {
         vchData.clear();
         vchVersion.clear();
         return false;
     }
     vchVersion.assign(vchTemp.begin(), vchTemp.begin() + nVersionBytes);
     vchData.resize(vchTemp.size() - nVersionBytes);
     if (!vchData.empty()) {
         memcpy(&vchData[0], &vchTemp[nVersionBytes], vchData.size());
     }
     memory_cleanse(&vchTemp[0], vchTemp.size());
     return true;
 }
 
 bool CBase58Data::SetString(const std::string &str) {
     return SetString(str.c_str());
 }
 
 std::string CBase58Data::ToString() const {
-    std::vector<unsigned char> vch = vchVersion;
+    std::vector<uint8_t> vch = vchVersion;
     vch.insert(vch.end(), vchData.begin(), vchData.end());
     return EncodeBase58Check(vch);
 }
 
 int CBase58Data::CompareTo(const CBase58Data &b58) const {
     if (vchVersion < b58.vchVersion) return -1;
     if (vchVersion > b58.vchVersion) return 1;
     if (vchData < b58.vchData) return -1;
     if (vchData > b58.vchData) return 1;
     return 0;
 }
 
 namespace {
 class CBitcoinAddressVisitor : public boost::static_visitor<bool> {
 private:
     CBitcoinAddress *addr;
 
 public:
     CBitcoinAddressVisitor(CBitcoinAddress *addrIn) : addr(addrIn) {}
 
     bool operator()(const CKeyID &id) const { return addr->Set(id); }
     bool operator()(const CScriptID &id) const { return addr->Set(id); }
     bool operator()(const CNoDestination &no) const { return false; }
 };
 
 } // anon namespace
 
 bool CBitcoinAddress::Set(const CKeyID &id) {
     SetData(Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS), &id, 20);
     return true;
 }
 
 bool CBitcoinAddress::Set(const CScriptID &id) {
     SetData(Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS), &id, 20);
     return true;
 }
 
 bool CBitcoinAddress::Set(const CTxDestination &dest) {
     return boost::apply_visitor(CBitcoinAddressVisitor(this), dest);
 }
 
 bool CBitcoinAddress::IsValid() const {
     return IsValid(Params());
 }
 
 bool CBitcoinAddress::IsValid(const CChainParams &params) const {
     bool fCorrectSize = vchData.size() == 20;
     bool fKnownVersion =
         vchVersion == params.Base58Prefix(CChainParams::PUBKEY_ADDRESS) ||
         vchVersion == params.Base58Prefix(CChainParams::SCRIPT_ADDRESS);
     return fCorrectSize && fKnownVersion;
 }
 
 CTxDestination CBitcoinAddress::Get() const {
     if (!IsValid()) return CNoDestination();
     uint160 id;
     memcpy(&id, &vchData[0], 20);
     if (vchVersion == Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS)) {
         return CKeyID(id);
     } else if (vchVersion ==
                Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS)) {
         return CScriptID(id);
     } else {
         return CNoDestination();
     }
 }
 
 bool CBitcoinAddress::GetKeyID(CKeyID &keyID) const {
     if (!IsValid() ||
         vchVersion != Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS)) {
         return false;
     }
     uint160 id;
     memcpy(&id, &vchData[0], 20);
     keyID = CKeyID(id);
     return true;
 }
 
 bool CBitcoinAddress::IsScript() const {
     return IsValid() &&
            vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS);
 }
 
 void CBitcoinSecret::SetKey(const CKey &vchSecret) {
     assert(vchSecret.IsValid());
     SetData(Params().Base58Prefix(CChainParams::SECRET_KEY), vchSecret.begin(),
             vchSecret.size());
     if (vchSecret.IsCompressed()) vchData.push_back(1);
 }
 
 CKey CBitcoinSecret::GetKey() {
     CKey ret;
     assert(vchData.size() >= 32);
     ret.Set(vchData.begin(), vchData.begin() + 32,
             vchData.size() > 32 && vchData[32] == 1);
     return ret;
 }
 
 bool CBitcoinSecret::IsValid() const {
     bool fExpectedFormat =
         vchData.size() == 32 || (vchData.size() == 33 && vchData[32] == 1);
     bool fCorrectVersion =
         vchVersion == Params().Base58Prefix(CChainParams::SECRET_KEY);
     return fExpectedFormat && fCorrectVersion;
 }
 
 bool CBitcoinSecret::SetString(const char *pszSecret) {
     return CBase58Data::SetString(pszSecret) && IsValid();
 }
 
 bool CBitcoinSecret::SetString(const std::string &strSecret) {
     return SetString(strSecret.c_str());
 }
diff --git a/src/base58.h b/src/base58.h
index 847503918..19b24f76d 100644
--- a/src/base58.h
+++ b/src/base58.h
@@ -1,187 +1,185 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-2015 The Bitcoin Core developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 /**
  * Why base-58 instead of standard base-64 encoding?
  * - Don't want 0OIl characters that look the same in some fonts and
  *      could be used to create visually identical looking data.
  * - A string with non-alphanumeric characters is not as easily accepted as
  * input.
  * - E-mail usually won't line-break if there's no punctuation to break at.
  * - Double-clicking selects the whole string as one word if it's all
  * alphanumeric.
  */
 #ifndef BITCOIN_BASE58_H
 #define BITCOIN_BASE58_H
 
 #include "chainparams.h"
 #include "key.h"
 #include "pubkey.h"
 #include "script/script.h"
 #include "script/standard.h"
 #include "support/allocators/zeroafterfree.h"
 
 #include <string>
 #include <vector>
 
 /**
  * Encode a byte sequence as a base58-encoded string.
  * pbegin and pend cannot be nullptr, unless both are.
  */
-std::string EncodeBase58(const unsigned char *pbegin,
-                         const unsigned char *pend);
+std::string EncodeBase58(const uint8_t *pbegin, const uint8_t *pend);
 
 /**
  * Encode a byte vector as a base58-encoded string
  */
-std::string EncodeBase58(const std::vector<unsigned char> &vch);
+std::string EncodeBase58(const std::vector<uint8_t> &vch);
 
 /**
  * Decode a base58-encoded string (psz) into a byte vector (vchRet).
  * return true if decoding is successful.
  * psz cannot be nullptr.
  */
-bool DecodeBase58(const char *psz, std::vector<unsigned char> &vchRet);
+bool DecodeBase58(const char *psz, std::vector<uint8_t> &vchRet);
 
 /**
  * Decode a base58-encoded string (str) into a byte vector (vchRet).
  * return true if decoding is successful.
  */
-bool DecodeBase58(const std::string &str, std::vector<unsigned char> &vchRet);
+bool DecodeBase58(const std::string &str, std::vector<uint8_t> &vchRet);
 
 /**
  * Encode a byte vector into a base58-encoded string, including checksum
  */
-std::string EncodeBase58Check(const std::vector<unsigned char> &vchIn);
+std::string EncodeBase58Check(const std::vector<uint8_t> &vchIn);
 
 /**
  * Decode a base58-encoded string (psz) that includes a checksum into a byte
  * vector (vchRet), return true if decoding is successful
  */
-inline bool DecodeBase58Check(const char *psz,
-                              std::vector<unsigned char> &vchRet);
+inline bool DecodeBase58Check(const char *psz, std::vector<uint8_t> &vchRet);
 
 /**
  * Decode a base58-encoded string (str) that includes a checksum into a byte
  * vector (vchRet), return true if decoding is successful
  */
 inline bool DecodeBase58Check(const std::string &str,
-                              std::vector<unsigned char> &vchRet);
+                              std::vector<uint8_t> &vchRet);
 
 /**
  * Base class for all base58-encoded data
  */
 class CBase58Data {
 protected:
     //! the version byte(s)
-    std::vector<unsigned char> vchVersion;
+    std::vector<uint8_t> vchVersion;
 
     //! the actually encoded data
-    typedef std::vector<unsigned char, zero_after_free_allocator<unsigned char>>
+    typedef std::vector<uint8_t, zero_after_free_allocator<uint8_t>>
         vector_uchar;
     vector_uchar vchData;
 
     CBase58Data();
-    void SetData(const std::vector<unsigned char> &vchVersionIn,
-                 const void *pdata, size_t nSize);
-    void SetData(const std::vector<unsigned char> &vchVersionIn,
-                 const unsigned char *pbegin, const unsigned char *pend);
+    void SetData(const std::vector<uint8_t> &vchVersionIn, const void *pdata,
+                 size_t nSize);
+    void SetData(const std::vector<uint8_t> &vchVersionIn,
+                 const uint8_t *pbegin, const uint8_t *pend);
 
 public:
     bool SetString(const char *psz, unsigned int nVersionBytes = 1);
     bool SetString(const std::string &str);
     std::string ToString() const;
     int CompareTo(const CBase58Data &b58) const;
 
     bool operator==(const CBase58Data &b58) const {
         return CompareTo(b58) == 0;
     }
     bool operator<=(const CBase58Data &b58) const {
         return CompareTo(b58) <= 0;
     }
     bool operator>=(const CBase58Data &b58) const {
         return CompareTo(b58) >= 0;
     }
     bool operator<(const CBase58Data &b58) const { return CompareTo(b58) < 0; }
     bool operator>(const CBase58Data &b58) const { return CompareTo(b58) > 0; }
 };
 
 /** base58-encoded Bitcoin addresses.
  * Public-key-hash-addresses have version 0 (or 111 testnet).
  * The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the
  * serialized public key.
  * Script-hash-addresses have version 5 (or 196 testnet).
  * The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the
  * serialized redemption script.
  */
 class CBitcoinAddress : public CBase58Data {
 public:
     bool Set(const CKeyID &id);
     bool Set(const CScriptID &id);
     bool Set(const CTxDestination &dest);
     bool IsValid() const;
     bool IsValid(const CChainParams &params) const;
 
     CBitcoinAddress() {}
     CBitcoinAddress(const CTxDestination &dest) { Set(dest); }
     CBitcoinAddress(const std::string &strAddress) { SetString(strAddress); }
     CBitcoinAddress(const char *pszAddress) { SetString(pszAddress); }
 
     CTxDestination Get() const;
     bool GetKeyID(CKeyID &keyID) const;
     bool IsScript() const;
 };
 
 /**
  * A base58-encoded secret key
  */
 class CBitcoinSecret : public CBase58Data {
 public:
     void SetKey(const CKey &vchSecret);
     CKey GetKey();
     bool IsValid() const;
     bool SetString(const char *pszSecret);
     bool SetString(const std::string &strSecret);
 
     CBitcoinSecret(const CKey &vchSecret) { SetKey(vchSecret); }
     CBitcoinSecret() {}
 };
 
 template <typename K, int Size, CChainParams::Base58Type Type>
 class CBitcoinExtKeyBase : public CBase58Data {
 public:
     void SetKey(const K &key) {
-        unsigned char vch[Size];
+        uint8_t vch[Size];
         key.Encode(vch);
         SetData(Params().Base58Prefix(Type), vch, vch + Size);
     }
 
     K GetKey() {
         K ret;
         if (vchData.size() == Size) {
             // If base58 encoded data does not hold an ext key, return a
             // !IsValid() key
             ret.Decode(&vchData[0]);
         }
         return ret;
     }
 
     CBitcoinExtKeyBase(const K &key) { SetKey(key); }
 
     CBitcoinExtKeyBase(const std::string &strBase58c) {
         SetString(strBase58c.c_str(), Params().Base58Prefix(Type).size());
     }
 
     CBitcoinExtKeyBase() {}
 };
 
 typedef CBitcoinExtKeyBase<CExtKey, BIP32_EXTKEY_SIZE,
                            CChainParams::EXT_SECRET_KEY>
     CBitcoinExtKey;
 typedef CBitcoinExtKeyBase<CExtPubKey, BIP32_EXTKEY_SIZE,
                            CChainParams::EXT_PUBLIC_KEY>
     CBitcoinExtPubKey;
 
 #endif // BITCOIN_BASE58_H
diff --git a/src/bench/base58.cpp b/src/bench/base58.cpp
index 8e6742125..78e008212 100644
--- a/src/bench/base58.cpp
+++ b/src/bench/base58.cpp
@@ -1,47 +1,45 @@
 // Copyright (c) 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.
 
 #include "bench.h"
 
 #include "base58.h"
 #include "validation.h"
 
 #include <string>
 #include <vector>
 
 static void Base58Encode(benchmark::State &state) {
-    unsigned char buff[32] = {17,  79, 8,   99,  150, 189, 208, 162,
-                              22,  23, 203, 163, 36,  58,  147, 227,
-                              139, 2,  215, 100, 91,  38,  11,  141,
-                              253, 40, 117, 21,  16,  90,  200, 24};
-    unsigned char *b = buff;
+    uint8_t buff[32] = {17,  79,  8,   99,  150, 189, 208, 162, 22,  23, 203,
+                        163, 36,  58,  147, 227, 139, 2,   215, 100, 91, 38,
+                        11,  141, 253, 40,  117, 21,  16,  90,  200, 24};
+    uint8_t *b = buff;
     while (state.KeepRunning()) {
         EncodeBase58(b, b + 32);
     }
 }
 
 static void Base58CheckEncode(benchmark::State &state) {
-    unsigned char buff[32] = {17,  79, 8,   99,  150, 189, 208, 162,
-                              22,  23, 203, 163, 36,  58,  147, 227,
-                              139, 2,  215, 100, 91,  38,  11,  141,
-                              253, 40, 117, 21,  16,  90,  200, 24};
-    unsigned char *b = buff;
-    std::vector<unsigned char> vch;
+    uint8_t buff[32] = {17,  79,  8,   99,  150, 189, 208, 162, 22,  23, 203,
+                        163, 36,  58,  147, 227, 139, 2,   215, 100, 91, 38,
+                        11,  141, 253, 40,  117, 21,  16,  90,  200, 24};
+    uint8_t *b = buff;
+    std::vector<uint8_t> vch;
     vch.assign(b, b + 32);
     while (state.KeepRunning()) {
         EncodeBase58Check(vch);
     }
 }
 
 static void Base58Decode(benchmark::State &state) {
     const char *addr = "17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem";
-    std::vector<unsigned char> vch;
+    std::vector<uint8_t> vch;
     while (state.KeepRunning()) {
         DecodeBase58(addr, vch);
     }
 }
 
 BENCHMARK(Base58Encode);
 BENCHMARK(Base58CheckEncode);
 BENCHMARK(Base58Decode);
diff --git a/src/bench/ccoins_caching.cpp b/src/bench/ccoins_caching.cpp
index e38a2eacb..8d76d0eec 100644
--- a/src/bench/ccoins_caching.cpp
+++ b/src/bench/ccoins_caching.cpp
@@ -1,94 +1,94 @@
 // Copyright (c) 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.
 
 #include "bench.h"
 #include "coins.h"
 #include "policy/policy.h"
 #include "wallet/crypter.h"
 
 #include <vector>
 
 // FIXME: Dedup with SetupDummyInputs in test/transaction_tests.cpp.
 //
 // Helper: create two dummy transactions, each with
 // two outputs.  The first has 11 and 50 CENT outputs
 // paid to a TX_PUBKEY, the second 21 and 22 CENT outputs
 // paid to a TX_PUBKEYHASH.
 //
 static std::vector<CMutableTransaction>
 SetupDummyInputs(CBasicKeyStore &keystoreRet, CCoinsViewCache &coinsRet) {
     std::vector<CMutableTransaction> dummyTransactions;
     dummyTransactions.resize(2);
 
     // Add some keys to the keystore:
     CKey key[4];
     for (int i = 0; i < 4; i++) {
         key[i].MakeNewKey(i % 2);
         keystoreRet.AddKey(key[i]);
     }
 
     // Create some dummy input transactions
     dummyTransactions[0].vout.resize(2);
     dummyTransactions[0].vout[0].nValue = 11 * CENT;
     dummyTransactions[0].vout[0].scriptPubKey
         << ToByteVector(key[0].GetPubKey()) << OP_CHECKSIG;
     dummyTransactions[0].vout[1].nValue = 50 * CENT;
     dummyTransactions[0].vout[1].scriptPubKey
         << ToByteVector(key[1].GetPubKey()) << OP_CHECKSIG;
     coinsRet.ModifyCoins(dummyTransactions[0].GetId())
         ->FromTx(dummyTransactions[0], 0);
 
     dummyTransactions[1].vout.resize(2);
     dummyTransactions[1].vout[0].nValue = 21 * CENT;
     dummyTransactions[1].vout[0].scriptPubKey =
         GetScriptForDestination(key[2].GetPubKey().GetID());
     dummyTransactions[1].vout[1].nValue = 22 * CENT;
     dummyTransactions[1].vout[1].scriptPubKey =
         GetScriptForDestination(key[3].GetPubKey().GetID());
     coinsRet.ModifyCoins(dummyTransactions[1].GetId())
         ->FromTx(dummyTransactions[1], 0);
 
     return dummyTransactions;
 }
 
 // Microbenchmark for simple accesses to a CCoinsViewCache database. Note from
 // laanwj, "replicating the actual usage patterns of the client is hard though,
 // many times micro-benchmarks of the database showed completely different
 // characteristics than e.g. reindex timings. But that's not a requirement of
 // every benchmark."
 // (https://github.com/bitcoin/bitcoin/issues/7883#issuecomment-224807484)
 static void CCoinsCaching(benchmark::State &state) {
     CBasicKeyStore keystore;
     CCoinsView coinsDummy;
     CCoinsViewCache coins(&coinsDummy);
     std::vector<CMutableTransaction> dummyTransactions =
         SetupDummyInputs(keystore, coins);
 
     CMutableTransaction t1;
     t1.vin.resize(3);
     t1.vin[0].prevout.hash = dummyTransactions[0].GetId();
     t1.vin[0].prevout.n = 1;
-    t1.vin[0].scriptSig << std::vector<unsigned char>(65, 0);
+    t1.vin[0].scriptSig << std::vector<uint8_t>(65, 0);
     t1.vin[1].prevout.hash = dummyTransactions[1].GetId();
     t1.vin[1].prevout.n = 0;
-    t1.vin[1].scriptSig << std::vector<unsigned char>(65, 0)
-                        << std::vector<unsigned char>(33, 4);
+    t1.vin[1].scriptSig << std::vector<uint8_t>(65, 0)
+                        << std::vector<uint8_t>(33, 4);
     t1.vin[2].prevout.hash = dummyTransactions[1].GetId();
     t1.vin[2].prevout.n = 1;
-    t1.vin[2].scriptSig << std::vector<unsigned char>(65, 0)
-                        << std::vector<unsigned char>(33, 4);
+    t1.vin[2].scriptSig << std::vector<uint8_t>(65, 0)
+                        << std::vector<uint8_t>(33, 4);
     t1.vout.resize(2);
     t1.vout[0].nValue = 90 * CENT;
     t1.vout[0].scriptPubKey << OP_1;
 
     // Benchmark.
     while (state.KeepRunning()) {
         bool success = AreInputsStandard(t1, coins);
         assert(success);
         CAmount value = coins.GetValueIn(t1);
         assert(value == (50 + 21 + 22) * CENT);
     }
 }
 
 BENCHMARK(CCoinsCaching);
diff --git a/src/bench/rollingbloom.cpp b/src/bench/rollingbloom.cpp
index 8f76292d0..0a5a22d87 100644
--- a/src/bench/rollingbloom.cpp
+++ b/src/bench/rollingbloom.cpp
@@ -1,44 +1,44 @@
 // Copyright (c) 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.
 
 #include <iostream>
 
 #include "bench.h"
 #include "bloom.h"
 #include "utiltime.h"
 
 static void RollingBloom(benchmark::State &state) {
     CRollingBloomFilter filter(120000, 0.000001);
-    std::vector<unsigned char> data(32);
+    std::vector<uint8_t> data(32);
     uint32_t count = 0;
     uint32_t nEntriesPerGeneration = (120000 + 1) / 2;
     uint32_t countnow = 0;
     uint64_t match = 0;
     while (state.KeepRunning()) {
         count++;
         data[0] = count;
         data[1] = count >> 8;
         data[2] = count >> 16;
         data[3] = count >> 24;
         if (countnow == nEntriesPerGeneration) {
             int64_t b = GetTimeMicros();
             filter.insert(data);
             int64_t e = GetTimeMicros();
             std::cout << "RollingBloom-refresh,1," << (e - b) * 0.000001 << ","
                       << (e - b) * 0.000001 << "," << (e - b) * 0.000001
                       << "\n";
             countnow = 0;
         } else {
             filter.insert(data);
         }
         countnow++;
         data[0] = count >> 24;
         data[1] = count >> 16;
         data[2] = count >> 8;
         data[3] = count;
         match += filter.contains(data);
     }
 }
 
 BENCHMARK(RollingBloom);
diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp
index 53649c502..55ffa5cf6 100644
--- a/src/bitcoin-tx.cpp
+++ b/src/bitcoin-tx.cpp
@@ -1,906 +1,906 @@
 // Copyright (c) 2009-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.
 
 #if defined(HAVE_CONFIG_H)
 #include "config/bitcoin-config.h"
 #endif
 
 #include "base58.h"
 #include "clientversion.h"
 #include "coins.h"
 #include "consensus/consensus.h"
 #include "core_io.h"
 #include "keystore.h"
 #include "policy/policy.h"
 #include "primitives/transaction.h"
 #include "script/script.h"
 #include "script/sign.h"
 #include "univalue.h"
 #include "util.h"
 #include "utilmoneystr.h"
 #include "utilstrencodings.h"
 
 #include <cstdio>
 
 #include <boost/algorithm/string.hpp>
 #include <boost/assign/list_of.hpp>
 
 static bool fCreateBlank;
 static std::map<std::string, UniValue> registers;
 static const int CONTINUE_EXECUTION = -1;
 
 //
 // This function returns either one of EXIT_ codes when it's expected to stop
 // the process or CONTINUE_EXECUTION when it's expected to continue further.
 //
 static int AppInitRawTx(int argc, char *argv[]) {
     //
     // Parameters
     //
     ParseParameters(argc, argv);
 
     // Check for -testnet or -regtest parameter (Params() calls are only valid
     // after this clause)
     try {
         SelectParams(ChainNameFromCommandLine());
     } catch (const std::exception &e) {
         fprintf(stderr, "Error: %s\n", e.what());
         return EXIT_FAILURE;
     }
 
     fCreateBlank = GetBoolArg("-create", false);
 
     if (argc < 2 || IsArgSet("-?") || IsArgSet("-h") || IsArgSet("-help")) {
         // First part of help message is specific to this utility
         std::string strUsage =
             strprintf(_("%s bitcoin-tx utility version"), _(PACKAGE_NAME)) +
             " " + FormatFullVersion() + "\n\n" + _("Usage:") + "\n" +
             "  bitcoin-tx [options] <hex-tx> [commands]  " +
             _("Update hex-encoded bitcoin transaction") + "\n" +
             "  bitcoin-tx [options] -create [commands]   " +
             _("Create hex-encoded bitcoin transaction") + "\n" + "\n";
 
         fprintf(stdout, "%s", strUsage.c_str());
 
         strUsage = HelpMessageGroup(_("Options:"));
         strUsage += HelpMessageOpt("-?", _("This help message"));
         strUsage += HelpMessageOpt("-create", _("Create new, empty TX."));
         strUsage += HelpMessageOpt("-json", _("Select JSON output"));
         strUsage +=
             HelpMessageOpt("-txid", _("Output only the hex-encoded transaction "
                                       "id of the resultant transaction."));
         AppendParamsHelpMessages(strUsage);
 
         fprintf(stdout, "%s", strUsage.c_str());
 
         strUsage = HelpMessageGroup(_("Commands:"));
         strUsage += HelpMessageOpt("delin=N", _("Delete input N from TX"));
         strUsage += HelpMessageOpt("delout=N", _("Delete output N from TX"));
         strUsage += HelpMessageOpt("in=TXID:VOUT(:SEQUENCE_NUMBER)",
                                    _("Add input to TX"));
         strUsage += HelpMessageOpt("locktime=N", _("Set TX lock time to N"));
         strUsage += HelpMessageOpt("nversion=N", _("Set TX version to N"));
         strUsage += HelpMessageOpt("outaddr=VALUE:ADDRESS",
                                    _("Add address-based output to TX"));
         strUsage +=
             HelpMessageOpt("outpubkey=VALUE:PUBKEY[:FLAGS]",
                            _("Add pay-to-pubkey output to TX") + ". " +
                                _("Optionally add the \"S\" flag to wrap the "
                                  "output in a pay-to-script-hash."));
         strUsage += HelpMessageOpt("outdata=[VALUE:]DATA",
                                    _("Add data-based output to TX"));
         strUsage +=
             HelpMessageOpt("outscript=VALUE:SCRIPT[:FLAGS]",
                            _("Add raw script output to TX") + ". " +
                                _("Optionally add the \"S\" flag to wrap the "
                                  "output in a pay-to-script-hash."));
         strUsage += HelpMessageOpt(
             "outmultisig=VALUE:REQUIRED:PUBKEYS:PUBKEY1:PUBKEY2:....[:FLAGS]",
             _("Add Pay To n-of-m Multi-sig output to TX. n = REQUIRED, m = "
               "PUBKEYS") +
                 ". " + _("Optionally add the \"S\" flag to wrap the output in "
                          "a pay-to-script-hash."));
         strUsage += HelpMessageOpt(
             "sign=SIGHASH-FLAGS",
             _("Add zero or more signatures to transaction") + ". " +
                 _("This command requires JSON registers:") +
                 _("prevtxs=JSON object") + ", " + _("privatekeys=JSON object") +
                 ". " + _("See signrawtransaction docs for format of sighash "
                          "flags, JSON objects."));
         fprintf(stdout, "%s", strUsage.c_str());
 
         strUsage = HelpMessageGroup(_("Register Commands:"));
         strUsage +=
             HelpMessageOpt("load=NAME:FILENAME",
                            _("Load JSON file FILENAME into register NAME"));
         strUsage += HelpMessageOpt("set=NAME:JSON-STRING",
                                    _("Set register NAME to given JSON-STRING"));
         fprintf(stdout, "%s", strUsage.c_str());
 
         if (argc < 2) {
             fprintf(stderr, "Error: too few parameters\n");
             return EXIT_FAILURE;
         }
 
         return EXIT_SUCCESS;
     }
 
     return CONTINUE_EXECUTION;
 }
 
 static void RegisterSetJson(const std::string &key,
                             const std::string &rawJson) {
     UniValue val;
     if (!val.read(rawJson)) {
         std::string strErr = "Cannot parse JSON for key " + key;
         throw std::runtime_error(strErr);
     }
 
     registers[key] = val;
 }
 
 static void RegisterSet(const std::string &strInput) {
     // separate NAME:VALUE in string
     size_t pos = strInput.find(':');
     if ((pos == std::string::npos) || (pos == 0) ||
         (pos == (strInput.size() - 1))) {
         throw std::runtime_error("Register input requires NAME:VALUE");
     }
 
     std::string key = strInput.substr(0, pos);
     std::string valStr = strInput.substr(pos + 1, std::string::npos);
 
     RegisterSetJson(key, valStr);
 }
 
 static void RegisterLoad(const std::string &strInput) {
     // separate NAME:FILENAME in string
     size_t pos = strInput.find(':');
     if ((pos == std::string::npos) || (pos == 0) ||
         (pos == (strInput.size() - 1))) {
         throw std::runtime_error("Register load requires NAME:FILENAME");
     }
 
     std::string key = strInput.substr(0, pos);
     std::string filename = strInput.substr(pos + 1, std::string::npos);
 
     FILE *f = fopen(filename.c_str(), "r");
     if (!f) {
         std::string strErr = "Cannot open file " + filename;
         throw std::runtime_error(strErr);
     }
 
     // load file chunks into one big buffer
     std::string valStr;
     while ((!feof(f)) && (!ferror(f))) {
         char buf[4096];
         int bread = fread(buf, 1, sizeof(buf), f);
         if (bread <= 0) {
             break;
         }
 
         valStr.insert(valStr.size(), buf, bread);
     }
 
     int error = ferror(f);
     fclose(f);
 
     if (error) {
         std::string strErr = "Error reading file " + filename;
         throw std::runtime_error(strErr);
     }
 
     // evaluate as JSON buffer register
     RegisterSetJson(key, valStr);
 }
 
 static CAmount ExtractAndValidateValue(const std::string &strValue) {
     CAmount value;
     if (!ParseMoney(strValue, value)) {
         throw std::runtime_error("invalid TX output value");
     }
 
     return value;
 }
 
 static void MutateTxVersion(CMutableTransaction &tx,
                             const std::string &cmdVal) {
     int64_t newVersion = atoi64(cmdVal);
     if (newVersion < 1 || newVersion > CTransaction::MAX_STANDARD_VERSION) {
         throw std::runtime_error("Invalid TX version requested");
     }
 
     tx.nVersion = int(newVersion);
 }
 
 static void MutateTxLocktime(CMutableTransaction &tx,
                              const std::string &cmdVal) {
     int64_t newLocktime = atoi64(cmdVal);
     if (newLocktime < 0LL || newLocktime > 0xffffffffLL) {
         throw std::runtime_error("Invalid TX locktime requested");
     }
 
     tx.nLockTime = (unsigned int)newLocktime;
 }
 
 static void MutateTxAddInput(CMutableTransaction &tx,
                              const std::string &strInput) {
     std::vector<std::string> vStrInputParts;
     boost::split(vStrInputParts, strInput, boost::is_any_of(":"));
 
     // separate TXID:VOUT in string
     if (vStrInputParts.size() < 2) {
         throw std::runtime_error("TX input missing separator");
     }
 
     // extract and validate TXID
     std::string strTxid = vStrInputParts[0];
     if ((strTxid.size() != 64) || !IsHex(strTxid)) {
         throw std::runtime_error("invalid TX input txid");
     }
 
     uint256 txid(uint256S(strTxid));
 
     static const unsigned int minTxOutSz = 9;
     static const unsigned int maxVout = MAX_TX_SIZE / minTxOutSz;
 
     // extract and validate vout
     std::string strVout = vStrInputParts[1];
     int vout = atoi(strVout);
     if ((vout < 0) || (vout > (int)maxVout)) {
         throw std::runtime_error("invalid TX input vout");
     }
 
     // extract the optional sequence number
     uint32_t nSequenceIn = std::numeric_limits<unsigned int>::max();
     if (vStrInputParts.size() > 2) {
         nSequenceIn = std::stoul(vStrInputParts[2]);
     }
 
     // append to transaction input list
     CTxIn txin(txid, vout, CScript(), nSequenceIn);
     tx.vin.push_back(txin);
 }
 
 static void MutateTxAddOutAddr(CMutableTransaction &tx,
                                const std::string &strInput) {
     // Separate into VALUE:ADDRESS
     std::vector<std::string> vStrInputParts;
     boost::split(vStrInputParts, strInput, boost::is_any_of(":"));
 
     if (vStrInputParts.size() != 2) {
         throw std::runtime_error("TX output missing or too many separators");
     }
 
     // Extract and validate VALUE
     CAmount value = ExtractAndValidateValue(vStrInputParts[0]);
 
     // extract and validate ADDRESS
     std::string strAddr = vStrInputParts[1];
     CBitcoinAddress addr(strAddr);
     if (!addr.IsValid()) {
         throw std::runtime_error("invalid TX output address");
     }
 
     // build standard output script via GetScriptForDestination()
     CScript scriptPubKey = GetScriptForDestination(addr.Get());
 
     // construct TxOut, append to transaction output list
     CTxOut txout(value, scriptPubKey);
     tx.vout.push_back(txout);
 }
 
 static void MutateTxAddOutPubKey(CMutableTransaction &tx,
                                  const std::string &strInput) {
     // Separate into VALUE:PUBKEY[:FLAGS]
     std::vector<std::string> vStrInputParts;
     boost::split(vStrInputParts, strInput, boost::is_any_of(":"));
 
     if (vStrInputParts.size() < 2 || vStrInputParts.size() > 3) {
         throw std::runtime_error("TX output missing or too many separators");
     }
 
     // Extract and validate VALUE
     CAmount value = ExtractAndValidateValue(vStrInputParts[0]);
 
     // Extract and validate PUBKEY
     CPubKey pubkey(ParseHex(vStrInputParts[1]));
     if (!pubkey.IsFullyValid()) {
         throw std::runtime_error("invalid TX output pubkey");
     }
 
     CScript scriptPubKey = GetScriptForRawPubKey(pubkey);
     CBitcoinAddress addr(scriptPubKey);
 
     // Extract and validate FLAGS
     bool bScriptHash = false;
     if (vStrInputParts.size() == 3) {
         std::string flags = vStrInputParts[2];
         bScriptHash = (flags.find("S") != std::string::npos);
     }
 
     if (bScriptHash) {
         // Get the address for the redeem script, then call
         // GetScriptForDestination() to construct a P2SH scriptPubKey.
         CBitcoinAddress redeemScriptAddr(scriptPubKey);
         scriptPubKey = GetScriptForDestination(redeemScriptAddr.Get());
     }
 
     // construct TxOut, append to transaction output list
     CTxOut txout(value, scriptPubKey);
     tx.vout.push_back(txout);
 }
 
 static void MutateTxAddOutMultiSig(CMutableTransaction &tx,
                                    const std::string &strInput) {
     // Separate into VALUE:REQUIRED:NUMKEYS:PUBKEY1:PUBKEY2:....[:FLAGS]
     std::vector<std::string> vStrInputParts;
     boost::split(vStrInputParts, strInput, boost::is_any_of(":"));
 
     // Check that there are enough parameters
     if (vStrInputParts.size() < 3) {
         throw std::runtime_error("Not enough multisig parameters");
     }
 
     // Extract and validate VALUE
     CAmount value = ExtractAndValidateValue(vStrInputParts[0]);
 
     // Extract REQUIRED
     uint32_t required = stoul(vStrInputParts[1]);
 
     // Extract NUMKEYS
     uint32_t numkeys = stoul(vStrInputParts[2]);
 
     // Validate there are the correct number of pubkeys
     if (vStrInputParts.size() < numkeys + 3) {
         throw std::runtime_error("incorrect number of multisig pubkeys");
     }
 
     if (required < 1 || required > 20 || numkeys < 1 || numkeys > 20 ||
         numkeys < required) {
         throw std::runtime_error("multisig parameter mismatch. Required " +
                                  std::to_string(required) + " of " +
                                  std::to_string(numkeys) + "signatures.");
     }
 
     // extract and validate PUBKEYs
     std::vector<CPubKey> pubkeys;
     for (int pos = 1; pos <= int(numkeys); pos++) {
         CPubKey pubkey(ParseHex(vStrInputParts[pos + 2]));
         if (!pubkey.IsFullyValid()) {
             throw std::runtime_error("invalid TX output pubkey");
         }
 
         pubkeys.push_back(pubkey);
     }
 
     // Extract FLAGS
     bool bScriptHash = false;
     if (vStrInputParts.size() == numkeys + 4) {
         std::string flags = vStrInputParts.back();
         bScriptHash = (flags.find("S") != std::string::npos);
     } else if (vStrInputParts.size() > numkeys + 4) {
         // Validate that there were no more parameters passed
         throw std::runtime_error("Too many parameters");
     }
 
     CScript scriptPubKey = GetScriptForMultisig(required, pubkeys);
 
     if (bScriptHash) {
         // Get the address for the redeem script, then call
         // GetScriptForDestination() to construct a P2SH scriptPubKey.
         CBitcoinAddress addr(scriptPubKey);
         scriptPubKey = GetScriptForDestination(addr.Get());
     }
 
     // construct TxOut, append to transaction output list
     CTxOut txout(value, scriptPubKey);
     tx.vout.push_back(txout);
 }
 
 static void MutateTxAddOutData(CMutableTransaction &tx,
                                const std::string &strInput) {
     CAmount value = 0;
 
     // separate [VALUE:]DATA in string
     size_t pos = strInput.find(':');
 
     if (pos == 0) {
         throw std::runtime_error("TX output value not specified");
     }
 
     if (pos != std::string::npos) {
         // Extract and validate VALUE
         value = ExtractAndValidateValue(strInput.substr(0, pos));
     }
 
     // extract and validate DATA
     std::string strData = strInput.substr(pos + 1, std::string::npos);
 
     if (!IsHex(strData)) {
         throw std::runtime_error("invalid TX output data");
     }
 
-    std::vector<unsigned char> data = ParseHex(strData);
+    std::vector<uint8_t> data = ParseHex(strData);
 
     CTxOut txout(value, CScript() << OP_RETURN << data);
     tx.vout.push_back(txout);
 }
 
 static void MutateTxAddOutScript(CMutableTransaction &tx,
                                  const std::string &strInput) {
     // separate VALUE:SCRIPT[:FLAGS]
     std::vector<std::string> vStrInputParts;
     boost::split(vStrInputParts, strInput, boost::is_any_of(":"));
     if (vStrInputParts.size() < 2)
         throw std::runtime_error("TX output missing separator");
 
     // Extract and validate VALUE
     CAmount value = ExtractAndValidateValue(vStrInputParts[0]);
 
     // extract and validate script
     std::string strScript = vStrInputParts[1];
     CScript scriptPubKey = ParseScript(strScript);
 
     // Extract FLAGS
     bool bScriptHash = false;
     if (vStrInputParts.size() == 3) {
         std::string flags = vStrInputParts.back();
         bScriptHash = (flags.find("S") != std::string::npos);
     }
 
     if (bScriptHash) {
         CBitcoinAddress addr(scriptPubKey);
         scriptPubKey = GetScriptForDestination(addr.Get());
     }
 
     // construct TxOut, append to transaction output list
     CTxOut txout(value, scriptPubKey);
     tx.vout.push_back(txout);
 }
 
 static void MutateTxDelInput(CMutableTransaction &tx,
                              const std::string &strInIdx) {
     // parse requested deletion index
     int inIdx = atoi(strInIdx);
     if (inIdx < 0 || inIdx >= (int)tx.vin.size()) {
         std::string strErr = "Invalid TX input index '" + strInIdx + "'";
         throw std::runtime_error(strErr.c_str());
     }
 
     // delete input from transaction
     tx.vin.erase(tx.vin.begin() + inIdx);
 }
 
 static void MutateTxDelOutput(CMutableTransaction &tx,
                               const std::string &strOutIdx) {
     // parse requested deletion index
     int outIdx = atoi(strOutIdx);
     if (outIdx < 0 || outIdx >= (int)tx.vout.size()) {
         std::string strErr = "Invalid TX output index '" + strOutIdx + "'";
         throw std::runtime_error(strErr.c_str());
     }
 
     // delete output from transaction
     tx.vout.erase(tx.vout.begin() + outIdx);
 }
 
 static const unsigned int N_SIGHASH_OPTS = 12;
 static const struct {
     const char *flagStr;
     int flags;
 } sighashOptions[N_SIGHASH_OPTS] = {
     {"ALL", SIGHASH_ALL},
     {"NONE", SIGHASH_NONE},
     {"SINGLE", SIGHASH_SINGLE},
     {"ALL|ANYONECANPAY", SIGHASH_ALL | SIGHASH_ANYONECANPAY},
     {"NONE|ANYONECANPAY", SIGHASH_NONE | SIGHASH_ANYONECANPAY},
     {"SINGLE|ANYONECANPAY", SIGHASH_SINGLE | SIGHASH_ANYONECANPAY},
     {"ALL|FORKID", SIGHASH_ALL | SIGHASH_FORKID},
     {"NONE|FORKID", SIGHASH_NONE | SIGHASH_FORKID},
     {"SINGLE|FORKID", SIGHASH_SINGLE | SIGHASH_FORKID},
     {"ALL|FORKID|ANYONECANPAY",
      SIGHASH_ALL | SIGHASH_FORKID | SIGHASH_ANYONECANPAY},
     {"NONE|FORKID|ANYONECANPAY",
      SIGHASH_NONE | SIGHASH_FORKID | SIGHASH_ANYONECANPAY},
     {"SINGLE|FORKID|ANYONECANPAY",
      SIGHASH_SINGLE | SIGHASH_FORKID | SIGHASH_ANYONECANPAY},
 };
 
 static bool findSighashFlags(int &flags, const std::string &flagStr) {
     flags = 0;
 
     for (unsigned int i = 0; i < N_SIGHASH_OPTS; i++) {
         if (flagStr == sighashOptions[i].flagStr) {
             flags = sighashOptions[i].flags;
             return true;
         }
     }
 
     return false;
 }
 
 uint256 ParseHashUO(std::map<std::string, UniValue> &o, std::string strKey) {
     if (!o.count(strKey)) {
         return uint256();
     }
 
     return ParseHashUV(o[strKey], strKey);
 }
 
-std::vector<unsigned char> ParseHexUO(std::map<std::string, UniValue> &o,
-                                      std::string strKey) {
+std::vector<uint8_t> ParseHexUO(std::map<std::string, UniValue> &o,
+                                std::string strKey) {
     if (!o.count(strKey)) {
-        std::vector<unsigned char> emptyVec;
+        std::vector<uint8_t> emptyVec;
         return emptyVec;
     }
 
     return ParseHexUV(o[strKey], strKey);
 }
 
 static CAmount AmountFromValue(const UniValue &value) {
     if (!value.isNum() && !value.isStr()) {
         throw std::runtime_error("Amount is not a number or string");
     }
 
     CAmount amount;
     if (!ParseFixedPoint(value.getValStr(), 8, &amount)) {
         throw std::runtime_error("Invalid amount");
     }
 
     if (!MoneyRange(amount)) {
         throw std::runtime_error("Amount out of range");
     }
 
     return amount;
 }
 
 static void MutateTxSign(CMutableTransaction &tx, const std::string &flagStr) {
     int nHashType = SIGHASH_ALL | SIGHASH_FORKID;
 
     if ((flagStr.size() > 0) && !findSighashFlags(nHashType, flagStr)) {
         throw std::runtime_error("unknown sighash flag/sign option");
     }
 
     std::vector<CTransaction> txVariants;
     txVariants.push_back(tx);
 
     // mergedTx will end up with all the signatures; it starts as a clone of the
     // raw tx:
     CMutableTransaction mergedTx(txVariants[0]);
     bool fComplete = true;
     CCoinsView viewDummy;
     CCoinsViewCache view(&viewDummy);
 
     if (!registers.count("privatekeys")) {
         throw std::runtime_error("privatekeys register variable must be set.");
     }
 
     CBasicKeyStore tempKeystore;
     UniValue keysObj = registers["privatekeys"];
 
     for (unsigned int kidx = 0; kidx < keysObj.size(); kidx++) {
         if (!keysObj[kidx].isStr()) {
             throw std::runtime_error("privatekey not a std::string");
         }
 
         CBitcoinSecret vchSecret;
         bool fGood = vchSecret.SetString(keysObj[kidx].getValStr());
         if (!fGood) {
             throw std::runtime_error("privatekey not valid");
         }
 
         CKey key = vchSecret.GetKey();
         tempKeystore.AddKey(key);
     }
 
     // Add previous txouts given in the RPC call:
     if (!registers.count("prevtxs")) {
         throw std::runtime_error("prevtxs register variable must be set.");
     }
 
     UniValue prevtxsObj = registers["prevtxs"];
 
     for (unsigned int previdx = 0; previdx < prevtxsObj.size(); previdx++) {
         UniValue prevOut = prevtxsObj[previdx];
         if (!prevOut.isObject()) {
             throw std::runtime_error("expected prevtxs internal object");
         }
 
         std::map<std::string, UniValue::VType> types =
             boost::assign::map_list_of("txid", UniValue::VSTR)(
                 "vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR);
         if (!prevOut.checkObject(types)) {
             throw std::runtime_error("prevtxs internal object typecheck fail");
         }
 
         uint256 txid = ParseHashUV(prevOut["txid"], "txid");
 
         int nOut = atoi(prevOut["vout"].getValStr());
         if (nOut < 0) {
             throw std::runtime_error("vout must be positive");
         }
 
-        std::vector<unsigned char> pkData(
+        std::vector<uint8_t> pkData(
             ParseHexUV(prevOut["scriptPubKey"], "scriptPubKey"));
         CScript scriptPubKey(pkData.begin(), pkData.end());
 
         {
             CCoinsModifier coins = view.ModifyCoins(txid);
             if (coins->IsAvailable(nOut) &&
                 coins->vout[nOut].scriptPubKey != scriptPubKey) {
                 std::string err("Previous output scriptPubKey mismatch:\n");
                 err = err + ScriptToAsmStr(coins->vout[nOut].scriptPubKey) +
                       "\nvs:\n" + ScriptToAsmStr(scriptPubKey);
                 throw std::runtime_error(err);
             }
 
             if ((unsigned int)nOut >= coins->vout.size()) {
                 coins->vout.resize(nOut + 1);
             }
 
             coins->vout[nOut].scriptPubKey = scriptPubKey;
             coins->vout[nOut].nValue = 0;
             if (prevOut.exists("amount")) {
                 coins->vout[nOut].nValue = AmountFromValue(prevOut["amount"]);
             }
         }
 
         // If redeemScript given and private keys given, add redeemScript to the
         // tempKeystore so it can be signed:
         if (scriptPubKey.IsPayToScriptHash() &&
             prevOut.exists("redeemScript")) {
             UniValue v = prevOut["redeemScript"];
-            std::vector<unsigned char> rsData(ParseHexUV(v, "redeemScript"));
+            std::vector<uint8_t> rsData(ParseHexUV(v, "redeemScript"));
             CScript redeemScript(rsData.begin(), rsData.end());
             tempKeystore.AddCScript(redeemScript);
         }
     }
 
     const CKeyStore &keystore = tempKeystore;
 
     bool fHashSingle =
         ((nHashType & ~(SIGHASH_ANYONECANPAY | SIGHASH_FORKID)) ==
          SIGHASH_SINGLE);
 
     // Sign what we can:
     for (size_t i = 0; i < mergedTx.vin.size(); i++) {
         CTxIn &txin = mergedTx.vin[i];
         const Coin &coin = view.AccessCoin(txin.prevout);
         if (coin.IsSpent()) {
             fComplete = false;
             continue;
         }
 
         const CScript &prevPubKey = coin.GetTxOut().scriptPubKey;
         const CAmount &amount = coin.GetTxOut().nValue;
 
         SignatureData sigdata;
         // Only sign SIGHASH_SINGLE if there's a corresponding output:
         if (!fHashSingle || (i < mergedTx.vout.size())) {
             ProduceSignature(MutableTransactionSignatureCreator(
                                  &keystore, &mergedTx, i, amount, nHashType),
                              prevPubKey, sigdata);
         }
 
         // ... and merge in other signatures:
         for (const CTransaction &txv : txVariants) {
             sigdata = CombineSignatures(
                 prevPubKey,
                 MutableTransactionSignatureChecker(&mergedTx, i, amount),
                 sigdata, DataFromTransaction(txv, i));
         }
 
         UpdateTransaction(mergedTx, i, sigdata);
 
         if (!VerifyScript(
                 txin.scriptSig, prevPubKey,
                 STANDARD_SCRIPT_VERIFY_FLAGS | SCRIPT_ENABLE_SIGHASH_FORKID,
                 MutableTransactionSignatureChecker(&mergedTx, i, amount))) {
             fComplete = false;
         }
     }
 
     if (fComplete) {
         // do nothing... for now
         // perhaps store this for later optional JSON output
     }
 
     tx = mergedTx;
 }
 
 class Secp256k1Init {
     ECCVerifyHandle globalVerifyHandle;
 
 public:
     Secp256k1Init() { ECC_Start(); }
     ~Secp256k1Init() { ECC_Stop(); }
 };
 
 static void MutateTx(CMutableTransaction &tx, const std::string &command,
                      const std::string &commandVal) {
     std::unique_ptr<Secp256k1Init> ecc;
 
     if (command == "nversion") {
         MutateTxVersion(tx, commandVal);
     } else if (command == "locktime") {
         MutateTxLocktime(tx, commandVal);
     } else if (command == "delin") {
         MutateTxDelInput(tx, commandVal);
     } else if (command == "in") {
         MutateTxAddInput(tx, commandVal);
     } else if (command == "delout") {
         MutateTxDelOutput(tx, commandVal);
     } else if (command == "outaddr") {
         MutateTxAddOutAddr(tx, commandVal);
     } else if (command == "outpubkey") {
         MutateTxAddOutPubKey(tx, commandVal);
     } else if (command == "outmultisig") {
         MutateTxAddOutMultiSig(tx, commandVal);
     } else if (command == "outscript") {
         MutateTxAddOutScript(tx, commandVal);
     } else if (command == "outdata") {
         MutateTxAddOutData(tx, commandVal);
     } else if (command == "sign") {
         if (!ecc) {
             ecc.reset(new Secp256k1Init());
         }
 
         MutateTxSign(tx, commandVal);
     } else if (command == "load") {
         RegisterLoad(commandVal);
     } else if (command == "set") {
         RegisterSet(commandVal);
     } else {
         throw std::runtime_error("unknown command");
     }
 }
 
 static void OutputTxJSON(const CTransaction &tx) {
     UniValue entry(UniValue::VOBJ);
     TxToUniv(tx, uint256(), entry);
 
     std::string jsonOutput = entry.write(4);
     fprintf(stdout, "%s\n", jsonOutput.c_str());
 }
 
 static void OutputTxHash(const CTransaction &tx) {
     // the hex-encoded transaction id.
     std::string strHexHash = tx.GetId().GetHex();
 
     fprintf(stdout, "%s\n", strHexHash.c_str());
 }
 
 static void OutputTxHex(const CTransaction &tx) {
     std::string strHex = EncodeHexTx(tx);
 
     fprintf(stdout, "%s\n", strHex.c_str());
 }
 
 static void OutputTx(const CTransaction &tx) {
     if (GetBoolArg("-json", false)) {
         OutputTxJSON(tx);
     } else if (GetBoolArg("-txid", false)) {
         OutputTxHash(tx);
     } else {
         OutputTxHex(tx);
     }
 }
 
 static std::string readStdin() {
     char buf[4096];
     std::string ret;
 
     while (!feof(stdin)) {
         size_t bread = fread(buf, 1, sizeof(buf), stdin);
         ret.append(buf, bread);
         if (bread < sizeof(buf)) {
             break;
         }
     }
 
     if (ferror(stdin)) {
         throw std::runtime_error("error reading stdin");
     }
 
     boost::algorithm::trim_right(ret);
 
     return ret;
 }
 
 static int CommandLineRawTx(int argc, char *argv[]) {
     std::string strPrint;
     int nRet = 0;
     try {
         // Skip switches; Permit common stdin convention "-"
         while (argc > 1 && IsSwitchChar(argv[1][0]) && (argv[1][1] != 0)) {
             argc--;
             argv++;
         }
 
         CMutableTransaction tx;
         int startArg;
 
         if (!fCreateBlank) {
             // require at least one param
             if (argc < 2) {
                 throw std::runtime_error("too few parameters");
             }
 
             // param: hex-encoded bitcoin transaction
             std::string strHexTx(argv[1]);
 
             // "-" implies standard input
             if (strHexTx == "-") {
                 strHexTx = readStdin();
             }
 
             if (!DecodeHexTx(tx, strHexTx)) {
                 throw std::runtime_error("invalid transaction encoding");
             }
 
             startArg = 2;
         } else {
             startArg = 1;
         }
 
         for (int i = startArg; i < argc; i++) {
             std::string arg = argv[i];
             std::string key, value;
             size_t eqpos = arg.find('=');
             if (eqpos == std::string::npos) {
                 key = arg;
             } else {
                 key = arg.substr(0, eqpos);
                 value = arg.substr(eqpos + 1);
             }
 
             MutateTx(tx, key, value);
         }
 
         OutputTx(tx);
     }
 
     catch (const boost::thread_interrupted &) {
         throw;
     } catch (const std::exception &e) {
         strPrint = std::string("error: ") + e.what();
         nRet = EXIT_FAILURE;
     } catch (...) {
         PrintExceptionContinue(nullptr, "CommandLineRawTx()");
         throw;
     }
 
     if (strPrint != "") {
         fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str());
     }
 
     return nRet;
 }
 
 int main(int argc, char *argv[]) {
     SetupEnvironment();
 
     try {
         int ret = AppInitRawTx(argc, argv);
         if (ret != CONTINUE_EXECUTION) return ret;
     } catch (const std::exception &e) {
         PrintExceptionContinue(&e, "AppInitRawTx()");
         return EXIT_FAILURE;
     } catch (...) {
         PrintExceptionContinue(nullptr, "AppInitRawTx()");
         return EXIT_FAILURE;
     }
 
     int ret = EXIT_FAILURE;
     try {
         ret = CommandLineRawTx(argc, argv);
     } catch (const std::exception &e) {
         PrintExceptionContinue(&e, "CommandLineRawTx()");
     } catch (...) {
         PrintExceptionContinue(nullptr, "CommandLineRawTx()");
     }
 
     return ret;
 }
diff --git a/src/blockencodings.cpp b/src/blockencodings.cpp
index c2a8b878d..866a1e8cf 100644
--- a/src/blockencodings.cpp
+++ b/src/blockencodings.cpp
@@ -1,245 +1,244 @@
 // Copyright (c) 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.
 
 #include "blockencodings.h"
 #include "chainparams.h"
 #include "config.h"
 #include "consensus/consensus.h"
 #include "consensus/validation.h"
 #include "hash.h"
 #include "random.h"
 #include "streams.h"
 #include "txmempool.h"
 #include "util.h"
 #include "validation.h"
 
 #include <unordered_map>
 
 CBlockHeaderAndShortTxIDs::CBlockHeaderAndShortTxIDs(const CBlock &block)
     : nonce(GetRand(std::numeric_limits<uint64_t>::max())),
       shorttxids(block.vtx.size() - 1), prefilledtxn(1), header(block) {
     FillShortTxIDSelector();
     // TODO: Use our mempool prior to block acceptance to predictively fill more
     // than just the coinbase.
     prefilledtxn[0] = {0, block.vtx[0]};
     for (size_t i = 1; i < block.vtx.size(); i++) {
         const CTransaction &tx = *block.vtx[i];
         shorttxids[i - 1] = GetShortID(tx.GetHash());
     }
 }
 
 void CBlockHeaderAndShortTxIDs::FillShortTxIDSelector() const {
     CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
     stream << header << nonce;
     CSHA256 hasher;
-    hasher.Write((unsigned char *)&(*stream.begin()),
-                 stream.end() - stream.begin());
+    hasher.Write((uint8_t *)&(*stream.begin()), stream.end() - stream.begin());
     uint256 shorttxidhash;
     hasher.Finalize(shorttxidhash.begin());
     shorttxidk0 = shorttxidhash.GetUint64(0);
     shorttxidk1 = shorttxidhash.GetUint64(1);
 }
 
 uint64_t CBlockHeaderAndShortTxIDs::GetShortID(const uint256 &txhash) const {
     static_assert(SHORTTXIDS_LENGTH == 6,
                   "shorttxids calculation assumes 6-byte shorttxids");
     return SipHashUint256(shorttxidk0, shorttxidk1, txhash) & 0xffffffffffffL;
 }
 
 ReadStatus PartiallyDownloadedBlock::InitData(
     const CBlockHeaderAndShortTxIDs &cmpctblock,
     const std::vector<std::pair<uint256, CTransactionRef>> &extra_txn) {
     if (cmpctblock.header.IsNull() ||
         (cmpctblock.shorttxids.empty() && cmpctblock.prefilledtxn.empty()))
         return READ_STATUS_INVALID;
     if (cmpctblock.shorttxids.size() + cmpctblock.prefilledtxn.size() >
         config->GetMaxBlockSize() / MIN_TRANSACTION_SIZE)
         return READ_STATUS_INVALID;
 
     assert(header.IsNull() && txn_available.empty());
     header = cmpctblock.header;
     txn_available.resize(cmpctblock.BlockTxCount());
 
     int32_t lastprefilledindex = -1;
     for (size_t i = 0; i < cmpctblock.prefilledtxn.size(); i++) {
         if (cmpctblock.prefilledtxn[i].tx->IsNull()) return READ_STATUS_INVALID;
 
         // index is a uint16_t, so can't overflow here.
         lastprefilledindex += cmpctblock.prefilledtxn[i].index + 1;
         if (lastprefilledindex > std::numeric_limits<uint16_t>::max())
             return READ_STATUS_INVALID;
         if ((uint32_t)lastprefilledindex > cmpctblock.shorttxids.size() + i) {
             // If we are inserting a tx at an index greater than our full list
             // of shorttxids plus the number of prefilled txn we've inserted,
             // then we have txn for which we have neither a prefilled txn or a
             // shorttxid!
             return READ_STATUS_INVALID;
         }
         txn_available[lastprefilledindex] = cmpctblock.prefilledtxn[i].tx;
     }
     prefilled_count = cmpctblock.prefilledtxn.size();
 
     // Calculate map of txids -> positions and check mempool to see what we have
     // (or don't). Because well-formed cmpctblock messages will have a
     // (relatively) uniform distribution of short IDs, any highly-uneven
     // distribution of elements can be safely treated as a READ_STATUS_FAILED.
     std::unordered_map<uint64_t, uint16_t> shorttxids(
         cmpctblock.shorttxids.size());
     uint16_t index_offset = 0;
     for (size_t i = 0; i < cmpctblock.shorttxids.size(); i++) {
         while (txn_available[i + index_offset])
             index_offset++;
         shorttxids[cmpctblock.shorttxids[i]] = i + index_offset;
         // To determine the chance that the number of entries in a bucket
         // exceeds N, we use the fact that the number of elements in a single
         // bucket is binomially distributed (with n = the number of shorttxids
         // S, and p = 1 / the number of buckets), that in the worst case the
         // number of buckets is equal to S (due to std::unordered_map having a
         // default load factor of 1.0), and that the chance for any bucket to
         // exceed N elements is at most buckets * (the chance that any given
         // bucket is above N elements). Thus: P(max_elements_per_bucket > N) <=
         // S * (1 - cdf(binomial(n=S,p=1/S), N)). If we assume blocks of up to
         // 16000, allowing 12 elements per bucket should only fail once per ~1
         // million block transfers (per peer and connection).
         if (shorttxids.bucket_size(
                 shorttxids.bucket(cmpctblock.shorttxids[i])) > 12)
             return READ_STATUS_FAILED;
     }
     // TODO: in the shortid-collision case, we should instead request both
     // transactions which collided. Falling back to full-block-request here is
     // overkill.
     if (shorttxids.size() != cmpctblock.shorttxids.size()) {
         // Short ID collision
         return READ_STATUS_FAILED;
     }
 
     std::vector<bool> have_txn(txn_available.size());
     {
         LOCK(pool->cs);
         const std::vector<std::pair<uint256, CTxMemPool::txiter>> &vTxHashes =
             pool->vTxHashes;
         for (size_t i = 0; i < vTxHashes.size(); i++) {
             uint64_t shortid = cmpctblock.GetShortID(vTxHashes[i].first);
             std::unordered_map<uint64_t, uint16_t>::iterator idit =
                 shorttxids.find(shortid);
             if (idit != shorttxids.end()) {
                 if (!have_txn[idit->second]) {
                     txn_available[idit->second] =
                         vTxHashes[i].second->GetSharedTx();
                     have_txn[idit->second] = true;
                     mempool_count++;
                 } else {
                     // If we find two mempool txn that match the short id, just
                     // request it. This should be rare enough that the extra
                     // bandwidth doesn't matter, but eating a round-trip due to
                     // FillBlock failure would be annoying.
                     if (txn_available[idit->second]) {
                         txn_available[idit->second].reset();
                         mempool_count--;
                     }
                 }
             }
             // Though ideally we'd continue scanning for the
             // two-txn-match-shortid case, the performance win of an early exit
             // here is too good to pass up and worth the extra risk.
             if (mempool_count == shorttxids.size()) break;
         }
     }
 
     for (size_t i = 0; i < extra_txn.size(); i++) {
         uint64_t shortid = cmpctblock.GetShortID(extra_txn[i].first);
         std::unordered_map<uint64_t, uint16_t>::iterator idit =
             shorttxids.find(shortid);
         if (idit != shorttxids.end()) {
             if (!have_txn[idit->second]) {
                 txn_available[idit->second] = extra_txn[i].second;
                 have_txn[idit->second] = true;
                 mempool_count++;
                 extra_count++;
             } else {
                 // If we find two mempool/extra txn that match the short id,
                 // just request it. This should be rare enough that the extra
                 // bandwidth doesn't matter, but eating a round-trip due to
                 // FillBlock failure would be annoying. Note that we dont want
                 // duplication between extra_txn and mempool to trigger this
                 // case, so we compare hashes first.
                 if (txn_available[idit->second] &&
                     txn_available[idit->second]->GetHash() !=
                         extra_txn[i].second->GetHash()) {
                     txn_available[idit->second].reset();
                     mempool_count--;
                     extra_count--;
                 }
             }
         }
 
         // Though ideally we'd continue scanning for the two-txn-match-shortid
         // case, the performance win of an early exit here is too good to pass
         // up and worth the extra risk.
         if (mempool_count == shorttxids.size()) break;
     }
 
     LogPrint("cmpctblock", "Initialized PartiallyDownloadedBlock for block %s "
                            "using a cmpctblock of size %lu\n",
              cmpctblock.header.GetHash().ToString(),
              GetSerializeSize(cmpctblock, SER_NETWORK, PROTOCOL_VERSION));
 
     return READ_STATUS_OK;
 }
 
 bool PartiallyDownloadedBlock::IsTxAvailable(size_t index) const {
     assert(!header.IsNull());
     assert(index < txn_available.size());
     return txn_available[index] ? true : false;
 }
 
 ReadStatus PartiallyDownloadedBlock::FillBlock(
     CBlock &block, const std::vector<CTransactionRef> &vtx_missing) {
     assert(!header.IsNull());
     uint256 hash = header.GetHash();
     block = header;
     block.vtx.resize(txn_available.size());
 
     size_t tx_missing_offset = 0;
     for (size_t i = 0; i < txn_available.size(); i++) {
         if (!txn_available[i]) {
             if (vtx_missing.size() <= tx_missing_offset)
                 return READ_STATUS_INVALID;
             block.vtx[i] = vtx_missing[tx_missing_offset++];
         } else
             block.vtx[i] = std::move(txn_available[i]);
     }
 
     // Make sure we can't call FillBlock again.
     header.SetNull();
     txn_available.clear();
 
     if (vtx_missing.size() != tx_missing_offset) return READ_STATUS_INVALID;
 
     CValidationState state;
     if (!CheckBlock(*config, block, state, Params().GetConsensus())) {
         // TODO: We really want to just check merkle tree manually here, but
         // that is expensive, and CheckBlock caches a block's "checked-status"
         // (in the CBlock?). CBlock should be able to check its own merkle root
         // and cache that check.
         if (state.CorruptionPossible()) {
             // Possible Short ID collision.
             return READ_STATUS_FAILED;
         }
         return READ_STATUS_CHECKBLOCK_FAILED;
     }
 
     LogPrint("cmpctblock", "Successfully reconstructed block %s with %lu txn "
                            "prefilled, %lu txn from mempool (incl at least %lu "
                            "from extra pool) and %lu txn requested\n",
              hash.ToString(), prefilled_count, mempool_count, extra_count,
              vtx_missing.size());
     if (vtx_missing.size() < 5) {
         for (const auto &tx : vtx_missing)
             LogPrint("cmpctblock", "Reconstructed block %s required tx %s\n",
                      hash.ToString(), tx->GetId().ToString());
     }
 
     return READ_STATUS_OK;
 }
diff --git a/src/bloom.cpp b/src/bloom.cpp
index 69a295fa6..2c648829e 100644
--- a/src/bloom.cpp
+++ b/src/bloom.cpp
@@ -1,299 +1,298 @@
 // Copyright (c) 2012-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.
 
 #include "bloom.h"
 
 #include "hash.h"
 #include "primitives/transaction.h"
 #include "random.h"
 #include "script/script.h"
 #include "script/standard.h"
 #include "streams.h"
 
 #include <cmath>
 #include <cstdlib>
 
 #define LN2SQUARED 0.4804530139182014246671025263266649717305529515945455
 #define LN2 0.6931471805599453094172321214581765680755001343602552
 
 /**
  * The ideal size for a bloom filter with a given number of elements and false
  * positive rate is:
  * - nElements * log(fp rate) / ln(2)^2
  * We ignore filter parameters which will create a bloom filter larger than the
  * protocol limits
  *
  * The ideal number of hash functions is filter size * ln(2) / number of
  * elements. Again, we ignore filter parameters which will create a bloom filter
  * with more hash functions than the protocol limits.
  * See https://en.wikipedia.org/wiki/Bloom_filter for an explanation of these
  * formulas.
  */
 CBloomFilter::CBloomFilter(unsigned int nElements, double nFPRate,
-                           unsigned int nTweakIn, unsigned char nFlagsIn)
+                           unsigned int nTweakIn, uint8_t nFlagsIn)
     : vData(std::min((unsigned int)(-1 / LN2SQUARED * nElements * log(nFPRate)),
                      MAX_BLOOM_FILTER_SIZE * 8) /
             8),
       isFull(false), isEmpty(true),
       nHashFuncs(std::min((unsigned int)(vData.size() * 8 / nElements * LN2),
                           MAX_HASH_FUNCS)),
       nTweak(nTweakIn), nFlags(nFlagsIn) {}
 
 // Private constructor used by CRollingBloomFilter
 CBloomFilter::CBloomFilter(unsigned int nElements, double nFPRate,
                            unsigned int nTweakIn)
     : vData((unsigned int)(-1 / LN2SQUARED * nElements * log(nFPRate)) / 8),
       isFull(false), isEmpty(true),
       nHashFuncs((unsigned int)(vData.size() * 8 / nElements * LN2)),
       nTweak(nTweakIn), nFlags(BLOOM_UPDATE_NONE) {}
 
 inline unsigned int
 CBloomFilter::Hash(unsigned int nHashNum,
-                   const std::vector<unsigned char> &vDataToHash) const {
+                   const std::vector<uint8_t> &vDataToHash) const {
     // 0xFBA4C795 chosen as it guarantees a reasonable bit difference between
     // nHashNum values.
     return MurmurHash3(nHashNum * 0xFBA4C795 + nTweak, vDataToHash) %
            (vData.size() * 8);
 }
 
-void CBloomFilter::insert(const std::vector<unsigned char> &vKey) {
+void CBloomFilter::insert(const std::vector<uint8_t> &vKey) {
     if (isFull) return;
     for (unsigned int i = 0; i < nHashFuncs; i++) {
         unsigned int nIndex = Hash(i, vKey);
         // Sets bit nIndex of vData
         vData[nIndex >> 3] |= (1 << (7 & nIndex));
     }
     isEmpty = false;
 }
 
 void CBloomFilter::insert(const COutPoint &outpoint) {
     CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
     stream << outpoint;
-    std::vector<unsigned char> data(stream.begin(), stream.end());
+    std::vector<uint8_t> data(stream.begin(), stream.end());
     insert(data);
 }
 
 void CBloomFilter::insert(const uint256 &hash) {
-    std::vector<unsigned char> data(hash.begin(), hash.end());
+    std::vector<uint8_t> data(hash.begin(), hash.end());
     insert(data);
 }
 
-bool CBloomFilter::contains(const std::vector<unsigned char> &vKey) const {
+bool CBloomFilter::contains(const std::vector<uint8_t> &vKey) const {
     if (isFull) return true;
     if (isEmpty) return false;
     for (unsigned int i = 0; i < nHashFuncs; i++) {
         unsigned int nIndex = Hash(i, vKey);
         // Checks bit nIndex of vData
         if (!(vData[nIndex >> 3] & (1 << (7 & nIndex)))) return false;
     }
     return true;
 }
 
 bool CBloomFilter::contains(const COutPoint &outpoint) const {
     CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
     stream << outpoint;
-    std::vector<unsigned char> data(stream.begin(), stream.end());
+    std::vector<uint8_t> data(stream.begin(), stream.end());
     return contains(data);
 }
 
 bool CBloomFilter::contains(const uint256 &hash) const {
-    std::vector<unsigned char> data(hash.begin(), hash.end());
+    std::vector<uint8_t> data(hash.begin(), hash.end());
     return contains(data);
 }
 
 void CBloomFilter::clear() {
     vData.assign(vData.size(), 0);
     isFull = false;
     isEmpty = true;
 }
 
 void CBloomFilter::reset(unsigned int nNewTweak) {
     clear();
     nTweak = nNewTweak;
 }
 
 bool CBloomFilter::IsWithinSizeConstraints() const {
     return vData.size() <= MAX_BLOOM_FILTER_SIZE &&
            nHashFuncs <= MAX_HASH_FUNCS;
 }
 
 bool CBloomFilter::IsRelevantAndUpdate(const CTransaction &tx) {
     bool fFound = false;
     // Match if the filter contains the hash of tx for finding tx when they
     // appear in a block
     if (isFull) return true;
     if (isEmpty) return false;
     const uint256 &txid = tx.GetId();
     if (contains(txid)) fFound = true;
 
     for (unsigned int i = 0; i < tx.vout.size(); i++) {
         const CTxOut &txout = tx.vout[i];
         // Match if the filter contains any arbitrary script data element in any
         // scriptPubKey in tx. If this matches, also add the specific output
         // that was matched. This means clients don't have to update the filter
         // themselves when a new relevant tx is discovered in order to find
         // spending transactions, which avoids round-tripping and race
         // conditions.
         CScript::const_iterator pc = txout.scriptPubKey.begin();
-        std::vector<unsigned char> data;
+        std::vector<uint8_t> data;
         while (pc < txout.scriptPubKey.end()) {
             opcodetype opcode;
             if (!txout.scriptPubKey.GetOp(pc, opcode, data)) break;
             if (data.size() != 0 && contains(data)) {
                 fFound = true;
                 if ((nFlags & BLOOM_UPDATE_MASK) == BLOOM_UPDATE_ALL)
                     insert(COutPoint(txid, i));
                 else if ((nFlags & BLOOM_UPDATE_MASK) ==
                          BLOOM_UPDATE_P2PUBKEY_ONLY) {
                     txnouttype type;
-                    std::vector<std::vector<unsigned char>> vSolutions;
+                    std::vector<std::vector<uint8_t>> vSolutions;
                     if (Solver(txout.scriptPubKey, type, vSolutions) &&
                         (type == TX_PUBKEY || type == TX_MULTISIG))
                         insert(COutPoint(txid, i));
                 }
                 break;
             }
         }
     }
 
     if (fFound) return true;
 
     for (const CTxIn &txin : tx.vin) {
         // Match if the filter contains an outpoint tx spends
         if (contains(txin.prevout)) return true;
 
         // Match if the filter contains any arbitrary script data element in any
         // scriptSig in tx
         CScript::const_iterator pc = txin.scriptSig.begin();
-        std::vector<unsigned char> data;
+        std::vector<uint8_t> data;
         while (pc < txin.scriptSig.end()) {
             opcodetype opcode;
             if (!txin.scriptSig.GetOp(pc, opcode, data)) break;
             if (data.size() != 0 && contains(data)) return true;
         }
     }
 
     return false;
 }
 
 void CBloomFilter::UpdateEmptyFull() {
     bool full = true;
     bool empty = true;
     for (unsigned int i = 0; i < vData.size(); i++) {
         full &= vData[i] == 0xff;
         empty &= vData[i] == 0;
     }
     isFull = full;
     isEmpty = empty;
 }
 
 CRollingBloomFilter::CRollingBloomFilter(unsigned int nElements,
                                          double fpRate) {
     double logFpRate = log(fpRate);
     /* The optimal number of hash functions is log(fpRate) / log(0.5), but
      * restrict it to the range 1-50. */
     nHashFuncs = std::max(1, std::min((int)round(logFpRate / log(0.5)), 50));
     /* In this rolling bloom filter, we'll store between 2 and 3 generations of
      * nElements / 2 entries. */
     nEntriesPerGeneration = (nElements + 1) / 2;
     uint32_t nMaxElements = nEntriesPerGeneration * 3;
     /* The maximum fpRate = pow(1.0 - exp(-nHashFuncs * nMaxElements /
      * nFilterBits), nHashFuncs)
      * =>          pow(fpRate, 1.0 / nHashFuncs) = 1.0 - exp(-nHashFuncs *
      * nMaxElements / nFilterBits)
      * =>          1.0 - pow(fpRate, 1.0 / nHashFuncs) = exp(-nHashFuncs *
      * nMaxElements / nFilterBits)
      * =>          log(1.0 - pow(fpRate, 1.0 / nHashFuncs)) = -nHashFuncs *
      * nMaxElements / nFilterBits
      * =>          nFilterBits = -nHashFuncs * nMaxElements / log(1.0 -
      * pow(fpRate, 1.0 / nHashFuncs))
      * =>          nFilterBits = -nHashFuncs * nMaxElements / log(1.0 -
      * exp(logFpRate / nHashFuncs))
      */
     uint32_t nFilterBits =
         (uint32_t)ceil(-1.0 * nHashFuncs * nMaxElements /
                        log(1.0 - exp(logFpRate / nHashFuncs)));
     data.clear();
     /* For each data element we need to store 2 bits. If both bits are 0, the
      * bit is treated as unset. If the bits are (01), (10), or (11), the bit is
      * treated as set in generation 1, 2, or 3 respectively. These bits are
      * stored in separate integers: position P corresponds to bit (P & 63) of
      * the integers data[(P >> 6) * 2] and data[(P >> 6) * 2 + 1]. */
     data.resize(((nFilterBits + 63) / 64) << 1);
     reset();
 }
 
 /* Similar to CBloomFilter::Hash */
 static inline uint32_t
 RollingBloomHash(unsigned int nHashNum, uint32_t nTweak,
-                 const std::vector<unsigned char> &vDataToHash) {
+                 const std::vector<uint8_t> &vDataToHash) {
     return MurmurHash3(nHashNum * 0xFBA4C795 + nTweak, vDataToHash);
 }
 
-void CRollingBloomFilter::insert(const std::vector<unsigned char> &vKey) {
+void CRollingBloomFilter::insert(const std::vector<uint8_t> &vKey) {
     if (nEntriesThisGeneration == nEntriesPerGeneration) {
         nEntriesThisGeneration = 0;
         nGeneration++;
         if (nGeneration == 4) {
             nGeneration = 1;
         }
         uint64_t nGenerationMask1 = -(uint64_t)(nGeneration & 1);
         uint64_t nGenerationMask2 = -(uint64_t)(nGeneration >> 1);
         /* Wipe old entries that used this generation number. */
         for (uint32_t p = 0; p < data.size(); p += 2) {
             uint64_t p1 = data[p], p2 = data[p + 1];
             uint64_t mask = (p1 ^ nGenerationMask1) | (p2 ^ nGenerationMask2);
             data[p] = p1 & mask;
             data[p + 1] = p2 & mask;
         }
     }
     nEntriesThisGeneration++;
 
     for (int n = 0; n < nHashFuncs; n++) {
         uint32_t h = RollingBloomHash(n, nTweak, vKey);
         int bit = h & 0x3F;
         uint32_t pos = (h >> 6) % data.size();
         /* The lowest bit of pos is ignored, and set to zero for the first bit,
          * and to one for the second. */
         data[pos & ~1] = (data[pos & ~1] & ~(((uint64_t)1) << bit)) |
                          ((uint64_t)(nGeneration & 1)) << bit;
         data[pos | 1] = (data[pos | 1] & ~(((uint64_t)1) << bit)) |
                         ((uint64_t)(nGeneration >> 1)) << bit;
     }
 }
 
 void CRollingBloomFilter::insert(const uint256 &hash) {
-    std::vector<unsigned char> vData(hash.begin(), hash.end());
+    std::vector<uint8_t> vData(hash.begin(), hash.end());
     insert(vData);
 }
 
-bool CRollingBloomFilter::contains(
-    const std::vector<unsigned char> &vKey) const {
+bool CRollingBloomFilter::contains(const std::vector<uint8_t> &vKey) const {
     for (int n = 0; n < nHashFuncs; n++) {
         uint32_t h = RollingBloomHash(n, nTweak, vKey);
         int bit = h & 0x3F;
         uint32_t pos = (h >> 6) % data.size();
         /* If the relevant bit is not set in either data[pos & ~1] or data[pos |
          * 1], the filter does not contain vKey */
         if (!(((data[pos & ~1] | data[pos | 1]) >> bit) & 1)) {
             return false;
         }
     }
     return true;
 }
 
 bool CRollingBloomFilter::contains(const uint256 &hash) const {
-    std::vector<unsigned char> vData(hash.begin(), hash.end());
+    std::vector<uint8_t> vData(hash.begin(), hash.end());
     return contains(vData);
 }
 
 void CRollingBloomFilter::reset() {
     nTweak = GetRand(std::numeric_limits<unsigned int>::max());
     nEntriesThisGeneration = 0;
     nGeneration = 1;
     for (std::vector<uint64_t>::iterator it = data.begin(); it != data.end();
          it++) {
         *it = 0;
     }
 }
diff --git a/src/bloom.h b/src/bloom.h
index 5dd497e27..a488696df 100644
--- a/src/bloom.h
+++ b/src/bloom.h
@@ -1,148 +1,148 @@
 // Copyright (c) 2012-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.
 
 #ifndef BITCOIN_BLOOM_H
 #define BITCOIN_BLOOM_H
 
 #include "serialize.h"
 
 #include <vector>
 
 class COutPoint;
 class CTransaction;
 class uint256;
 
 //! 20,000 items with fp rate < 0.1% or 10,000 items and <0.0001%
 static const unsigned int MAX_BLOOM_FILTER_SIZE = 36000; // bytes
 static const unsigned int MAX_HASH_FUNCS = 50;
 
 /**
  * First two bits of nFlags control how much IsRelevantAndUpdate actually
  * updates. The remaining bits are reserved.
  */
 enum bloomflags {
     BLOOM_UPDATE_NONE = 0,
     BLOOM_UPDATE_ALL = 1,
     // Only adds outpoints to the filter if the output is a
     // pay-to-pubkey/pay-to-multisig script
     BLOOM_UPDATE_P2PUBKEY_ONLY = 2,
     BLOOM_UPDATE_MASK = 3,
 };
 
 /**
  * BloomFilter is a probabilistic filter which SPV clients provide so that we
  * can filter the transactions we send them.
  *
  * This allows for significantly more efficient transaction and block downloads.
  *
  * Because bloom filters are probabilistic, a SPV node can increase the
  * false-positive rate, making us send it transactions which aren't actually
  * its, allowing clients to trade more bandwidth for more privacy by obfuscating
  * which keys are controlled by them.
  */
 class CBloomFilter {
 private:
-    std::vector<unsigned char> vData;
+    std::vector<uint8_t> vData;
     bool isFull;
     bool isEmpty;
     unsigned int nHashFuncs;
     unsigned int nTweak;
-    unsigned char nFlags;
+    uint8_t nFlags;
 
     unsigned int Hash(unsigned int nHashNum,
-                      const std::vector<unsigned char> &vDataToHash) const;
+                      const std::vector<uint8_t> &vDataToHash) const;
 
     // Private constructor for CRollingBloomFilter, no restrictions on size
     CBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweak);
     friend class CRollingBloomFilter;
 
 public:
     /**
      * Creates a new bloom filter which will provide the given fp rate when
      * filled with the given number of elements. Note that if the given
      * parameters will result in a filter outside the bounds of the protocol
      * limits, the filter created will be as close to the given parameters as
      * possible within the protocol limits. This will apply if nFPRate is very
      * low or nElements is unreasonably high. nTweak is a constant which is
      * added to the seed value passed to the hash function. It should generally
      * always be a random value (and is largely only exposed for unit testing)
      * nFlags should be one of the BLOOM_UPDATE_* enums (not _MASK)
      */
     CBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweak,
-                 unsigned char nFlagsIn);
+                 uint8_t nFlagsIn);
     CBloomFilter()
         : isFull(true), isEmpty(false), nHashFuncs(0), nTweak(0), nFlags(0) {}
 
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
     inline void SerializationOp(Stream &s, Operation ser_action) {
         READWRITE(vData);
         READWRITE(nHashFuncs);
         READWRITE(nTweak);
         READWRITE(nFlags);
     }
 
-    void insert(const std::vector<unsigned char> &vKey);
+    void insert(const std::vector<uint8_t> &vKey);
     void insert(const COutPoint &outpoint);
     void insert(const uint256 &hash);
 
-    bool contains(const std::vector<unsigned char> &vKey) const;
+    bool contains(const std::vector<uint8_t> &vKey) const;
     bool contains(const COutPoint &outpoint) const;
     bool contains(const uint256 &hash) const;
 
     void clear();
     void reset(unsigned int nNewTweak);
 
     //! True if the size is <= MAX_BLOOM_FILTER_SIZE and the number of hash
     //! functions is <= MAX_HASH_FUNCS (catch a filter which was just
     //! deserialized which was too big)
     bool IsWithinSizeConstraints() const;
 
     //! Also adds any outputs which match the filter to the filter (to match
     //! their spending txes)
     bool IsRelevantAndUpdate(const CTransaction &tx);
 
     //! Checks for empty and full filters to avoid wasting cpu
     void UpdateEmptyFull();
 };
 
 /**
  * RollingBloomFilter is a probabilistic "keep track of most recently inserted"
  * set. Construct it with the number of items to keep track of, and a
  * false-positive rate. Unlike CBloomFilter, by default nTweak is set to a
  * cryptographically secure random value for you. Similarly rather than clear()
  * the method reset() is provided, which also changes nTweak to decrease the
  * impact of false-positives.
  *
  * contains(item) will always return true if item was one of the last N to 1.5*N
  * insert()'ed ... but may also return true for items that were not inserted.
  *
  * It needs around 1.8 bytes per element per factor 0.1 of false positive rate.
  * (More accurately: 3/(log(256)*log(2)) * log(1/fpRate) * nElements bytes)
  */
 class CRollingBloomFilter {
 public:
     // A random bloom filter calls GetRand() at creation time. Don't create
     // global CRollingBloomFilter objects, as they may be constructed before the
     // randomizer is properly initialized.
     CRollingBloomFilter(unsigned int nElements, double nFPRate);
 
-    void insert(const std::vector<unsigned char> &vKey);
+    void insert(const std::vector<uint8_t> &vKey);
     void insert(const uint256 &hash);
-    bool contains(const std::vector<unsigned char> &vKey) const;
+    bool contains(const std::vector<uint8_t> &vKey) const;
     bool contains(const uint256 &hash) const;
 
     void reset();
 
 private:
     int nEntriesPerGeneration;
     int nEntriesThisGeneration;
     int nGeneration;
     std::vector<uint64_t> data;
     unsigned int nTweak;
     int nHashFuncs;
 };
 
 #endif // BITCOIN_BLOOM_H
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index 7fcaf9d71..f2551d79a 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -1,515 +1,514 @@
 // Copyright (c) 2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #include "chainparams.h"
 #include "consensus/merkle.h"
 
 #include "tinyformat.h"
 #include "util.h"
 #include "utilstrencodings.h"
 
 #include <cassert>
 
 #include <boost/assign/list_of.hpp>
 
 #include "chainparamsseeds.h"
 
 // Far into the future.
 static const std::string ANTI_REPLAY_COMMITMENT =
     "Bitcoin: A Peer-to-Peer Electronic Cash System";
 
-static std::vector<unsigned char> GetAntiReplayCommitment() {
-    return std::vector<unsigned char>(std::begin(ANTI_REPLAY_COMMITMENT),
-                                      std::end(ANTI_REPLAY_COMMITMENT));
+static std::vector<uint8_t> GetAntiReplayCommitment() {
+    return std::vector<uint8_t>(std::begin(ANTI_REPLAY_COMMITMENT),
+                                std::end(ANTI_REPLAY_COMMITMENT));
 }
 
 static CBlock CreateGenesisBlock(const char *pszTimestamp,
                                  const CScript &genesisOutputScript,
                                  uint32_t nTime, uint32_t nNonce,
                                  uint32_t nBits, int32_t nVersion,
                                  const CAmount &genesisReward) {
     CMutableTransaction txNew;
     txNew.nVersion = 1;
     txNew.vin.resize(1);
     txNew.vout.resize(1);
-    txNew.vin[0].scriptSig = CScript()
-                             << 486604799 << CScriptNum(4)
-                             << std::vector<unsigned char>(
-                                    (const unsigned char *)pszTimestamp,
-                                    (const unsigned char *)pszTimestamp +
-                                        strlen(pszTimestamp));
+    txNew.vin[0].scriptSig =
+        CScript() << 486604799 << CScriptNum(4)
+                  << std::vector<uint8_t>((const uint8_t *)pszTimestamp,
+                                          (const uint8_t *)pszTimestamp +
+                                              strlen(pszTimestamp));
     txNew.vout[0].nValue = genesisReward;
     txNew.vout[0].scriptPubKey = genesisOutputScript;
 
     CBlock genesis;
     genesis.nTime = nTime;
     genesis.nBits = nBits;
     genesis.nNonce = nNonce;
     genesis.nVersion = nVersion;
     genesis.vtx.push_back(MakeTransactionRef(std::move(txNew)));
     genesis.hashPrevBlock.SetNull();
     genesis.hashMerkleRoot = BlockMerkleRoot(genesis);
     return genesis;
 }
 
 /**
  * Build the genesis block. Note that the output of its generation transaction
  * cannot be spent since it did not originally exist in the database.
  *
  * CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000,
  * hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893,
  * vtx=1)
  *   CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0)
  *     CTxIn(COutPoint(000000, -1), coinbase
  * 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73)
  *     CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B)
  *   vMerkleTree: 4a5e1e
  */
 static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce,
                                  uint32_t nBits, int32_t nVersion,
                                  const CAmount &genesisReward) {
     const char *pszTimestamp =
         "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";
     const CScript genesisOutputScript =
         CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909"
                               "a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112"
                               "de5c384df7ba0b8d578a4c702b6bf11d5f")
                   << OP_CHECKSIG;
     return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce,
                               nBits, nVersion, genesisReward);
 }
 
 /**
  * Main network
  */
 /**
  * What makes a good checkpoint block?
  * + Is surrounded by blocks with reasonable timestamps
  *   (no blocks before with a timestamp after, none after with
  *    timestamp before)
  * + Contains no strange transactions
  */
 class CMainParams : public CChainParams {
 public:
     CMainParams() {
         strNetworkID = "main";
         consensus.nSubsidyHalvingInterval = 210000;
         consensus.BIP34Height = 227931;
         consensus.BIP34Hash = uint256S("0x000000000000024b89b42a942fe0d9fea3bb4"
                                        "4ab7bd1b19115dd6a759c0808b8");
         // 000000000000000004c2b624ed5d7756c508d90fd0da2c7c679febfa6c4735f0
         consensus.BIP65Height = 388381;
         // 00000000000000000379eaa19dce8c9b722d46ae6a57c2f1a988119488b50931
         consensus.BIP66Height = 363725;
         consensus.antiReplayOpReturnSunsetHeight = 530000;
         consensus.antiReplayOpReturnCommitment = GetAntiReplayCommitment();
         consensus.powLimit = uint256S(
             "00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
         // two weeks
         consensus.nPowTargetTimespan = 14 * 24 * 60 * 60;
         consensus.nPowTargetSpacing = 10 * 60;
         consensus.fPowAllowMinDifficultyBlocks = false;
         consensus.fPowNoRetargeting = false;
         // 95% of 2016
         consensus.nRuleChangeActivationThreshold = 1916;
         // nPowTargetTimespan / nPowTargetSpacing
         consensus.nMinerConfirmationWindow = 2016;
         consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
         // January 1, 2008
         consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime =
             1199145601;
         // December 31, 2008
         consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout =
             1230767999;
 
         // Deployment of BIP68, BIP112, and BIP113.
         consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
         // May 1st, 2016
         consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime =
             1462060800;
         // May 1st, 2017
         consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1493596800;
 
         // The best chain should have at least this much work.
         consensus.nMinimumChainWork =
             uint256S("0x0000000000000000000000000000000000000000003f94d1ad39168"
                      "2fe038bf5");
 
         // By default assume that the signatures in ancestors of this block are
         // valid.
         consensus.defaultAssumeValid =
             uint256S("0x000000000000000000651ef99cb9fcbe0dadde1d424bd9f15ff2013"
                      "6191a5eec");
 
         /**
          * The message start string is designed to be unlikely to occur in
          * normal data. The characters are rarely used upper ASCII, not valid as
          * UTF-8, and produce a large 32-bit integer with any alignment.
          */
         pchMessageStart[0] = 0xf9;
         pchMessageStart[1] = 0xbe;
         pchMessageStart[2] = 0xb4;
         pchMessageStart[3] = 0xd9;
         pchCashMessageStart[0] = 0xe3;
         pchCashMessageStart[1] = 0xe1;
         pchCashMessageStart[2] = 0xf3;
         pchCashMessageStart[3] = 0xe8;
         nDefaultPort = 8333;
         nPruneAfterHeight = 100000;
 
         genesis = CreateGenesisBlock(1231006505, 2083236893, 0x1d00ffff, 1,
                                      50 * COIN);
         consensus.hashGenesisBlock = genesis.GetHash();
         assert(consensus.hashGenesisBlock ==
                uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3"
                         "f1b60a8ce26f"));
         assert(genesis.hashMerkleRoot ==
                uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab212"
                         "7b7afdeda33b"));
 
         // Note that of those with the service bits flag, most only support a
         // subset of possible options.
         // Bitcoin ABC seeder
         vSeeds.push_back(
             CDNSSeedData("bitcoinabc.org", "seed.bitcoinabc.org", true));
         // bitcoinforks seeders
         vSeeds.push_back(CDNSSeedData("bitcoinforks.org",
                                       "seed-abc.bitcoinforks.org", true));
         // BU backed seeder
         vSeeds.push_back(CDNSSeedData("bitcoinunlimited.info",
                                       "btccash-seeder.bitcoinunlimited.info",
                                       true));
         // Bitprim
         vSeeds.push_back(CDNSSeedData("bitprim.org", "seed.bitprim.org", true));
         // Amaury SÉCHET
         vSeeds.push_back(
             CDNSSeedData("deadalnix.me", "seed.deadalnix.me", true));
         // criptolayer.net
         vSeeds.push_back(
             CDNSSeedData("criptolayer.net", "seeder.criptolayer.net", true));
 
-        base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1, 0);
-        base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1, 5);
-        base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1, 128);
+        base58Prefixes[PUBKEY_ADDRESS] = std::vector<uint8_t>(1, 0);
+        base58Prefixes[SCRIPT_ADDRESS] = std::vector<uint8_t>(1, 5);
+        base58Prefixes[SECRET_KEY] = std::vector<uint8_t>(1, 128);
         base58Prefixes[EXT_PUBLIC_KEY] =
             boost::assign::list_of(0x04)(0x88)(0xB2)(0x1E)
-                .convert_to_container<std::vector<unsigned char>>();
+                .convert_to_container<std::vector<uint8_t>>();
         base58Prefixes[EXT_SECRET_KEY] =
             boost::assign::list_of(0x04)(0x88)(0xAD)(0xE4)
-                .convert_to_container<std::vector<unsigned char>>();
+                .convert_to_container<std::vector<uint8_t>>();
 
         vFixedSeeds = std::vector<SeedSpec6>(
             pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main));
 
         fMiningRequiresPeers = true;
         fDefaultConsistencyChecks = false;
         fRequireStandard = true;
         fMineBlocksOnDemand = false;
 
         checkpointData = (CCheckpointData){boost::assign::map_list_of(
             11111, uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee925"
                             "59f542fdb26e7c1d"))(
             33333, uint256S("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce"
                             "69f00d7ddfb5d0a6"))(
             74000, uint256S("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a"
                             "81e7f953b8661a20"))(
             105000, uint256S("0x00000000000291ce28027faea320c8d2b054b2e0fe44a77"
                              "3f3eefb151d6bdc97"))(
             134444, uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814"
                              "c91184a0d42d2b0fe"))(
             168000, uint256S("0x000000000000099e61ea72015e79632f216fe6cb33d7899"
                              "acb35b75c8303b763"))(
             193000, uint256S("0x000000000000059f452a5f7340de6682a977387c17010ff"
                              "6e6c3bd83ca8b1317"))(
             210000, uint256S("0x000000000000048b95347e83192f69cf0366076336c639f"
                              "9b7228e9ba171342e"))(
             216116, uint256S("0x00000000000001b4f4b433e81ee46494af945cf96014816"
                              "a4e2370f11b23df4e"))(
             225430, uint256S("0x00000000000001c108384350f74090433e7fcf79a606b8e"
                              "797f065b130575932"))(
             250000, uint256S("0x000000000000003887df1f29024b06fc2200b55f8af8f35"
                              "453d7be294df2d214"))(
             279000, uint256S("0x0000000000000001ae8c72a0b0c301f67e3afca10e819ef"
                              "a9041e458e9bd7e40"))(
             295000, uint256S("0x00000000000000004d9b4ef50f0f9d686fd69db2e03af35"
                              "a100370c64632a983"))(
             478641, uint256S("0x0000000000000000027c1fea6fe49acb16d46c82dd2f2a8"
                              "0b22ecc9cdb3ababe"))};
 
         // Data as of block
         // 00000000000000000166d612d5595e2b1cd88d71d695fc580af64d8da8658c23
         // (height 446482).
         chainTxData = ChainTxData{
             // UNIX timestamp of last known number of transactions.
             1483472411,
             // Total number of transactions between genesis and that timestamp
             // (the tx=... number in the SetBestChain debug.log lines)
             184495391,
             // Estimated number of transactions per second after that timestamp.
             3.2};
     }
 };
 static CMainParams mainParams;
 
 /**
  * Testnet (v3)
  */
 class CTestNetParams : public CChainParams {
 public:
     CTestNetParams() {
         strNetworkID = "test";
         consensus.nSubsidyHalvingInterval = 210000;
         consensus.BIP34Height = 21111;
         consensus.BIP34Hash = uint256S("0x0000000023b3a96d3484e5abb3755c413e7d4"
                                        "1500f8e2a5c3f0dd01299cd8ef8");
         // 00000000007f6655f22f98e72ed80d8b06dc761d5da09df0fa1dc4be4f861eb6
         consensus.BIP65Height = 581885;
         // 000000002104c8c45e99a8853285a3b592602a3ccde2b832481da85e9e4ba182
         consensus.BIP66Height = 330776;
         consensus.antiReplayOpReturnSunsetHeight = 1250000;
         consensus.antiReplayOpReturnCommitment = GetAntiReplayCommitment();
         consensus.powLimit = uint256S(
             "00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
         // two weeks
         consensus.nPowTargetTimespan = 14 * 24 * 60 * 60;
         consensus.nPowTargetSpacing = 10 * 60;
         consensus.fPowAllowMinDifficultyBlocks = true;
         consensus.fPowNoRetargeting = false;
         // 75% for testchains
         consensus.nRuleChangeActivationThreshold = 1512;
         // nPowTargetTimespan / nPowTargetSpacing
         consensus.nMinerConfirmationWindow = 2016;
         consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
         // January 1, 2008
         consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime =
             1199145601;
         // December 31, 2008
         consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout =
             1230767999;
 
         // Deployment of BIP68, BIP112, and BIP113.
         consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
         // March 1st, 2016
         consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime =
             1456790400;
         // May 1st, 2017
         consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1493596800;
 
         // The best chain should have at least this much work.
         consensus.nMinimumChainWork =
             uint256S("0x00000000000000000000000000000000000000000000001f057509e"
                      "ba81aed91");
 
         // By default assume that the signatures in ancestors of this block are
         // valid.
         consensus.defaultAssumeValid =
             uint256S("0x00000000f17c850672894b9a75b63a1e72830bbd5f4c8889b5c1a80"
                      "e7faef138");
 
         pchMessageStart[0] = 0x0b;
         pchMessageStart[1] = 0x11;
         pchMessageStart[2] = 0x09;
         pchMessageStart[3] = 0x07;
         pchCashMessageStart[0] = 0xf4;
         pchCashMessageStart[1] = 0xe5;
         pchCashMessageStart[2] = 0xf3;
         pchCashMessageStart[3] = 0xf4;
         nDefaultPort = 18333;
         nPruneAfterHeight = 1000;
 
         genesis =
             CreateGenesisBlock(1296688602, 414098458, 0x1d00ffff, 1, 50 * COIN);
         consensus.hashGenesisBlock = genesis.GetHash();
         assert(consensus.hashGenesisBlock ==
                uint256S("0x000000000933ea01ad0ee984209779baaec3ced90fa3f4087195"
                         "26f8d77f4943"));
         assert(genesis.hashMerkleRoot ==
                uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab212"
                         "7b7afdeda33b"));
 
         vFixedSeeds.clear();
         vSeeds.clear();
         // nodes with support for servicebits filtering should be at the top
         // Bitcoin ABC seeder
         vSeeds.push_back(CDNSSeedData("bitcoinabc.org",
                                       "testnet-seed.bitcoinabc.org", true));
         // bitcoinforks seeders
         vSeeds.push_back(CDNSSeedData(
             "bitcoinforks.org", "testnet-seed-abc.bitcoinforks.org", true));
         // BU seeder
         vSeeds.push_back(CDNSSeedData("bitcoinunlimited.info",
                                       "testnet-seed.bitcoinunlimited.info",
                                       true));
         // Bitprim
         vSeeds.push_back(
             CDNSSeedData("bitprim.org", "testnet-seed.bitprim.org", true));
         // Amaury SÉCHET
         vSeeds.push_back(
             CDNSSeedData("deadalnix.me", "testnet-seed.deadalnix.me", true));
         // criptolayer.net
         vSeeds.push_back(CDNSSeedData("criptolayer.net",
                                       "testnet-seeder.criptolayer.net", true));
 
-        base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1, 111);
-        base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1, 196);
-        base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1, 239);
+        base58Prefixes[PUBKEY_ADDRESS] = std::vector<uint8_t>(1, 111);
+        base58Prefixes[SCRIPT_ADDRESS] = std::vector<uint8_t>(1, 196);
+        base58Prefixes[SECRET_KEY] = std::vector<uint8_t>(1, 239);
         base58Prefixes[EXT_PUBLIC_KEY] =
             boost::assign::list_of(0x04)(0x35)(0x87)(0xCF)
-                .convert_to_container<std::vector<unsigned char>>();
+                .convert_to_container<std::vector<uint8_t>>();
         base58Prefixes[EXT_SECRET_KEY] =
             boost::assign::list_of(0x04)(0x35)(0x83)(0x94)
-                .convert_to_container<std::vector<unsigned char>>();
+                .convert_to_container<std::vector<uint8_t>>();
 
         vFixedSeeds = std::vector<SeedSpec6>(
             pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test));
 
         fMiningRequiresPeers = true;
         fDefaultConsistencyChecks = false;
         fRequireStandard = false;
         fMineBlocksOnDemand = false;
 
         checkpointData = (CCheckpointData){
             boost::assign::map_list_of(
                 546, uint256S("000000002a936ca763904c3c35fce2f3556c559c0214345d"
                               "31b1bcebf76acb70")),
         };
 
         // Data as of block
         // 00000000c2872f8f8a8935c8e3c5862be9038c97d4de2cf37ed496991166928a
         // (height 1063660)
         chainTxData = ChainTxData{1483546230, 12834668, 0.15};
     }
 };
 static CTestNetParams testNetParams;
 
 /**
  * Regression test
  */
 class CRegTestParams : public CChainParams {
 public:
     CRegTestParams() {
         strNetworkID = "regtest";
         consensus.nSubsidyHalvingInterval = 150;
         // BIP34 has not activated on regtest (far in the future so block v1 are
         // not rejected in tests)
         consensus.BIP34Height = 100000000;
         consensus.BIP34Hash = uint256();
         // BIP65 activated on regtest (Used in rpc activation tests)
         consensus.BIP65Height = 1351;
         // BIP66 activated on regtest (Used in rpc activation tests)
         consensus.BIP66Height = 1251;
         consensus.antiReplayOpReturnSunsetHeight = 530000;
         consensus.antiReplayOpReturnCommitment = GetAntiReplayCommitment();
         consensus.powLimit = uint256S(
             "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
         // two weeks
         consensus.nPowTargetTimespan = 14 * 24 * 60 * 60;
         consensus.nPowTargetSpacing = 10 * 60;
         consensus.fPowAllowMinDifficultyBlocks = true;
         consensus.fPowNoRetargeting = true;
         // 75% for testchains
         consensus.nRuleChangeActivationThreshold = 108;
         // Faster than normal for regtest (144 instead of 2016)
         consensus.nMinerConfirmationWindow = 144;
         consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
         consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 0;
         consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout =
             999999999999ULL;
         consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
         consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 0;
         consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout =
             999999999999ULL;
 
         // The best chain should have at least this much work.
         consensus.nMinimumChainWork = uint256S("0x00");
 
         // By default assume that the signatures in ancestors of this block are
         // valid.
         consensus.defaultAssumeValid = uint256S("0x00");
 
         pchMessageStart[0] = 0xfa;
         pchMessageStart[1] = 0xbf;
         pchMessageStart[2] = 0xb5;
         pchMessageStart[3] = 0xda;
         pchCashMessageStart[0] = 0xda;
         pchCashMessageStart[1] = 0xb5;
         pchCashMessageStart[2] = 0xbf;
         pchCashMessageStart[3] = 0xfa;
         nDefaultPort = 18444;
         nPruneAfterHeight = 1000;
 
         genesis = CreateGenesisBlock(1296688602, 2, 0x207fffff, 1, 50 * COIN);
         consensus.hashGenesisBlock = genesis.GetHash();
         assert(consensus.hashGenesisBlock ==
                uint256S("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b"
                         "1a11466e2206"));
         assert(genesis.hashMerkleRoot ==
                uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab212"
                         "7b7afdeda33b"));
 
         //!< Regtest mode doesn't have any fixed seeds.
         vFixedSeeds.clear();
         //!< Regtest mode doesn't have any DNS seeds.
         vSeeds.clear();
 
         fMiningRequiresPeers = false;
         fDefaultConsistencyChecks = true;
         fRequireStandard = false;
         fMineBlocksOnDemand = true;
 
         checkpointData = (CCheckpointData){boost::assign::map_list_of(
             0, uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a"
                         "11466e2206"))};
 
         chainTxData = ChainTxData{0, 0, 0};
 
-        base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1, 111);
-        base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1, 196);
-        base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1, 239);
+        base58Prefixes[PUBKEY_ADDRESS] = std::vector<uint8_t>(1, 111);
+        base58Prefixes[SCRIPT_ADDRESS] = std::vector<uint8_t>(1, 196);
+        base58Prefixes[SECRET_KEY] = std::vector<uint8_t>(1, 239);
         base58Prefixes[EXT_PUBLIC_KEY] =
             boost::assign::list_of(0x04)(0x35)(0x87)(0xCF)
-                .convert_to_container<std::vector<unsigned char>>();
+                .convert_to_container<std::vector<uint8_t>>();
         base58Prefixes[EXT_SECRET_KEY] =
             boost::assign::list_of(0x04)(0x35)(0x83)(0x94)
-                .convert_to_container<std::vector<unsigned char>>();
+                .convert_to_container<std::vector<uint8_t>>();
     }
 
     void UpdateBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime,
                               int64_t nTimeout) {
         consensus.vDeployments[d].nStartTime = nStartTime;
         consensus.vDeployments[d].nTimeout = nTimeout;
     }
 };
 
 static CRegTestParams regTestParams;
 
 static CChainParams *pCurrentParams = 0;
 
 const CChainParams &Params() {
     assert(pCurrentParams);
     return *pCurrentParams;
 }
 
 CChainParams &Params(const std::string &chain) {
     if (chain == CBaseChainParams::MAIN)
         return mainParams;
     else if (chain == CBaseChainParams::TESTNET)
         return testNetParams;
     else if (chain == CBaseChainParams::REGTEST)
         return regTestParams;
     else
         throw std::runtime_error(
             strprintf("%s: Unknown chain %s.", __func__, chain));
 }
 
 void SelectParams(const std::string &network) {
     SelectBaseParams(network);
     pCurrentParams = &Params(network);
 }
 
 void UpdateRegtestBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime,
                                  int64_t nTimeout) {
     regTestParams.UpdateBIP9Parameters(d, nStartTime, nTimeout);
 }
diff --git a/src/chainparams.h b/src/chainparams.h
index d9640aecf..294a32b3a 100644
--- a/src/chainparams.h
+++ b/src/chainparams.h
@@ -1,137 +1,137 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_CHAINPARAMS_H
 #define BITCOIN_CHAINPARAMS_H
 
 #include "chainparamsbase.h"
 #include "consensus/params.h"
 #include "primitives/block.h"
 #include "protocol.h"
 
 #include <vector>
 
 struct CDNSSeedData {
     std::string name, host;
     bool supportsServiceBitsFiltering;
     CDNSSeedData(const std::string &strName, const std::string &strHost,
                  bool supportsServiceBitsFilteringIn = false)
         : name(strName), host(strHost),
           supportsServiceBitsFiltering(supportsServiceBitsFilteringIn) {}
 };
 
 struct SeedSpec6 {
     uint8_t addr[16];
     uint16_t port;
 };
 
 typedef std::map<int, uint256> MapCheckpoints;
 
 struct CCheckpointData {
     MapCheckpoints mapCheckpoints;
 };
 
 struct ChainTxData {
     int64_t nTime;
     int64_t nTxCount;
     double dTxRate;
 };
 
 /**
  * CChainParams defines various tweakable parameters of a given instance of the
  * Bitcoin system. There are three: the main network on which people trade goods
  * and services, the public test network which gets reset from time to time and
  * a regression test mode which is intended for private networks only. It has
  * minimal difficulty to ensure that blocks can be found instantly.
  */
 class CChainParams {
 public:
     enum Base58Type {
         PUBKEY_ADDRESS,
         SCRIPT_ADDRESS,
         SECRET_KEY,
         EXT_PUBLIC_KEY,
         EXT_SECRET_KEY,
 
         MAX_BASE58_TYPES
     };
 
     const Consensus::Params &GetConsensus() const { return consensus; }
     const CMessageHeader::MessageStartChars &MessageStart() const {
         return pchMessageStart;
     }
     const CMessageHeader::MessageStartChars &CashMessageStart() const {
         return pchCashMessageStart;
     }
     int GetDefaultPort() const { return nDefaultPort; }
 
     const CBlock &GenesisBlock() const { return genesis; }
     /** Make miner wait to have peers to avoid wasting work */
     bool MiningRequiresPeers() const { return fMiningRequiresPeers; }
     /** Default value for -checkmempool and -checkblockindex argument */
     bool DefaultConsistencyChecks() const { return fDefaultConsistencyChecks; }
     /** Policy: Filter transactions that do not match well-defined patterns */
     bool RequireStandard() const { return fRequireStandard; }
     uint64_t PruneAfterHeight() const { return nPruneAfterHeight; }
     /**
      * Make miner stop after a block is found. In RPC, don't return until
      * nGenProcLimit blocks are generated.
      */
     bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; }
     /** Return the BIP70 network string (main, test or regtest) */
     std::string NetworkIDString() const { return strNetworkID; }
     const std::vector<CDNSSeedData> &DNSSeeds() const { return vSeeds; }
-    const std::vector<unsigned char> &Base58Prefix(Base58Type type) const {
+    const std::vector<uint8_t> &Base58Prefix(Base58Type type) const {
         return base58Prefixes[type];
     }
     const std::vector<SeedSpec6> &FixedSeeds() const { return vFixedSeeds; }
     const CCheckpointData &Checkpoints() const { return checkpointData; }
     const ChainTxData &TxData() const { return chainTxData; }
 
 protected:
     CChainParams() {}
 
     Consensus::Params consensus;
     CMessageHeader::MessageStartChars pchMessageStart;
     CMessageHeader::MessageStartChars pchCashMessageStart;
     int nDefaultPort;
     uint64_t nPruneAfterHeight;
     std::vector<CDNSSeedData> vSeeds;
-    std::vector<unsigned char> base58Prefixes[MAX_BASE58_TYPES];
+    std::vector<uint8_t> base58Prefixes[MAX_BASE58_TYPES];
     std::string strNetworkID;
     CBlock genesis;
     std::vector<SeedSpec6> vFixedSeeds;
     bool fMiningRequiresPeers;
     bool fDefaultConsistencyChecks;
     bool fRequireStandard;
     bool fMineBlocksOnDemand;
     CCheckpointData checkpointData;
     ChainTxData chainTxData;
 };
 
 /**
  * Return the currently selected parameters. This won't change after app
  * startup, except for unit tests.
  */
 const CChainParams &Params();
 
 /**
  * @returns CChainParams for the given BIP70 chain name.
  */
 CChainParams &Params(const std::string &chain);
 
 /**
  * Sets the params returned by Params() to those for the given BIP70 chain name.
  * @throws std::runtime_error when the chain is not supported.
  */
 void SelectParams(const std::string &chain);
 
 /**
  * Allows modifying the BIP9 regtest parameters.
  */
 void UpdateRegtestBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime,
                                  int64_t nTimeout);
 
 #endif // BITCOIN_CHAINPARAMS_H
diff --git a/src/coins.h b/src/coins.h
index 4618f3b00..758ccdf45 100644
--- a/src/coins.h
+++ b/src/coins.h
@@ -1,582 +1,582 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_COINS_H
 #define BITCOIN_COINS_H
 
 #include "compressor.h"
 #include "core_memusage.h"
 #include "hash.h"
 #include "memusage.h"
 #include "serialize.h"
 #include "uint256.h"
 
 #include <cassert>
 #include <cstdint>
 
 #include <unordered_map>
 
 /**
  * A UTXO entry.
  *
  * Serialized format:
  * - VARINT((coinbase ? 1 : 0) | (height << 1))
  * - the non-spent CTxOut (via CTxOutCompressor)
  */
 class Coin {
     //! Unspent transaction output.
     CTxOut out;
 
     //! Whether containing transaction was a coinbase and height at which the
     //! transaction was included into a block.
     uint32_t nHeightAndIsCoinBase;
 
 public:
     //! Empty constructor
     Coin() : nHeightAndIsCoinBase(0) {}
 
     //! Constructor from a CTxOut and height/coinbase information.
     Coin(CTxOut outIn, uint32_t nHeightIn, bool IsCoinbase)
         : out(std::move(outIn)),
           nHeightAndIsCoinBase((nHeightIn << 1) | IsCoinbase) {}
 
     uint32_t GetHeight() const { return nHeightAndIsCoinBase >> 1; }
     bool IsCoinBase() const { return nHeightAndIsCoinBase & 0x01; }
     bool IsSpent() const { return out.IsNull(); }
 
     CTxOut &GetTxOut() { return out; }
     const CTxOut &GetTxOut() const { return out; }
 
     void Clear() {
         out.SetNull();
         nHeightAndIsCoinBase = 0;
     }
 
     template <typename Stream> void Serialize(Stream &s) const {
         assert(!IsSpent());
         ::Serialize(s, VARINT(nHeightAndIsCoinBase));
         ::Serialize(s, CTxOutCompressor(REF(out)));
     }
 
     template <typename Stream> void Unserialize(Stream &s) {
         ::Unserialize(s, VARINT(nHeightAndIsCoinBase));
         ::Unserialize(s, REF(CTxOutCompressor(out)));
     }
 
     size_t DynamicMemoryUsage() const {
         return memusage::DynamicUsage(out.scriptPubKey);
     }
 };
 
 /**
  * Pruned version of CTransaction: only retains metadata and unspent transaction outputs
  *
  * Serialized format:
  * - VARINT(nVersion)
  * - VARINT(nCode)
  * - unspentness bitvector, for vout[2] and further; least significant byte first
  * - the non-spent CTxOuts (via CTxOutCompressor)
  * - VARINT(nHeight)
  *
  * The nCode value consists of:
  * - bit 0: IsCoinBase()
  * - bit 1: vout[0] is not spent
  * - bit 2: vout[1] is not spent
  * - The higher bits encode N, the number of non-zero bytes in the following bitvector.
  *   - In case both bit 1 and bit 2 are unset, they encode N-1, as there must be at
  *     least one non-spent output).
  *
  * Example: 0104835800816115944e077fe7c803cfa57f29b36bf87c1d358bb85e
  *          <><><--------------------------------------------><---->
  *          |  \                  |                             /
  *    version   code             vout[1]                  height
  *
  *    - version = 1
  *    - code = 4 (vout[1] is not spent, and 0 non-zero bytes of bitvector follow)
  *    - unspentness bitvector: as 0 non-zero bytes follow, it has length 0
  *    - vout[1]: 835800816115944e077fe7c803cfa57f29b36bf87c1d35
  *               * 8358: compact amount representation for 60000000000 (600 BCC)
  *               * 00: special txout type pay-to-pubkey-hash
  *               * 816115944e077fe7c803cfa57f29b36bf87c1d35: address uint160
  *    - height = 203998
  *
  *
  * Example: 0109044086ef97d5790061b01caab50f1b8e9c50a5057eb43c2d9563a4eebbd123008c988f1a4a4de2161e0f50aac7f17e7f9555caa486af3b
  *          <><><--><--------------------------------------------------><----------------------------------------------><---->
  *         /  \   \                     |                                                           |                     /
  *  version  code  unspentness       vout[4]                                                     vout[16]           height
  *
  *  - version = 1
  *  - code = 9 (coinbase, neither vout[0] or vout[1] are unspent,
  *                2 (1, +1 because both bit 1 and bit 2 are unset) non-zero bitvector bytes follow)
  *  - unspentness bitvector: bits 2 (0x04) and 14 (0x4000) are set, so vout[2+2] and vout[14+2] are unspent
  *  - vout[4]: 86ef97d5790061b01caab50f1b8e9c50a5057eb43c2d9563a4ee
  *             * 86ef97d579: compact amount representation for 234925952 (2.35 BCC)
  *             * 00: special txout type pay-to-pubkey-hash
  *             * 61b01caab50f1b8e9c50a5057eb43c2d9563a4ee: address uint160
  *  - vout[16]: bbd123008c988f1a4a4de2161e0f50aac7f17e7f9555caa4
  *              * bbd123: compact amount representation for 110397 (0.001 BCC)
  *              * 00: special txout type pay-to-pubkey-hash
  *              * 8c988f1a4a4de2161e0f50aac7f17e7f9555caa4: address uint160
  *  - height = 120891
  *
  * @DISABLE FORMATING FOR THIS COMMENT@
  */
 class CCoins {
 public:
     //! whether transaction is a coinbase
     bool fCoinBase;
 
     //! unspent transaction outputs; spent outputs are .IsNull(); spent outputs
     //! at the end of the array are dropped
     std::vector<CTxOut> vout;
 
     //! at which height this transaction was included in the active block chain
     int nHeight;
 
     //! version of the CTransaction; accesses to this value should probably
     //! check for nHeight as well, as new tx version will probably only be
     //! introduced at certain heights
     int nVersion;
 
     void FromTx(const CTransaction &tx, int nHeightIn) {
         fCoinBase = tx.IsCoinBase();
         vout = tx.vout;
         nHeight = nHeightIn;
         nVersion = tx.nVersion;
         ClearUnspendable();
     }
 
     //! construct a CCoins from a CTransaction, at a given height
     CCoins(const CTransaction &tx, int nHeightIn) { FromTx(tx, nHeightIn); }
 
     void Clear() {
         fCoinBase = false;
         std::vector<CTxOut>().swap(vout);
         nHeight = 0;
         nVersion = 0;
     }
 
     //! empty constructor
     CCoins() : fCoinBase(false), vout(0), nHeight(0), nVersion(0) {}
 
     //! remove spent outputs at the end of vout
     void Cleanup() {
         while (vout.size() > 0 && vout.back().IsNull())
             vout.pop_back();
         if (vout.empty()) std::vector<CTxOut>().swap(vout);
     }
 
     void ClearUnspendable() {
         for (CTxOut &txout : vout) {
             if (txout.scriptPubKey.IsUnspendable()) txout.SetNull();
         }
         Cleanup();
     }
 
     void swap(CCoins &to) {
         std::swap(to.fCoinBase, fCoinBase);
         to.vout.swap(vout);
         std::swap(to.nHeight, nHeight);
         std::swap(to.nVersion, nVersion);
     }
 
     //! equality test
     friend bool operator==(const CCoins &a, const CCoins &b) {
         // Empty CCoins objects are always equal.
         if (a.IsPruned() && b.IsPruned()) return true;
         return a.fCoinBase == b.fCoinBase && a.nHeight == b.nHeight &&
                a.nVersion == b.nVersion && a.vout == b.vout;
     }
 
     friend bool operator!=(const CCoins &a, const CCoins &b) {
         return !(a == b);
     }
 
     void CalcMaskSize(unsigned int &nBytes, unsigned int &nNonzeroBytes) const;
 
     bool IsCoinBase() const { return fCoinBase; }
 
     template <typename Stream> void Serialize(Stream &s) const {
         unsigned int nMaskSize = 0, nMaskCode = 0;
         CalcMaskSize(nMaskSize, nMaskCode);
         bool fFirst = vout.size() > 0 && !vout[0].IsNull();
         bool fSecond = vout.size() > 1 && !vout[1].IsNull();
         assert(fFirst || fSecond || nMaskCode);
         unsigned int nCode = 8 * (nMaskCode - (fFirst || fSecond ? 0 : 1)) +
                              (fCoinBase ? 1 : 0) + (fFirst ? 2 : 0) +
                              (fSecond ? 4 : 0);
         // version
         ::Serialize(s, VARINT(this->nVersion));
         // header code
         ::Serialize(s, VARINT(nCode));
         // spentness bitmask
         for (unsigned int b = 0; b < nMaskSize; b++) {
-            unsigned char chAvail = 0;
+            uint8_t chAvail = 0;
             for (unsigned int i = 0; i < 8 && 2 + b * 8 + i < vout.size(); i++)
                 if (!vout[2 + b * 8 + i].IsNull()) chAvail |= (1 << i);
             ::Serialize(s, chAvail);
         }
         // txouts themself
         for (unsigned int i = 0; i < vout.size(); i++) {
             if (!vout[i].IsNull())
                 ::Serialize(s, CTxOutCompressor(REF(vout[i])));
         }
         // coinbase height
         ::Serialize(s, VARINT(nHeight));
     }
 
     template <typename Stream> void Unserialize(Stream &s) {
         unsigned int nCode = 0;
         // version
         ::Unserialize(s, VARINT(this->nVersion));
         // header code
         ::Unserialize(s, VARINT(nCode));
         fCoinBase = nCode & 1;
         std::vector<bool> vAvail(2, false);
         vAvail[0] = (nCode & 2) != 0;
         vAvail[1] = (nCode & 4) != 0;
         unsigned int nMaskCode = (nCode / 8) + ((nCode & 6) != 0 ? 0 : 1);
         // spentness bitmask
         while (nMaskCode > 0) {
-            unsigned char chAvail = 0;
+            uint8_t chAvail = 0;
             ::Unserialize(s, chAvail);
             for (unsigned int p = 0; p < 8; p++) {
                 bool f = (chAvail & (1 << p)) != 0;
                 vAvail.push_back(f);
             }
             if (chAvail != 0) nMaskCode--;
         }
         // txouts themself
         vout.assign(vAvail.size(), CTxOut());
         for (unsigned int i = 0; i < vAvail.size(); i++) {
             if (vAvail[i]) ::Unserialize(s, REF(CTxOutCompressor(vout[i])));
         }
         // coinbase height
         ::Unserialize(s, VARINT(nHeight));
         Cleanup();
     }
 
     //! mark a vout spent
     bool Spend(uint32_t nPos);
 
     //! check whether a particular output is still available
     bool IsAvailable(unsigned int nPos) const {
         return (nPos < vout.size() && !vout[nPos].IsNull());
     }
 
     //! check whether the entire CCoins is spent
     //! note that only !IsPruned() CCoins can be serialized
     bool IsPruned() const {
         for (const CTxOut &out : vout)
             if (!out.IsNull()) return false;
         return true;
     }
 
     size_t DynamicMemoryUsage() const {
         size_t ret = memusage::DynamicUsage(vout);
         for (const CTxOut &out : vout) {
             ret += RecursiveDynamicUsage(out.scriptPubKey);
         }
         return ret;
     }
 };
 
 class SaltedTxidHasher {
 private:
     /** Salt */
     const uint64_t k0, k1;
 
 public:
     SaltedTxidHasher();
 
     /**
      * This *must* return size_t. With Boost 1.46 on 32-bit systems the
      * unordered_map will behave unpredictably if the custom hasher returns a
      * uint64_t, resulting in failures when syncing the chain (#4634).
      * Note: This information above might be outdated as the unordered map
      * container type has meanwhile been switched to the C++ standard library
      * implementation.
      */
     size_t operator()(const uint256 &txid) const {
         return SipHashUint256(k0, k1, txid);
     }
 };
 
 struct CCoinsCacheEntry {
     CCoins coins; // The actual cached data.
-    unsigned char flags;
+    uint8_t flags;
 
     enum Flags {
         // This cache entry is potentially different from the version in the
         // parent view.
         DIRTY = (1 << 0),
         // The parent view does not have this entry (or it is pruned).
         FRESH = (1 << 1),
         /* Note that FRESH is a performance optimization with which we can erase
            coins that are fully spent if we know we do not need to flush the
            changes to the parent cache. It is always safe to not mark FRESH if
            that condition is not guaranteed. */
     };
 
     CCoinsCacheEntry() : coins(), flags(0) {}
 };
 
 typedef std::unordered_map<uint256, CCoinsCacheEntry, SaltedTxidHasher>
     CCoinsMap;
 
 /** Cursor for iterating over CoinsView state */
 class CCoinsViewCursor {
 public:
     CCoinsViewCursor(const uint256 &hashBlockIn) : hashBlock(hashBlockIn) {}
     virtual ~CCoinsViewCursor();
 
     virtual bool GetKey(uint256 &key) const = 0;
     virtual bool GetValue(CCoins &coins) const = 0;
     /* Don't care about GetKeySize here */
     virtual unsigned int GetValueSize() const = 0;
 
     virtual bool Valid() const = 0;
     virtual void Next() = 0;
 
     //! Get best block at the time this cursor was created
     const uint256 &GetBestBlock() const { return hashBlock; }
 
 private:
     uint256 hashBlock;
 };
 
 /** Abstract view on the open txout dataset. */
 class CCoinsView {
 protected:
     //! Retrieve the CCoins (unspent transaction outputs) for a given txid
     virtual bool GetCoins(const uint256 &txid, CCoins &coins) const;
 
     //! Just check whether we have data for a given txid.
     //! This may (but cannot always) return true for fully spent transactions
     virtual bool HaveCoins(const uint256 &txid) const;
 
 public:
     //! Transitional function to move from GetCoins to GetCoin.
     bool GetCoins_DONOTUSE(const uint256 &txid, CCoins &coins) const {
         return GetCoins(txid, coins);
     }
 
     //! Retrieve the Coin (unspent transaction output) for a given outpoint.
     bool GetCoin(const COutPoint &outpoint, Coin &coin) const {
         CCoins coins;
         if (!GetCoins(outpoint.hash, coins) || !coins.IsAvailable(outpoint.n)) {
             return false;
         }
 
         coin = Coin(coins.vout[outpoint.n], coins.nHeight, coins.fCoinBase);
         return true;
     }
 
     //! Transitional function to move from HaveCoins to HaveCoin.
     bool HaveCoins_DONOTUSE(const uint256 &txid) const {
         return HaveCoins(txid);
     }
 
     //! Just check whether we have data for a given outpoint.
     //! This may (but cannot always) return true for spent outputs.
     bool HaveCoin(const COutPoint &outpoint) const {
         CCoins coins;
         if (!GetCoins(outpoint.hash, coins)) {
             return false;
         }
         return coins.IsAvailable(outpoint.n);
     }
 
     //! Retrieve the block hash whose state this CCoinsView currently represents
     virtual uint256 GetBestBlock() const;
 
     //! Do a bulk modification (multiple CCoins changes + BestBlock change).
     //! The passed mapCoins can be modified.
     virtual bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
 
     //! Get a cursor to iterate over the whole state
     virtual CCoinsViewCursor *Cursor() const;
 
     //! As we use CCoinsViews polymorphically, have a virtual destructor
     virtual ~CCoinsView() {}
 };
 
 /** CCoinsView backed by another CCoinsView */
 class CCoinsViewBacked : public CCoinsView {
 protected:
     CCoinsView *base;
 
     bool GetCoins(const uint256 &txid, CCoins &coins) const;
     bool HaveCoins(const uint256 &txid) const;
 
 public:
     CCoinsViewBacked(CCoinsView *viewIn);
     uint256 GetBestBlock() const;
     void SetBackend(CCoinsView &viewIn);
     bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
     CCoinsViewCursor *Cursor() const;
 };
 
 class CCoinsViewCache;
 
 /**
  * A reference to a mutable cache entry. Encapsulating it allows us to run
  *  cleanup code after the modification is finished, and keeping track of
  *  concurrent modifications.
  */
 class CCoinsModifier {
 private:
     CCoinsViewCache &cache;
     CCoinsMap::iterator it;
     // Cached memory usage of the CCoins object before modification.
     size_t cachedCoinUsage;
 
     CCoinsModifier(CCoinsViewCache &cache_, CCoinsMap::iterator it_,
                    size_t usage);
 
 public:
     CCoins *operator->() { return &it->second.coins; }
     CCoins &operator*() { return it->second.coins; }
     ~CCoinsModifier();
     friend class CCoinsViewCache;
 };
 
 /** CCoinsView that adds a memory cache for transactions to another CCoinsView
  */
 class CCoinsViewCache : public CCoinsViewBacked {
 protected:
     /* Whether this cache has an active modifier. */
     bool hasModifier;
 
     /**
      * Make mutable so that we can "fill the cache" even from Get-methods
      * declared as "const".
      */
     mutable uint256 hashBlock;
     mutable CCoinsMap cacheCoins;
 
     /* Cached dynamic memory usage for the inner CCoins objects. */
     mutable size_t cachedCoinsUsage;
 
     bool GetCoins(const uint256 &txid, CCoins &coins) const;
     bool HaveCoins(const uint256 &txid) const;
 
     /**
      * Return a pointer to CCoins in the cache, or nullptr if not found. This is
      * more efficient than GetCoins. Modifications to other cache entries are
      * allowed while accessing the returned pointer.
      */
     const CCoins *AccessCoins(const uint256 &txid) const;
 
 public:
     CCoinsViewCache(CCoinsView *baseIn);
     ~CCoinsViewCache();
 
     // Standard CCoinsView methods
     uint256 GetBestBlock() const;
     void SetBestBlock(const uint256 &hashBlock);
     bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
 
     /**
      * Check if we have the given utxo already loaded in this cache.
      * The semantics are the same as HaveCoin(), but no calls to the backing
      * CCoinsView are made.
      */
     bool HaveCoinInCache(const COutPoint &outpoint) const;
 
     //! Transitional function to move from AccessCoins to AccessCoin.
     const CCoins *AccessCoins_DONOTUSE(const uint256 &txid) const {
         return AccessCoins(txid);
     }
 
     /**
      * Return a copy of a Coin in the cache, or a pruned one if not found. This
      * is more efficient than GetCoin. Modifications to other cache entries are
      * allowed while accessing the returned pointer.
      * TODO: return a reference instead of a value once underlying storage is
      * updated.
      */
     const Coin AccessCoin(const COutPoint &output) const;
 
     /**
      * Return a modifiable reference to a CCoins. If no entry with the given
      * txid exists, a new one is created. Simultaneous modifications are not
      * allowed.
      */
     CCoinsModifier ModifyCoins(const uint256 &txid);
 
     /**
      * Return a modifiable reference to a CCoins. Assumes that no entry with the
      * given txid exists and creates a new one. This saves a database access in
      * the case where the coins were to be wiped out by FromTx anyway. This
      * should not be called with the 2 historical coinbase duplicate pairs
      * because the new coins are marked fresh, and in the event the duplicate
      * coinbase was spent before a flush, the now pruned coins would not
      * properly overwrite the first coinbase of the pair. Simultaneous
      * modifications are not allowed.
      */
     CCoinsModifier ModifyNewCoins(const uint256 &txid, bool coinbase);
 
     /**
      * Push the modifications applied to this cache to its base.
      * Failure to call this method before destruction will cause the changes to
      * be forgotten. If false is returned, the state of this cache (and its
      * backing view) will be undefined.
      */
     bool Flush();
 
     /**
      * Removes the UTXO with the given outpoint from the cache, if it is not
      * modified.
      */
     void Uncache(const COutPoint &outpoint);
 
     //! Calculate the size of the cache (in number of transactions)
     unsigned int GetCacheSize() const;
 
     //! Calculate the size of the cache (in bytes)
     size_t DynamicMemoryUsage() const;
 
     /**
      * Amount of bitcoins coming in to a transaction
      * Note that lightweight clients may not know anything besides the hash of
      * previous transactions, so may not be able to calculate this.
      *
      * @param[in] tx	transaction for which we are checking input total
      * @return	Sum of value of all inputs (scriptSigs)
      */
     CAmount GetValueIn(const CTransaction &tx) const;
 
     //! Check whether all prevouts of the transaction are present in the UTXO
     //! set represented by this view
     bool HaveInputs(const CTransaction &tx) const;
 
     /**
      * Return priority of tx at height nHeight. Also calculate the sum of the
      * values of the inputs that are already in the chain. These are the inputs
      * that will age and increase priority as new blocks are added to the chain.
      */
     double GetPriority(const CTransaction &tx, int nHeight,
                        CAmount &inChainInputValue) const;
 
     const CTxOut &GetOutputFor(const CTxIn &input) const;
 
     friend class CCoinsModifier;
 
 private:
     CCoinsMap::const_iterator FetchCoins(const uint256 &txid) const;
 
     /**
      * By making the copy constructor private, we prevent accidentally using it
      * when one intends to create a cache on top of a base cache.
      */
     CCoinsViewCache(const CCoinsViewCache &);
 };
 
 //! Utility function to find any unspent output with a given txid.
 const Coin AccessByTxid(const CCoinsViewCache &cache, const uint256 &txid);
 
 #endif // BITCOIN_COINS_H
diff --git a/src/compressor.cpp b/src/compressor.cpp
index 490f5e536..e56b551fd 100644
--- a/src/compressor.cpp
+++ b/src/compressor.cpp
@@ -1,185 +1,185 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-2014 The Bitcoin Core developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #include "compressor.h"
 
 #include "hash.h"
 #include "pubkey.h"
 #include "script/standard.h"
 
 bool CScriptCompressor::IsToKeyID(CKeyID &hash) const {
     if (script.size() == 25 && script[0] == OP_DUP && script[1] == OP_HASH160 &&
         script[2] == 20 && script[23] == OP_EQUALVERIFY &&
         script[24] == OP_CHECKSIG) {
         memcpy(&hash, &script[3], 20);
         return true;
     }
     return false;
 }
 
 bool CScriptCompressor::IsToScriptID(CScriptID &hash) const {
     if (script.size() == 23 && script[0] == OP_HASH160 && script[1] == 20 &&
         script[22] == OP_EQUAL) {
         memcpy(&hash, &script[2], 20);
         return true;
     }
     return false;
 }
 
 bool CScriptCompressor::IsToPubKey(CPubKey &pubkey) const {
     if (script.size() == 35 && script[0] == 33 && script[34] == OP_CHECKSIG &&
         (script[1] == 0x02 || script[1] == 0x03)) {
         pubkey.Set(&script[1], &script[34]);
         return true;
     }
     if (script.size() == 67 && script[0] == 65 && script[66] == OP_CHECKSIG &&
         script[1] == 0x04) {
         pubkey.Set(&script[1], &script[66]);
         // if not fully valid, a case that would not be compressible
         return pubkey.IsFullyValid();
     }
     return false;
 }
 
-bool CScriptCompressor::Compress(std::vector<unsigned char> &out) const {
+bool CScriptCompressor::Compress(std::vector<uint8_t> &out) const {
     CKeyID keyID;
     if (IsToKeyID(keyID)) {
         out.resize(21);
         out[0] = 0x00;
         memcpy(&out[1], &keyID, 20);
         return true;
     }
     CScriptID scriptID;
     if (IsToScriptID(scriptID)) {
         out.resize(21);
         out[0] = 0x01;
         memcpy(&out[1], &scriptID, 20);
         return true;
     }
     CPubKey pubkey;
     if (IsToPubKey(pubkey)) {
         out.resize(33);
         memcpy(&out[1], &pubkey[1], 32);
         if (pubkey[0] == 0x02 || pubkey[0] == 0x03) {
             out[0] = pubkey[0];
             return true;
         } else if (pubkey[0] == 0x04) {
             out[0] = 0x04 | (pubkey[64] & 0x01);
             return true;
         }
     }
     return false;
 }
 
 unsigned int CScriptCompressor::GetSpecialSize(unsigned int nSize) const {
     if (nSize == 0 || nSize == 1) {
         return 20;
     }
     if (nSize == 2 || nSize == 3 || nSize == 4 || nSize == 5) {
         return 32;
     }
     return 0;
 }
 
 bool CScriptCompressor::Decompress(unsigned int nSize,
-                                   const std::vector<unsigned char> &in) {
+                                   const std::vector<uint8_t> &in) {
     switch (nSize) {
         case 0x00:
             script.resize(25);
             script[0] = OP_DUP;
             script[1] = OP_HASH160;
             script[2] = 20;
             memcpy(&script[3], &in[0], 20);
             script[23] = OP_EQUALVERIFY;
             script[24] = OP_CHECKSIG;
             return true;
         case 0x01:
             script.resize(23);
             script[0] = OP_HASH160;
             script[1] = 20;
             memcpy(&script[2], &in[0], 20);
             script[22] = OP_EQUAL;
             return true;
         case 0x02:
         case 0x03:
             script.resize(35);
             script[0] = 33;
             script[1] = nSize;
             memcpy(&script[2], &in[0], 32);
             script[34] = OP_CHECKSIG;
             return true;
         case 0x04:
         case 0x05:
-            unsigned char vch[33] = {};
+            uint8_t vch[33] = {};
             vch[0] = nSize - 2;
             memcpy(&vch[1], &in[0], 32);
             CPubKey pubkey(&vch[0], &vch[33]);
             if (!pubkey.Decompress()) return false;
             assert(pubkey.size() == 65);
             script.resize(67);
             script[0] = 65;
             memcpy(&script[1], pubkey.begin(), 65);
             script[66] = OP_CHECKSIG;
             return true;
     }
     return false;
 }
 
 // Amount compression:
 // * If the amount is 0, output 0
 // * first, divide the amount (in base units) by the largest power of 10
 // possible; call the exponent e (e is max 9)
 // * if e<9, the last digit of the resulting number cannot be 0; store it as d,
 // and drop it (divide by 10)
 //   * call the result n
 //   * output 1 + 10*(9*n + d - 1) + e
 // * if e==9, we only know the resulting number is not zero, so output 1 + 10*(n
 // - 1) + 9
 // (this is decodable, as d is in [1-9] and e is in [0-9])
 
 uint64_t CTxOutCompressor::CompressAmount(uint64_t n) {
     if (n == 0) {
         return 0;
     }
     int e = 0;
     while (((n % 10) == 0) && e < 9) {
         n /= 10;
         e++;
     }
     if (e < 9) {
         int d = (n % 10);
         assert(d >= 1 && d <= 9);
         n /= 10;
         return 1 + (n * 9 + d - 1) * 10 + e;
     } else {
         return 1 + (n - 1) * 10 + 9;
     }
 }
 
 uint64_t CTxOutCompressor::DecompressAmount(uint64_t x) {
     // x = 0  OR  x = 1+10*(9*n + d - 1) + e  OR  x = 1+10*(n - 1) + 9
     if (x == 0) {
         return 0;
     }
     x--;
     // x = 10*(9*n + d - 1) + e
     int e = x % 10;
     x /= 10;
     uint64_t n = 0;
     if (e < 9) {
         // x = 9*n + d - 1
         int d = (x % 9) + 1;
         x /= 9;
         // x = n
         n = x * 10 + d;
     } else {
         n = x + 1;
     }
     while (e) {
         n *= 10;
         e--;
     }
     return n;
 }
diff --git a/src/compressor.h b/src/compressor.h
index fd1b5929e..355b84a62 100644
--- a/src/compressor.h
+++ b/src/compressor.h
@@ -1,120 +1,120 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_COMPRESSOR_H
 #define BITCOIN_COMPRESSOR_H
 
 #include "primitives/transaction.h"
 #include "script/script.h"
 #include "serialize.h"
 
 class CKeyID;
 class CPubKey;
 class CScriptID;
 
 /**
  * Compact serializer for scripts.
  *
  * It detects common cases and encodes them much more efficiently.
  * 3 special cases are defined:
  *  * Pay to pubkey hash (encoded as 21 bytes)
  *  * Pay to script hash (encoded as 21 bytes)
  *  * Pay to pubkey starting with 0x02, 0x03 or 0x04 (encoded as 33 bytes)
  *
  * Other scripts up to 121 bytes require 1 byte + script length. Above that,
  * scripts up to 16505 bytes require 2 bytes + script length.
  */
 class CScriptCompressor {
 private:
     /**
      * make this static for now (there are only 6 special scripts defined) this
      * can potentially be extended together with a new nVersion for
      * transactions, in which case this value becomes dependent on nVersion and
      * nHeight of the enclosing transaction.
      */
     static const unsigned int nSpecialScripts = 6;
 
     CScript &script;
 
 protected:
     /**
      * These check for scripts for which a special case with a shorter encoding
      * is defined. They are implemented separately from the CScript test, as
      * these test for exact byte sequence correspondences, and are more strict.
      * For example, IsToPubKey also verifies whether the public key is valid (as
      * invalid ones cannot be represented in compressed form).
      */
     bool IsToKeyID(CKeyID &hash) const;
     bool IsToScriptID(CScriptID &hash) const;
     bool IsToPubKey(CPubKey &pubkey) const;
 
-    bool Compress(std::vector<unsigned char> &out) const;
+    bool Compress(std::vector<uint8_t> &out) const;
     unsigned int GetSpecialSize(unsigned int nSize) const;
-    bool Decompress(unsigned int nSize, const std::vector<unsigned char> &out);
+    bool Decompress(unsigned int nSize, const std::vector<uint8_t> &out);
 
 public:
     CScriptCompressor(CScript &scriptIn) : script(scriptIn) {}
 
     template <typename Stream> void Serialize(Stream &s) const {
-        std::vector<unsigned char> compr;
+        std::vector<uint8_t> compr;
         if (Compress(compr)) {
             s << CFlatData(compr);
             return;
         }
         unsigned int nSize = script.size() + nSpecialScripts;
         s << VARINT(nSize);
         s << CFlatData(script);
     }
 
     template <typename Stream> void Unserialize(Stream &s) {
         unsigned int nSize = 0;
         s >> VARINT(nSize);
         if (nSize < nSpecialScripts) {
-            std::vector<unsigned char> vch(GetSpecialSize(nSize), 0x00);
+            std::vector<uint8_t> vch(GetSpecialSize(nSize), 0x00);
             s >> REF(CFlatData(vch));
             Decompress(nSize, vch);
             return;
         }
         nSize -= nSpecialScripts;
         if (nSize > MAX_SCRIPT_SIZE) {
             // Overly long script, replace with a short invalid one
             script << OP_RETURN;
             s.ignore(nSize);
         } else {
             script.resize(nSize);
             s >> REF(CFlatData(script));
         }
     }
 };
 
 /** wrapper for CTxOut that provides a more compact serialization */
 class CTxOutCompressor {
 private:
     CTxOut &txout;
 
 public:
     static uint64_t CompressAmount(uint64_t nAmount);
     static uint64_t DecompressAmount(uint64_t nAmount);
 
     CTxOutCompressor(CTxOut &txoutIn) : txout(txoutIn) {}
 
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
     inline void SerializationOp(Stream &s, Operation ser_action) {
         if (!ser_action.ForRead()) {
             uint64_t nVal = CompressAmount(txout.nValue);
             READWRITE(VARINT(nVal));
         } else {
             uint64_t nVal = 0;
             READWRITE(VARINT(nVal));
             txout.nValue = DecompressAmount(nVal);
         }
         CScriptCompressor cscript(REF(txout.scriptPubKey));
         READWRITE(cscript);
     }
 };
 
 #endif // BITCOIN_COMPRESSOR_H
diff --git a/src/consensus/params.h b/src/consensus/params.h
index c7694e265..a6559109c 100644
--- a/src/consensus/params.h
+++ b/src/consensus/params.h
@@ -1,77 +1,77 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_CONSENSUS_PARAMS_H
 #define BITCOIN_CONSENSUS_PARAMS_H
 
 #include "uint256.h"
 #include <map>
 #include <string>
 
 namespace Consensus {
 
 enum DeploymentPos {
     DEPLOYMENT_TESTDUMMY,
     // Deployment of BIP68, BIP112, and BIP113.
     DEPLOYMENT_CSV,
     // NOTE: Also add new deployments to VersionBitsDeploymentInfo in
     // versionbits.cpp
     MAX_VERSION_BITS_DEPLOYMENTS
 };
 
 /**
  * Struct for each individual consensus rule change using BIP9.
  */
 struct BIP9Deployment {
     /** Bit position to select the particular bit in nVersion. */
     int bit;
     /** Start MedianTime for version bits miner confirmation. Can be a date in
      * the past */
     int64_t nStartTime;
     /** Timeout/expiry MedianTime for the deployment attempt. */
     int64_t nTimeout;
 };
 
 /**
  * Parameters that influence chain consensus.
  */
 struct Params {
     uint256 hashGenesisBlock;
     int nSubsidyHalvingInterval;
     /** Block height and hash at which BIP34 becomes active */
     int BIP34Height;
     uint256 BIP34Hash;
     /** Block height at which BIP65 becomes active */
     int BIP65Height;
     /** Block height at which BIP66 becomes active */
     int BIP66Height;
     /** Block height at which OP_RETURN replay protection stops */
     int antiReplayOpReturnSunsetHeight;
     /** Committed OP_RETURN value for replay protection */
-    std::vector<unsigned char> antiReplayOpReturnCommitment;
+    std::vector<uint8_t> antiReplayOpReturnCommitment;
     /**
      * Minimum blocks including miner confirmation of the total of 2016 blocks
      * in a retargeting period, (nPowTargetTimespan / nPowTargetSpacing) which
      * is also used for BIP9 deployments.
      * Examples: 1916 for 95%, 1512 for testchains.
      */
     uint32_t nRuleChangeActivationThreshold;
     uint32_t nMinerConfirmationWindow;
     BIP9Deployment vDeployments[MAX_VERSION_BITS_DEPLOYMENTS];
     /** Proof of work parameters */
     uint256 powLimit;
     bool fPowAllowMinDifficultyBlocks;
     bool fPowNoRetargeting;
     int64_t nPowTargetSpacing;
     int64_t nPowTargetTimespan;
     int64_t DifficultyAdjustmentInterval() const {
         return nPowTargetTimespan / nPowTargetSpacing;
     }
     uint256 nMinimumChainWork;
     uint256 defaultAssumeValid;
 };
 } // namespace Consensus
 
 #endif // BITCOIN_CONSENSUS_PARAMS_H
diff --git a/src/consensus/validation.h b/src/consensus/validation.h
index 3d27f5a92..fc9f53451 100644
--- a/src/consensus/validation.h
+++ b/src/consensus/validation.h
@@ -1,89 +1,89 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_CONSENSUS_VALIDATION_H
 #define BITCOIN_CONSENSUS_VALIDATION_H
 
 #include <string>
 
 /** "reject" message codes */
-static const unsigned char REJECT_MALFORMED = 0x01;
-static const unsigned char REJECT_INVALID = 0x10;
-static const unsigned char REJECT_OBSOLETE = 0x11;
-static const unsigned char REJECT_DUPLICATE = 0x12;
-static const unsigned char REJECT_NONSTANDARD = 0x40;
-static const unsigned char REJECT_DUST = 0x41;
-static const unsigned char REJECT_INSUFFICIENTFEE = 0x42;
-static const unsigned char REJECT_CHECKPOINT = 0x43;
+static const uint8_t REJECT_MALFORMED = 0x01;
+static const uint8_t REJECT_INVALID = 0x10;
+static const uint8_t REJECT_OBSOLETE = 0x11;
+static const uint8_t REJECT_DUPLICATE = 0x12;
+static const uint8_t REJECT_NONSTANDARD = 0x40;
+static const uint8_t REJECT_DUST = 0x41;
+static const uint8_t REJECT_INSUFFICIENTFEE = 0x42;
+static const uint8_t REJECT_CHECKPOINT = 0x43;
 
 /** Capture information about block/transaction validation */
 class CValidationState {
 private:
     enum mode_state {
         MODE_VALID,   //!< everything ok
         MODE_INVALID, //!< network rule violation (DoS value may be set)
         MODE_ERROR,   //!< run-time error
     } mode;
     int nDoS;
     std::string strRejectReason;
     unsigned int chRejectCode;
     bool corruptionPossible;
     std::string strDebugMessage;
 
 public:
     CValidationState()
         : mode(MODE_VALID), nDoS(0), chRejectCode(0),
           corruptionPossible(false) {}
 
     bool DoS(int level, bool ret = false, unsigned int chRejectCodeIn = 0,
              const std::string &strRejectReasonIn = "",
              bool corruptionIn = false,
              const std::string &strDebugMessageIn = "") {
         chRejectCode = chRejectCodeIn;
         strRejectReason = strRejectReasonIn;
         corruptionPossible = corruptionIn;
         strDebugMessage = strDebugMessageIn;
         if (mode == MODE_ERROR) {
             return ret;
         }
         nDoS += level;
         mode = MODE_INVALID;
         return ret;
     }
 
     bool Invalid(bool ret = false, unsigned int _chRejectCode = 0,
                  const std::string &_strRejectReason = "",
                  const std::string &_strDebugMessage = "") {
         return DoS(0, ret, _chRejectCode, _strRejectReason, false,
                    _strDebugMessage);
     }
     bool Error(const std::string &strRejectReasonIn) {
         if (mode == MODE_VALID) {
             strRejectReason = strRejectReasonIn;
         }
 
         mode = MODE_ERROR;
         return false;
     }
 
     bool IsValid() const { return mode == MODE_VALID; }
     bool IsInvalid() const { return mode == MODE_INVALID; }
     bool IsError() const { return mode == MODE_ERROR; }
     bool IsInvalid(int &nDoSOut) const {
         if (IsInvalid()) {
             nDoSOut = nDoS;
             return true;
         }
         return false;
     }
 
     bool CorruptionPossible() const { return corruptionPossible; }
     void SetCorruptionPossible() { corruptionPossible = true; }
     unsigned int GetRejectCode() const { return chRejectCode; }
     std::string GetRejectReason() const { return strRejectReason; }
     std::string GetDebugMessage() const { return strDebugMessage; }
 };
 
 #endif // BITCOIN_CONSENSUS_VALIDATION_H
diff --git a/src/core_io.h b/src/core_io.h
index f1abf77a4..e1bf406b6 100644
--- a/src/core_io.h
+++ b/src/core_io.h
@@ -1,37 +1,36 @@
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_CORE_IO_H
 #define BITCOIN_CORE_IO_H
 
 #include <string>
 #include <vector>
 
 class CBlock;
 class CScript;
 class CTransaction;
 struct CMutableTransaction;
 class uint256;
 class UniValue;
 
 // core_read.cpp
 CScript ParseScript(const std::string &s);
 std::string ScriptToAsmStr(const CScript &script,
                            const bool fAttemptSighashDecode = false);
 bool DecodeHexTx(CMutableTransaction &tx, const std::string &strHexTx);
 bool DecodeHexBlk(CBlock &, const std::string &strHexBlk);
 uint256 ParseHashUV(const UniValue &v, const std::string &strName);
 uint256 ParseHashStr(const std::string &, const std::string &strName);
-std::vector<unsigned char> ParseHexUV(const UniValue &v,
-                                      const std::string &strName);
+std::vector<uint8_t> ParseHexUV(const UniValue &v, const std::string &strName);
 
 // core_write.cpp
 std::string FormatScript(const CScript &script);
 std::string EncodeHexTx(const CTransaction &tx, const int serializeFlags = 0);
 void ScriptPubKeyToUniv(const CScript &scriptPubKey, UniValue &out,
                         bool fIncludeHex);
 void TxToUniv(const CTransaction &tx, const uint256 &hashBlock,
               UniValue &entry);
 
 #endif // BITCOIN_CORE_IO_H
diff --git a/src/core_read.cpp b/src/core_read.cpp
index 1ec6699b5..82528a629 100644
--- a/src/core_read.cpp
+++ b/src/core_read.cpp
@@ -1,161 +1,160 @@
 // Copyright (c) 2009-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.
 
 #include "core_io.h"
 
 #include "primitives/block.h"
 #include "primitives/transaction.h"
 #include "script/script.h"
 #include "serialize.h"
 #include "streams.h"
 #include "util.h"
 #include "utilstrencodings.h"
 #include "version.h"
 
 #include <univalue.h>
 
 #include <boost/algorithm/string/classification.hpp>
 #include <boost/algorithm/string/predicate.hpp>
 #include <boost/algorithm/string/replace.hpp>
 #include <boost/algorithm/string/split.hpp>
 #include <boost/assign/list_of.hpp>
 
 CScript ParseScript(const std::string &s) {
     CScript result;
 
     static std::map<std::string, opcodetype> mapOpNames;
 
     if (mapOpNames.empty()) {
         for (int op = 0; op <= OP_NOP10; op++) {
             // Allow OP_RESERVED to get into mapOpNames
             if (op < OP_NOP && op != OP_RESERVED) {
                 continue;
             }
 
             const char *name = GetOpName((opcodetype)op);
             if (strcmp(name, "OP_UNKNOWN") == 0) {
                 continue;
             }
 
             std::string strName(name);
             mapOpNames[strName] = (opcodetype)op;
             // Convenience: OP_ADD and just ADD are both recognized:
             boost::algorithm::replace_first(strName, "OP_", "");
             mapOpNames[strName] = (opcodetype)op;
         }
     }
 
     std::vector<std::string> words;
     boost::algorithm::split(words, s, boost::algorithm::is_any_of(" \t\n"),
                             boost::algorithm::token_compress_on);
 
     for (std::vector<std::string>::const_iterator w = words.begin();
          w != words.end(); ++w) {
         if (w->empty()) {
             // Empty string, ignore. (boost::split given '' will return one
             // word)
         } else if (all(*w, boost::algorithm::is_digit()) ||
                    (boost::algorithm::starts_with(*w, "-") &&
                     all(std::string(w->begin() + 1, w->end()),
                         boost::algorithm::is_digit()))) {
             // Number
             int64_t n = atoi64(*w);
             result << n;
         } else if (boost::algorithm::starts_with(*w, "0x") &&
                    (w->begin() + 2 != w->end()) &&
                    IsHex(std::string(w->begin() + 2, w->end()))) {
             // Raw hex data, inserted NOT pushed onto stack:
-            std::vector<unsigned char> raw =
+            std::vector<uint8_t> raw =
                 ParseHex(std::string(w->begin() + 2, w->end()));
             result.insert(result.end(), raw.begin(), raw.end());
         } else if (w->size() >= 2 && boost::algorithm::starts_with(*w, "'") &&
                    boost::algorithm::ends_with(*w, "'")) {
             // Single-quoted string, pushed as data. NOTE: this is poor-man's
             // parsing, spaces/tabs/newlines in single-quoted strings won't
             // work.
-            std::vector<unsigned char> value(w->begin() + 1, w->end() - 1);
+            std::vector<uint8_t> value(w->begin() + 1, w->end() - 1);
             result << value;
         } else if (mapOpNames.count(*w)) {
             // opcode, e.g. OP_ADD or ADD:
             result << mapOpNames[*w];
         } else {
             throw std::runtime_error("script parse error");
         }
     }
 
     return result;
 }
 
 bool DecodeHexTx(CMutableTransaction &tx, const std::string &strHexTx) {
     if (!IsHex(strHexTx)) {
         return false;
     }
 
-    std::vector<unsigned char> txData(ParseHex(strHexTx));
+    std::vector<uint8_t> txData(ParseHex(strHexTx));
 
     CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
     try {
         ssData >> tx;
         if (!ssData.empty()) {
             return false;
         }
     } catch (const std::exception &) {
         return false;
     }
 
     return true;
 }
 
 bool DecodeHexBlk(CBlock &block, const std::string &strHexBlk) {
     if (!IsHex(strHexBlk)) {
         return false;
     }
 
-    std::vector<unsigned char> blockData(ParseHex(strHexBlk));
+    std::vector<uint8_t> blockData(ParseHex(strHexBlk));
     CDataStream ssBlock(blockData, SER_NETWORK, PROTOCOL_VERSION);
     try {
         ssBlock >> block;
     } catch (const std::exception &) {
         return false;
     }
 
     return true;
 }
 
 uint256 ParseHashUV(const UniValue &v, const std::string &strName) {
     std::string strHex;
     if (v.isStr()) {
         strHex = v.getValStr();
     }
 
     // Note: ParseHashStr("") throws a runtime_error
     return ParseHashStr(strHex, strName);
 }
 
 uint256 ParseHashStr(const std::string &strHex, const std::string &strName) {
     if (!IsHex(strHex)) {
         // Note: IsHex("") is false
         throw std::runtime_error(
             strName + " must be hexadecimal string (not '" + strHex + "')");
     }
 
     uint256 result;
     result.SetHex(strHex);
     return result;
 }
 
-std::vector<unsigned char> ParseHexUV(const UniValue &v,
-                                      const std::string &strName) {
+std::vector<uint8_t> ParseHexUV(const UniValue &v, const std::string &strName) {
     std::string strHex;
     if (v.isStr()) {
         strHex = v.getValStr();
     }
 
     if (!IsHex(strHex)) {
         throw std::runtime_error(
             strName + " must be hexadecimal string (not '" + strHex + "')");
     }
 
     return ParseHex(strHex);
 }
diff --git a/src/core_write.cpp b/src/core_write.cpp
index 712d42e9c..2609e2cf3 100644
--- a/src/core_write.cpp
+++ b/src/core_write.cpp
@@ -1,252 +1,251 @@
 // Copyright (c) 2009-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.
 
 #include "core_io.h"
 
 #include "base58.h"
 #include "primitives/transaction.h"
 #include "script/script.h"
 #include "script/standard.h"
 #include "serialize.h"
 #include "streams.h"
 #include "util.h"
 #include "utilmoneystr.h"
 #include "utilstrencodings.h"
 
 #include <univalue.h>
 
 #include <boost/assign/list_of.hpp>
 
 std::string FormatScript(const CScript &script) {
     std::string ret;
     CScript::const_iterator it = script.begin();
     opcodetype op;
     while (it != script.end()) {
         CScript::const_iterator it2 = it;
-        std::vector<unsigned char> vch;
+        std::vector<uint8_t> vch;
         if (script.GetOp2(it, op, &vch)) {
             if (op == OP_0) {
                 ret += "0 ";
                 continue;
             }
 
             if ((op >= OP_1 && op <= OP_16) || op == OP_1NEGATE) {
                 ret += strprintf("%i ", op - OP_1NEGATE - 1);
                 continue;
             }
 
             if (op >= OP_NOP && op <= OP_NOP10) {
                 std::string str(GetOpName(op));
                 if (str.substr(0, 3) == std::string("OP_")) {
                     ret += str.substr(3, std::string::npos) + " ";
                     continue;
                 }
             }
 
             if (vch.size() > 0) {
                 ret += strprintf("0x%x 0x%x ", HexStr(it2, it - vch.size()),
                                  HexStr(it - vch.size(), it));
             } else {
                 ret += strprintf("0x%x ", HexStr(it2, it));
             }
 
             continue;
         }
 
         ret += strprintf("0x%x ", HexStr(it2, script.end()));
         break;
     }
 
     return ret.substr(0, ret.size() - 1);
 }
 
-const std::map<unsigned char, std::string> mapSigHashTypes =
-    boost::assign::map_list_of(static_cast<unsigned char>(SIGHASH_ALL),
+const std::map<uint8_t, std::string> mapSigHashTypes =
+    boost::assign::map_list_of(static_cast<uint8_t>(SIGHASH_ALL),
                                std::string("ALL"))(
-        static_cast<unsigned char>(SIGHASH_ALL | SIGHASH_ANYONECANPAY),
+        static_cast<uint8_t>(SIGHASH_ALL | SIGHASH_ANYONECANPAY),
         std::string("ALL|ANYONECANPAY"))(
-        static_cast<unsigned char>(SIGHASH_ALL | SIGHASH_FORKID),
-        std::string("ALL|FORKID"))(
-        static_cast<unsigned char>(SIGHASH_ALL | SIGHASH_FORKID |
-                                   SIGHASH_ANYONECANPAY),
-        std::string("ALL|FORKID|ANYONECANPAY"))(
-        static_cast<unsigned char>(SIGHASH_NONE), std::string("NONE"))(
-        static_cast<unsigned char>(SIGHASH_NONE | SIGHASH_ANYONECANPAY),
+        static_cast<uint8_t>(SIGHASH_ALL | SIGHASH_FORKID),
+        std::string("ALL|FORKID"))(static_cast<uint8_t>(SIGHASH_ALL |
+                                                        SIGHASH_FORKID |
+                                                        SIGHASH_ANYONECANPAY),
+                                   std::string("ALL|FORKID|ANYONECANPAY"))(
+        static_cast<uint8_t>(SIGHASH_NONE), std::string("NONE"))(
+        static_cast<uint8_t>(SIGHASH_NONE | SIGHASH_ANYONECANPAY),
         std::string("NONE|ANYONECANPAY"))(
-        static_cast<unsigned char>(SIGHASH_NONE | SIGHASH_FORKID),
-        std::string("NONE|FORKID"))(
-        static_cast<unsigned char>(SIGHASH_NONE | SIGHASH_FORKID |
-                                   SIGHASH_ANYONECANPAY),
-        std::string("NONE|FORKID|ANYONECANPAY"))(
-        static_cast<unsigned char>(SIGHASH_SINGLE), std::string("SINGLE"))(
-        static_cast<unsigned char>(SIGHASH_SINGLE | SIGHASH_ANYONECANPAY),
+        static_cast<uint8_t>(SIGHASH_NONE | SIGHASH_FORKID),
+        std::string("NONE|FORKID"))(static_cast<uint8_t>(SIGHASH_NONE |
+                                                         SIGHASH_FORKID |
+                                                         SIGHASH_ANYONECANPAY),
+                                    std::string("NONE|FORKID|ANYONECANPAY"))(
+        static_cast<uint8_t>(SIGHASH_SINGLE), std::string("SINGLE"))(
+        static_cast<uint8_t>(SIGHASH_SINGLE | SIGHASH_ANYONECANPAY),
         std::string("SINGLE|ANYONECANPAY"))(
-        static_cast<unsigned char>(SIGHASH_SINGLE | SIGHASH_FORKID),
+        static_cast<uint8_t>(SIGHASH_SINGLE | SIGHASH_FORKID),
         std::string("SINGLE|FORKID"))(
-        static_cast<unsigned char>(SIGHASH_SINGLE | SIGHASH_FORKID |
-                                   SIGHASH_ANYONECANPAY),
+        static_cast<uint8_t>(SIGHASH_SINGLE | SIGHASH_FORKID |
+                             SIGHASH_ANYONECANPAY),
         std::string("SINGLE|FORKID|ANYONECANPAY"));
 
 /**
  * Create the assembly string representation of a CScript object.
  * @param[in] script    CScript object to convert into the asm string
  * representation.
  * @param[in] fAttemptSighashDecode    Whether to attempt to decode sighash
  * types on data within the script that matches the format of a signature. Only
  * pass true for scripts you believe could contain signatures. For example, pass
  * false, or omit the this argument (defaults to false), for scriptPubKeys.
  */
 std::string ScriptToAsmStr(const CScript &script,
                            const bool fAttemptSighashDecode) {
     std::string str;
     opcodetype opcode;
-    std::vector<unsigned char> vch;
+    std::vector<uint8_t> vch;
     CScript::const_iterator pc = script.begin();
     while (pc < script.end()) {
         if (!str.empty()) {
             str += " ";
         }
 
         if (!script.GetOp(pc, opcode, vch)) {
             str += "[error]";
             return str;
         }
 
         if (0 <= opcode && opcode <= OP_PUSHDATA4) {
-            if (vch.size() <=
-                static_cast<std::vector<unsigned char>::size_type>(4)) {
+            if (vch.size() <= static_cast<std::vector<uint8_t>::size_type>(4)) {
                 str += strprintf("%d", CScriptNum(vch, false).getint());
             } else {
                 // the IsUnspendable check makes sure not to try to decode
                 // OP_RETURN data that may match the format of a signature
                 if (fAttemptSighashDecode && !script.IsUnspendable()) {
                     std::string strSigHashDecode;
                     // goal: only attempt to decode a defined sighash type from
                     // data that looks like a signature within a scriptSig. This
                     // won't decode correctly formatted public keys in Pubkey or
                     // Multisig scripts due to the restrictions on the pubkey
                     // formats (see IsCompressedOrUncompressedPubKey) being
                     // incongruous with the checks in CheckSignatureEncoding.
                     uint32_t flags = SCRIPT_VERIFY_STRICTENC;
                     if (vch.back() & SIGHASH_FORKID) {
                         // If the transaction is using SIGHASH_FORKID, we need
                         // to set the apropriate flag.
                         // TODO: Remove after the Hard Fork.
                         flags |= SCRIPT_ENABLE_SIGHASH_FORKID;
                     }
                     if (CheckSignatureEncoding(vch, flags, nullptr)) {
-                        const unsigned char chSigHashType = vch.back();
+                        const uint8_t chSigHashType = vch.back();
                         if (mapSigHashTypes.count(chSigHashType)) {
                             strSigHashDecode =
                                 "[" +
                                 mapSigHashTypes.find(chSigHashType)->second +
                                 "]";
                             // remove the sighash type byte. it will be replaced
                             // by the decode.
                             vch.pop_back();
                         }
                     }
 
                     str += HexStr(vch) + strSigHashDecode;
                 } else {
                     str += HexStr(vch);
                 }
             }
         } else {
             str += GetOpName(opcode);
         }
     }
 
     return str;
 }
 
 std::string EncodeHexTx(const CTransaction &tx, const int serialFlags) {
     CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION | serialFlags);
     ssTx << tx;
     return HexStr(ssTx.begin(), ssTx.end());
 }
 
 void ScriptPubKeyToUniv(const CScript &scriptPubKey, UniValue &out,
                         bool fIncludeHex) {
     txnouttype type;
     std::vector<CTxDestination> addresses;
     int nRequired;
 
     out.pushKV("asm", ScriptToAsmStr(scriptPubKey));
     if (fIncludeHex) {
         out.pushKV("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end()));
     }
 
     if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) {
         out.pushKV("type", GetTxnOutputType(type));
         return;
     }
 
     out.pushKV("reqSigs", nRequired);
     out.pushKV("type", GetTxnOutputType(type));
 
     UniValue a(UniValue::VARR);
     for (const CTxDestination &addr : addresses) {
         a.push_back(CBitcoinAddress(addr).ToString());
     }
 
     out.pushKV("addresses", a);
 }
 
 void TxToUniv(const CTransaction &tx, const uint256 &hashBlock,
               UniValue &entry) {
     entry.pushKV("txid", tx.GetId().GetHex());
     entry.pushKV("hash", tx.GetHash().GetHex());
     entry.pushKV("version", tx.nVersion);
     entry.pushKV("locktime", (int64_t)tx.nLockTime);
 
     UniValue vin(UniValue::VARR);
     for (unsigned int i = 0; i < tx.vin.size(); i++) {
         const CTxIn &txin = tx.vin[i];
         UniValue in(UniValue::VOBJ);
         if (tx.IsCoinBase()) {
             in.pushKV("coinbase",
                       HexStr(txin.scriptSig.begin(), txin.scriptSig.end()));
         } else {
             in.pushKV("txid", txin.prevout.hash.GetHex());
             in.pushKV("vout", (int64_t)txin.prevout.n);
             UniValue o(UniValue::VOBJ);
             o.pushKV("asm", ScriptToAsmStr(txin.scriptSig, true));
             o.pushKV("hex",
                      HexStr(txin.scriptSig.begin(), txin.scriptSig.end()));
             in.pushKV("scriptSig", o);
         }
 
         in.pushKV("sequence", (int64_t)txin.nSequence);
         vin.push_back(in);
     }
 
     entry.pushKV("vin", vin);
 
     UniValue vout(UniValue::VARR);
     for (unsigned int i = 0; i < tx.vout.size(); i++) {
         const CTxOut &txout = tx.vout[i];
 
         UniValue out(UniValue::VOBJ);
 
         UniValue outValue(UniValue::VNUM, FormatMoney(txout.nValue));
         out.pushKV("value", outValue);
         out.pushKV("n", (int64_t)i);
 
         UniValue o(UniValue::VOBJ);
         ScriptPubKeyToUniv(txout.scriptPubKey, o, true);
         out.pushKV("scriptPubKey", o);
         vout.push_back(out);
     }
 
     entry.pushKV("vout", vout);
 
     if (!hashBlock.IsNull()) {
         entry.pushKV("blockhash", hashBlock.GetHex());
     }
 
     // the hex-encoded transaction. used the name "hex" to be consistent with
     // the verbose output of "getrawtransaction".
     entry.pushKV("hex", EncodeHexTx(tx));
 }
diff --git a/src/crypto/aes.cpp b/src/crypto/aes.cpp
index 513407739..bb0470245 100644
--- a/src/crypto/aes.cpp
+++ b/src/crypto/aes.cpp
@@ -1,205 +1,203 @@
 // Copyright (c) 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.
 
 #include "aes.h"
 #include "crypto/common.h"
 
 #include <cassert>
 #include <cstring>
 
 extern "C" {
 #include "crypto/ctaes/ctaes.c"
 }
 
-AES128Encrypt::AES128Encrypt(const unsigned char key[16]) {
+AES128Encrypt::AES128Encrypt(const uint8_t key[16]) {
     AES128_init(&ctx, key);
 }
 
 AES128Encrypt::~AES128Encrypt() {
     memset(&ctx, 0, sizeof(ctx));
 }
 
-void AES128Encrypt::Encrypt(unsigned char ciphertext[16],
-                            const unsigned char plaintext[16]) const {
+void AES128Encrypt::Encrypt(uint8_t ciphertext[16],
+                            const uint8_t plaintext[16]) const {
     AES128_encrypt(&ctx, 1, ciphertext, plaintext);
 }
 
-AES128Decrypt::AES128Decrypt(const unsigned char key[16]) {
+AES128Decrypt::AES128Decrypt(const uint8_t key[16]) {
     AES128_init(&ctx, key);
 }
 
 AES128Decrypt::~AES128Decrypt() {
     memset(&ctx, 0, sizeof(ctx));
 }
 
-void AES128Decrypt::Decrypt(unsigned char plaintext[16],
-                            const unsigned char ciphertext[16]) const {
+void AES128Decrypt::Decrypt(uint8_t plaintext[16],
+                            const uint8_t ciphertext[16]) const {
     AES128_decrypt(&ctx, 1, plaintext, ciphertext);
 }
 
-AES256Encrypt::AES256Encrypt(const unsigned char key[32]) {
+AES256Encrypt::AES256Encrypt(const uint8_t key[32]) {
     AES256_init(&ctx, key);
 }
 
 AES256Encrypt::~AES256Encrypt() {
     memset(&ctx, 0, sizeof(ctx));
 }
 
-void AES256Encrypt::Encrypt(unsigned char ciphertext[16],
-                            const unsigned char plaintext[16]) const {
+void AES256Encrypt::Encrypt(uint8_t ciphertext[16],
+                            const uint8_t plaintext[16]) const {
     AES256_encrypt(&ctx, 1, ciphertext, plaintext);
 }
 
-AES256Decrypt::AES256Decrypt(const unsigned char key[32]) {
+AES256Decrypt::AES256Decrypt(const uint8_t key[32]) {
     AES256_init(&ctx, key);
 }
 
 AES256Decrypt::~AES256Decrypt() {
     memset(&ctx, 0, sizeof(ctx));
 }
 
-void AES256Decrypt::Decrypt(unsigned char plaintext[16],
-                            const unsigned char ciphertext[16]) const {
+void AES256Decrypt::Decrypt(uint8_t plaintext[16],
+                            const uint8_t ciphertext[16]) const {
     AES256_decrypt(&ctx, 1, plaintext, ciphertext);
 }
 
 template <typename T>
-static int CBCEncrypt(const T &enc, const unsigned char iv[AES_BLOCKSIZE],
-                      const unsigned char *data, int size, bool pad,
-                      unsigned char *out) {
+static int CBCEncrypt(const T &enc, const uint8_t iv[AES_BLOCKSIZE],
+                      const uint8_t *data, int size, bool pad, uint8_t *out) {
     int written = 0;
     int padsize = size % AES_BLOCKSIZE;
-    unsigned char mixed[AES_BLOCKSIZE];
+    uint8_t mixed[AES_BLOCKSIZE];
 
     if (!data || !size || !out) return 0;
 
     if (!pad && padsize != 0) return 0;
 
     memcpy(mixed, iv, AES_BLOCKSIZE);
 
     // Write all but the last block
     while (written + AES_BLOCKSIZE <= size) {
         for (int i = 0; i != AES_BLOCKSIZE; i++)
             mixed[i] ^= *data++;
         enc.Encrypt(out + written, mixed);
         memcpy(mixed, out + written, AES_BLOCKSIZE);
         written += AES_BLOCKSIZE;
     }
     if (pad) {
         // For all that remains, pad each byte with the value of the remaining
         // space. If there is none, pad by a full block.
         for (int i = 0; i != padsize; i++)
             mixed[i] ^= *data++;
         for (int i = padsize; i != AES_BLOCKSIZE; i++)
             mixed[i] ^= AES_BLOCKSIZE - padsize;
         enc.Encrypt(out + written, mixed);
         written += AES_BLOCKSIZE;
     }
     return written;
 }
 
 template <typename T>
-static int CBCDecrypt(const T &dec, const unsigned char iv[AES_BLOCKSIZE],
-                      const unsigned char *data, int size, bool pad,
-                      unsigned char *out) {
-    unsigned char padsize = 0;
+static int CBCDecrypt(const T &dec, const uint8_t iv[AES_BLOCKSIZE],
+                      const uint8_t *data, int size, bool pad, uint8_t *out) {
+    uint8_t padsize = 0;
     int written = 0;
     bool fail = false;
-    const unsigned char *prev = iv;
+    const uint8_t *prev = iv;
 
     if (!data || !size || !out) return 0;
 
     if (size % AES_BLOCKSIZE != 0) return 0;
 
     // Decrypt all data. Padding will be checked in the output.
     while (written != size) {
         dec.Decrypt(out, data + written);
         for (int i = 0; i != AES_BLOCKSIZE; i++)
             *out++ ^= prev[i];
         prev = data + written;
         written += AES_BLOCKSIZE;
     }
 
     // When decrypting padding, attempt to run in constant-time
     if (pad) {
         // If used, padding size is the value of the last decrypted byte. For
         // it to be valid, It must be between 1 and AES_BLOCKSIZE.
         padsize = *--out;
         fail = !padsize | (padsize > AES_BLOCKSIZE);
 
         // If not well-formed, treat it as though there's no padding.
         padsize *= !fail;
 
         // All padding must equal the last byte otherwise it's not well-formed
         for (int i = AES_BLOCKSIZE; i != 0; i--)
             fail |= ((i > AES_BLOCKSIZE - padsize) & (*out-- != padsize));
 
         written -= padsize;
     }
     return written * !fail;
 }
 
-AES256CBCEncrypt::AES256CBCEncrypt(const unsigned char key[AES256_KEYSIZE],
-                                   const unsigned char ivIn[AES_BLOCKSIZE],
+AES256CBCEncrypt::AES256CBCEncrypt(const uint8_t key[AES256_KEYSIZE],
+                                   const uint8_t ivIn[AES_BLOCKSIZE],
                                    bool padIn)
     : enc(key), pad(padIn) {
     memcpy(iv, ivIn, AES_BLOCKSIZE);
 }
 
-int AES256CBCEncrypt::Encrypt(const unsigned char *data, int size,
-                              unsigned char *out) const {
+int AES256CBCEncrypt::Encrypt(const uint8_t *data, int size,
+                              uint8_t *out) const {
     return CBCEncrypt(enc, iv, data, size, pad, out);
 }
 
 AES256CBCEncrypt::~AES256CBCEncrypt() {
     memset(iv, 0, sizeof(iv));
 }
 
-AES256CBCDecrypt::AES256CBCDecrypt(const unsigned char key[AES256_KEYSIZE],
-                                   const unsigned char ivIn[AES_BLOCKSIZE],
+AES256CBCDecrypt::AES256CBCDecrypt(const uint8_t key[AES256_KEYSIZE],
+                                   const uint8_t ivIn[AES_BLOCKSIZE],
                                    bool padIn)
     : dec(key), pad(padIn) {
     memcpy(iv, ivIn, AES_BLOCKSIZE);
 }
 
-int AES256CBCDecrypt::Decrypt(const unsigned char *data, int size,
-                              unsigned char *out) const {
+int AES256CBCDecrypt::Decrypt(const uint8_t *data, int size,
+                              uint8_t *out) const {
     return CBCDecrypt(dec, iv, data, size, pad, out);
 }
 
 AES256CBCDecrypt::~AES256CBCDecrypt() {
     memset(iv, 0, sizeof(iv));
 }
 
-AES128CBCEncrypt::AES128CBCEncrypt(const unsigned char key[AES128_KEYSIZE],
-                                   const unsigned char ivIn[AES_BLOCKSIZE],
+AES128CBCEncrypt::AES128CBCEncrypt(const uint8_t key[AES128_KEYSIZE],
+                                   const uint8_t ivIn[AES_BLOCKSIZE],
                                    bool padIn)
     : enc(key), pad(padIn) {
     memcpy(iv, ivIn, AES_BLOCKSIZE);
 }
 
 AES128CBCEncrypt::~AES128CBCEncrypt() {
     memset(iv, 0, AES_BLOCKSIZE);
 }
 
-int AES128CBCEncrypt::Encrypt(const unsigned char *data, int size,
-                              unsigned char *out) const {
+int AES128CBCEncrypt::Encrypt(const uint8_t *data, int size,
+                              uint8_t *out) const {
     return CBCEncrypt(enc, iv, data, size, pad, out);
 }
 
-AES128CBCDecrypt::AES128CBCDecrypt(const unsigned char key[AES128_KEYSIZE],
-                                   const unsigned char ivIn[AES_BLOCKSIZE],
+AES128CBCDecrypt::AES128CBCDecrypt(const uint8_t key[AES128_KEYSIZE],
+                                   const uint8_t ivIn[AES_BLOCKSIZE],
                                    bool padIn)
     : dec(key), pad(padIn) {
     memcpy(iv, ivIn, AES_BLOCKSIZE);
 }
 
 AES128CBCDecrypt::~AES128CBCDecrypt() {
     memset(iv, 0, AES_BLOCKSIZE);
 }
 
-int AES128CBCDecrypt::Decrypt(const unsigned char *data, int size,
-                              unsigned char *out) const {
+int AES128CBCDecrypt::Decrypt(const uint8_t *data, int size,
+                              uint8_t *out) const {
     return CBCDecrypt(dec, iv, data, size, pad, out);
 }
diff --git a/src/crypto/aes.h b/src/crypto/aes.h
index 7d209dee8..08ec2b795 100644
--- a/src/crypto/aes.h
+++ b/src/crypto/aes.h
@@ -1,118 +1,114 @@
 // Copyright (c) 2015-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.
 //
 // C++ wrapper around ctaes, a constant-time AES implementation
 
 #ifndef BITCOIN_CRYPTO_AES_H
 #define BITCOIN_CRYPTO_AES_H
 
 extern "C" {
 #include "crypto/ctaes/ctaes.h"
 }
 
 static const int AES_BLOCKSIZE = 16;
 static const int AES128_KEYSIZE = 16;
 static const int AES256_KEYSIZE = 32;
 
 /** An encryption class for AES-128. */
 class AES128Encrypt {
 private:
     AES128_ctx ctx;
 
 public:
-    AES128Encrypt(const unsigned char key[16]);
+    AES128Encrypt(const uint8_t key[16]);
     ~AES128Encrypt();
-    void Encrypt(unsigned char ciphertext[16],
-                 const unsigned char plaintext[16]) const;
+    void Encrypt(uint8_t ciphertext[16], const uint8_t plaintext[16]) const;
 };
 
 /** A decryption class for AES-128. */
 class AES128Decrypt {
 private:
     AES128_ctx ctx;
 
 public:
-    AES128Decrypt(const unsigned char key[16]);
+    AES128Decrypt(const uint8_t key[16]);
     ~AES128Decrypt();
-    void Decrypt(unsigned char plaintext[16],
-                 const unsigned char ciphertext[16]) const;
+    void Decrypt(uint8_t plaintext[16], const uint8_t ciphertext[16]) const;
 };
 
 /** An encryption class for AES-256. */
 class AES256Encrypt {
 private:
     AES256_ctx ctx;
 
 public:
-    AES256Encrypt(const unsigned char key[32]);
+    AES256Encrypt(const uint8_t key[32]);
     ~AES256Encrypt();
-    void Encrypt(unsigned char ciphertext[16],
-                 const unsigned char plaintext[16]) const;
+    void Encrypt(uint8_t ciphertext[16], const uint8_t plaintext[16]) const;
 };
 
 /** A decryption class for AES-256. */
 class AES256Decrypt {
 private:
     AES256_ctx ctx;
 
 public:
-    AES256Decrypt(const unsigned char key[32]);
+    AES256Decrypt(const uint8_t key[32]);
     ~AES256Decrypt();
-    void Decrypt(unsigned char plaintext[16],
-                 const unsigned char ciphertext[16]) const;
+    void Decrypt(uint8_t plaintext[16], const uint8_t ciphertext[16]) const;
 };
 
 class AES256CBCEncrypt {
 public:
-    AES256CBCEncrypt(const unsigned char key[AES256_KEYSIZE],
-                     const unsigned char ivIn[AES_BLOCKSIZE], bool padIn);
+    AES256CBCEncrypt(const uint8_t key[AES256_KEYSIZE],
+                     const uint8_t ivIn[AES_BLOCKSIZE], bool padIn);
     ~AES256CBCEncrypt();
-    int Encrypt(const unsigned char *data, int size, unsigned char *out) const;
+    int Encrypt(const uint8_t *data, int size, uint8_t *out) const;
 
 private:
     const AES256Encrypt enc;
     const bool pad;
-    unsigned char iv[AES_BLOCKSIZE];
+    uint8_t iv[AES_BLOCKSIZE];
 };
 
 class AES256CBCDecrypt {
 public:
-    AES256CBCDecrypt(const unsigned char key[AES256_KEYSIZE],
-                     const unsigned char ivIn[AES_BLOCKSIZE], bool padIn);
+    AES256CBCDecrypt(const uint8_t key[AES256_KEYSIZE],
+                     const uint8_t ivIn[AES_BLOCKSIZE], bool padIn);
     ~AES256CBCDecrypt();
-    int Decrypt(const unsigned char *data, int size, unsigned char *out) const;
+    int Decrypt(const uint8_t *data, int size, uint8_t *out) const;
 
 private:
     const AES256Decrypt dec;
     const bool pad;
-    unsigned char iv[AES_BLOCKSIZE];
+    uint8_t iv[AES_BLOCKSIZE];
 };
 
 class AES128CBCEncrypt {
 public:
-    AES128CBCEncrypt(const unsigned char key[AES128_KEYSIZE],
-                     const unsigned char ivIn[AES_BLOCKSIZE], bool padIn);
+    AES128CBCEncrypt(const uint8_t key[AES128_KEYSIZE],
+                     const uint8_t ivIn[AES_BLOCKSIZE], bool padIn);
     ~AES128CBCEncrypt();
-    int Encrypt(const unsigned char *data, int size, unsigned char *out) const;
+    int Encrypt(const uint8_t *data, int size, uint8_t *out) const;
 
 private:
     const AES128Encrypt enc;
     const bool pad;
-    unsigned char iv[AES_BLOCKSIZE];
+    uint8_t iv[AES_BLOCKSIZE];
 };
 
 class AES128CBCDecrypt {
 public:
-    AES128CBCDecrypt(const unsigned char key[AES128_KEYSIZE],
-                     const unsigned char ivIn[AES_BLOCKSIZE], bool padIn);
+    AES128CBCDecrypt(const uint8_t key[AES128_KEYSIZE],
+                     const uint8_t ivIn[AES_BLOCKSIZE], bool padIn);
     ~AES128CBCDecrypt();
-    int Decrypt(const unsigned char *data, int size, unsigned char *out) const;
+    int Decrypt(const uint8_t *data, int size, uint8_t *out) const;
 
 private:
     const AES128Decrypt dec;
     const bool pad;
-    unsigned char iv[AES_BLOCKSIZE];
+    uint8_t iv[AES_BLOCKSIZE];
 };
 
 #endif // BITCOIN_CRYPTO_AES_H
diff --git a/src/crypto/common.h b/src/crypto/common.h
index 355bd39d3..07d103836 100644
--- a/src/crypto/common.h
+++ b/src/crypto/common.h
@@ -1,72 +1,72 @@
 // Copyright (c) 2014 The Bitcoin Core developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #ifndef BITCOIN_CRYPTO_COMMON_H
 #define BITCOIN_CRYPTO_COMMON_H
 
 #if defined(HAVE_CONFIG_H)
 #include "bitcoin-config.h"
 #endif
 
 #include <cstdint>
 #include <cstring>
 
 #include "compat/endian.h"
 
-static inline uint16_t ReadLE16(const unsigned char *ptr) {
+static inline uint16_t ReadLE16(const uint8_t *ptr) {
     uint16_t x;
     memcpy((char *)&x, ptr, 2);
     return le16toh(x);
 }
 
-static inline uint32_t ReadLE32(const unsigned char *ptr) {
+static inline uint32_t ReadLE32(const uint8_t *ptr) {
     uint32_t x;
     memcpy((char *)&x, ptr, 4);
     return le32toh(x);
 }
 
-static inline uint64_t ReadLE64(const unsigned char *ptr) {
+static inline uint64_t ReadLE64(const uint8_t *ptr) {
     uint64_t x;
     memcpy((char *)&x, ptr, 8);
     return le64toh(x);
 }
 
-static inline void WriteLE16(unsigned char *ptr, uint16_t x) {
+static inline void WriteLE16(uint8_t *ptr, uint16_t x) {
     uint16_t v = htole16(x);
     memcpy(ptr, (char *)&v, 2);
 }
 
-static inline void WriteLE32(unsigned char *ptr, uint32_t x) {
+static inline void WriteLE32(uint8_t *ptr, uint32_t x) {
     uint32_t v = htole32(x);
     memcpy(ptr, (char *)&v, 4);
 }
 
-static inline void WriteLE64(unsigned char *ptr, uint64_t x) {
+static inline void WriteLE64(uint8_t *ptr, uint64_t x) {
     uint64_t v = htole64(x);
     memcpy(ptr, (char *)&v, 8);
 }
 
-static inline uint32_t ReadBE32(const unsigned char *ptr) {
+static inline uint32_t ReadBE32(const uint8_t *ptr) {
     uint32_t x;
     memcpy((char *)&x, ptr, 4);
     return be32toh(x);
 }
 
-static inline uint64_t ReadBE64(const unsigned char *ptr) {
+static inline uint64_t ReadBE64(const uint8_t *ptr) {
     uint64_t x;
     memcpy((char *)&x, ptr, 8);
     return be64toh(x);
 }
 
-static inline void WriteBE32(unsigned char *ptr, uint32_t x) {
+static inline void WriteBE32(uint8_t *ptr, uint32_t x) {
     uint32_t v = htobe32(x);
     memcpy(ptr, (char *)&v, 4);
 }
 
-static inline void WriteBE64(unsigned char *ptr, uint64_t x) {
+static inline void WriteBE64(uint8_t *ptr, uint64_t x) {
     uint64_t v = htobe64(x);
     memcpy(ptr, (char *)&v, 8);
 }
 
 #endif // BITCOIN_CRYPTO_COMMON_H
diff --git a/src/crypto/ctaes/bench.c b/src/crypto/ctaes/bench.c
index 5a1fd1446..c4a6d3528 100644
--- a/src/crypto/ctaes/bench.c
+++ b/src/crypto/ctaes/bench.c
@@ -1,180 +1,180 @@
 #include "sys/time.h"
 #include <math.h>
 #include <stdio.h>
 
 #include "ctaes.h"
 
 static double gettimedouble(void) {
     struct timeval tv;
     gettimeofday(&tv, NULL);
     return tv.tv_usec * 0.000001 + tv.tv_sec;
 }
 
 static void print_number(double x) {
     double y = x;
     int c = 0;
     if (y < 0.0) {
         y = -y;
     }
     while (y < 100.0) {
         y *= 10.0;
         c++;
     }
     printf("%.*f", c, x);
 }
 
 static void run_benchmark(char *name, void (*benchmark)(void *),
                           void (*setup)(void *), void (*teardown)(void *),
                           void *data, int count, int iter) {
     int i;
     double min = HUGE_VAL;
     double sum = 0.0;
     double max = 0.0;
     for (i = 0; i < count; i++) {
         double begin, total;
         if (setup != NULL) {
             setup(data);
         }
         begin = gettimedouble();
         benchmark(data);
         total = gettimedouble() - begin;
         if (teardown != NULL) {
             teardown(data);
         }
         if (total < min) {
             min = total;
         }
         if (total > max) {
             max = total;
         }
         sum += total;
     }
     printf("%s: min ", name);
     print_number(min * 1000000000.0 / iter);
     printf("ns / avg ");
     print_number((sum / count) * 1000000000.0 / iter);
     printf("ns / max ");
     print_number(max * 1000000000.0 / iter);
     printf("ns\n");
 }
 
 static void bench_AES128_init(void *data) {
     AES128_ctx *ctx = (AES128_ctx *)data;
     int i;
     for (i = 0; i < 50000; i++) {
-        AES128_init(ctx, (unsigned char *)ctx);
+        AES128_init(ctx, (uint8_t *)ctx);
     }
 }
 
 static void bench_AES128_encrypt_setup(void *data) {
     AES128_ctx *ctx = (AES128_ctx *)data;
-    static const unsigned char key[16] = {0};
+    static const uint8_t key[16] = {0};
     AES128_init(ctx, key);
 }
 
 static void bench_AES128_encrypt(void *data) {
     const AES128_ctx *ctx = (const AES128_ctx *)data;
-    unsigned char scratch[16] = {0};
+    uint8_t scratch[16] = {0};
     int i;
     for (i = 0; i < 4000000 / 16; i++) {
         AES128_encrypt(ctx, 1, scratch, scratch);
     }
 }
 
 static void bench_AES128_decrypt(void *data) {
     const AES128_ctx *ctx = (const AES128_ctx *)data;
-    unsigned char scratch[16] = {0};
+    uint8_t scratch[16] = {0};
     int i;
     for (i = 0; i < 4000000 / 16; i++) {
         AES128_decrypt(ctx, 1, scratch, scratch);
     }
 }
 
 static void bench_AES192_init(void *data) {
     AES192_ctx *ctx = (AES192_ctx *)data;
     int i;
     for (i = 0; i < 50000; i++) {
-        AES192_init(ctx, (unsigned char *)ctx);
+        AES192_init(ctx, (uint8_t *)ctx);
     }
 }
 
 static void bench_AES192_encrypt_setup(void *data) {
     AES192_ctx *ctx = (AES192_ctx *)data;
-    static const unsigned char key[16] = {0};
+    static const uint8_t key[16] = {0};
     AES192_init(ctx, key);
 }
 
 static void bench_AES192_encrypt(void *data) {
     const AES192_ctx *ctx = (const AES192_ctx *)data;
-    unsigned char scratch[16] = {0};
+    uint8_t scratch[16] = {0};
     int i;
     for (i = 0; i < 4000000 / 16; i++) {
         AES192_encrypt(ctx, 1, scratch, scratch);
     }
 }
 
 static void bench_AES192_decrypt(void *data) {
     const AES192_ctx *ctx = (const AES192_ctx *)data;
-    unsigned char scratch[16] = {0};
+    uint8_t scratch[16] = {0};
     int i;
     for (i = 0; i < 4000000 / 16; i++) {
         AES192_decrypt(ctx, 1, scratch, scratch);
     }
 }
 
 static void bench_AES256_init(void *data) {
     AES256_ctx *ctx = (AES256_ctx *)data;
     int i;
     for (i = 0; i < 50000; i++) {
-        AES256_init(ctx, (unsigned char *)ctx);
+        AES256_init(ctx, (uint8_t *)ctx);
     }
 }
 
 static void bench_AES256_encrypt_setup(void *data) {
     AES256_ctx *ctx = (AES256_ctx *)data;
-    static const unsigned char key[16] = {0};
+    static const uint8_t key[16] = {0};
     AES256_init(ctx, key);
 }
 
 static void bench_AES256_encrypt(void *data) {
     const AES256_ctx *ctx = (const AES256_ctx *)data;
-    unsigned char scratch[16] = {0};
+    uint8_t scratch[16] = {0};
     int i;
     for (i = 0; i < 4000000 / 16; i++) {
         AES256_encrypt(ctx, 1, scratch, scratch);
     }
 }
 
 static void bench_AES256_decrypt(void *data) {
     const AES256_ctx *ctx = (const AES256_ctx *)data;
-    unsigned char scratch[16] = {0};
+    uint8_t scratch[16] = {0};
     int i;
     for (i = 0; i < 4000000 / 16; i++) {
         AES256_decrypt(ctx, 1, scratch, scratch);
     }
 }
 
 int main(void) {
     AES128_ctx ctx128;
     AES192_ctx ctx192;
     AES256_ctx ctx256;
     run_benchmark("aes128_init", bench_AES128_init, NULL, NULL, &ctx128, 20,
                   50000);
     run_benchmark("aes128_encrypt_byte", bench_AES128_encrypt,
                   bench_AES128_encrypt_setup, NULL, &ctx128, 20, 4000000);
     run_benchmark("aes128_decrypt_byte", bench_AES128_decrypt,
                   bench_AES128_encrypt_setup, NULL, &ctx128, 20, 4000000);
     run_benchmark("aes192_init", bench_AES192_init, NULL, NULL, &ctx192, 20,
                   50000);
     run_benchmark("aes192_encrypt_byte", bench_AES192_encrypt,
                   bench_AES192_encrypt_setup, NULL, &ctx192, 20, 4000000);
     run_benchmark("aes192_decrypt_byte", bench_AES192_decrypt,
                   bench_AES192_encrypt_setup, NULL, &ctx192, 20, 4000000);
     run_benchmark("aes256_init", bench_AES256_init, NULL, NULL, &ctx256, 20,
                   50000);
     run_benchmark("aes256_encrypt_byte", bench_AES256_encrypt,
                   bench_AES256_encrypt_setup, NULL, &ctx256, 20, 4000000);
     run_benchmark("aes256_decrypt_byte", bench_AES256_decrypt,
                   bench_AES256_encrypt_setup, NULL, &ctx256, 20, 4000000);
     return 0;
 }
diff --git a/src/crypto/ctaes/ctaes.c b/src/crypto/ctaes/ctaes.c
index 1831f19a0..aafcb8470 100644
--- a/src/crypto/ctaes/ctaes.c
+++ b/src/crypto/ctaes/ctaes.c
@@ -1,582 +1,582 @@
 /*********************************************************************
 * Copyright (c) 2016 Pieter Wuille                                   *
 * Distributed under the MIT software license, see the accompanying   *
 * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
 **********************************************************************/
 
 /* Constant time, unoptimized, concise, plain C, AES implementation
  * Based On:
  *   Emilia Kasper and Peter Schwabe, Faster and Timing-Attack Resistant AES-GCM
  *   http://www.iacr.org/archive/ches2009/57470001/57470001.pdf
  * But using 8 16-bit integers representing a single AES state rather than 8
  * 128-bit integers representing 8 AES states.
  */
 
 #include "ctaes.h"
 
 /* Slice variable slice_i contains the i'th bit of the 16 state variables in
  * this order:
  *  0  1  2  3
  *  4  5  6  7
  *  8  9 10 11
  * 12 13 14 15
  */
 
 /**
  * Convert a byte to sliced form, storing it corresponding to given row and
  * column in s.
  */
-static void LoadByte(AES_state *s, unsigned char byte, int r, int c) {
+static void LoadByte(AES_state *s, uint8_t byte, int r, int c) {
     int i;
     for (i = 0; i < 8; i++) {
         s->slice[i] |= (byte & 1) << (r * 4 + c);
         byte >>= 1;
     }
 }
 
 /** Load 16 bytes of data into 8 sliced integers */
-static void LoadBytes(AES_state *s, const unsigned char *data16) {
+static void LoadBytes(AES_state *s, const uint8_t *data16) {
     int c;
     for (c = 0; c < 4; c++) {
         int r;
         for (r = 0; r < 4; r++) {
             LoadByte(s, *(data16++), r, c);
         }
     }
 }
 
 /** Convert 8 sliced integers into 16 bytes of data */
-static void SaveBytes(unsigned char *data16, const AES_state *s) {
+static void SaveBytes(uint8_t *data16, const AES_state *s) {
     int c;
     for (c = 0; c < 4; c++) {
         int r;
         for (r = 0; r < 4; r++) {
             int b;
             uint8_t v = 0;
             for (b = 0; b < 8; b++) {
                 v |= ((s->slice[b] >> (r * 4 + c)) & 1) << b;
             }
             *(data16++) = v;
         }
     }
 }
 
 /* S-box implementation based on the gate logic from:
  *   Joan Boyar and Rene Peralta, A depth-16 circuit for the AES S-box.
  *   https://eprint.iacr.org/2011/332.pdf
  */
 static void SubBytes(AES_state *s, int inv) {
     /* Load the bit slices */
     uint16_t U0 = s->slice[7], U1 = s->slice[6], U2 = s->slice[5],
              U3 = s->slice[4];
     uint16_t U4 = s->slice[3], U5 = s->slice[2], U6 = s->slice[1],
              U7 = s->slice[0];
 
     uint16_t T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
         T16;
     uint16_t T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, D;
     uint16_t M1, M6, M11, M13, M15, M20, M21, M22, M23, M25, M37, M38, M39, M40;
     uint16_t M41, M42, M43, M44, M45, M46, M47, M48, M49, M50, M51, M52, M53,
         M54;
     uint16_t M55, M56, M57, M58, M59, M60, M61, M62, M63;
 
     if (inv) {
         uint16_t R5, R13, R17, R18, R19;
         /* Undo linear postprocessing */
         T23 = U0 ^ U3;
         T22 = ~(U1 ^ U3);
         T2 = ~(U0 ^ U1);
         T1 = U3 ^ U4;
         T24 = ~(U4 ^ U7);
         R5 = U6 ^ U7;
         T8 = ~(U1 ^ T23);
         T19 = T22 ^ R5;
         T9 = ~(U7 ^ T1);
         T10 = T2 ^ T24;
         T13 = T2 ^ R5;
         T3 = T1 ^ R5;
         T25 = ~(U2 ^ T1);
         R13 = U1 ^ U6;
         T17 = ~(U2 ^ T19);
         T20 = T24 ^ R13;
         T4 = U4 ^ T8;
         R17 = ~(U2 ^ U5);
         R18 = ~(U5 ^ U6);
         R19 = ~(U2 ^ U4);
         D = U0 ^ R17;
         T6 = T22 ^ R17;
         T16 = R13 ^ R19;
         T27 = T1 ^ R18;
         T15 = T10 ^ T27;
         T14 = T10 ^ R18;
         T26 = T3 ^ T16;
     } else {
         /* Linear preprocessing. */
         T1 = U0 ^ U3;
         T2 = U0 ^ U5;
         T3 = U0 ^ U6;
         T4 = U3 ^ U5;
         T5 = U4 ^ U6;
         T6 = T1 ^ T5;
         T7 = U1 ^ U2;
         T8 = U7 ^ T6;
         T9 = U7 ^ T7;
         T10 = T6 ^ T7;
         T11 = U1 ^ U5;
         T12 = U2 ^ U5;
         T13 = T3 ^ T4;
         T14 = T6 ^ T11;
         T15 = T5 ^ T11;
         T16 = T5 ^ T12;
         T17 = T9 ^ T16;
         T18 = U3 ^ U7;
         T19 = T7 ^ T18;
         T20 = T1 ^ T19;
         T21 = U6 ^ U7;
         T22 = T7 ^ T21;
         T23 = T2 ^ T22;
         T24 = T2 ^ T10;
         T25 = T20 ^ T17;
         T26 = T3 ^ T16;
         T27 = T1 ^ T12;
         D = U7;
     }
 
     /* Non-linear transformation (shared between the forward and backward case)
      */
     M1 = T13 & T6;
     M6 = T3 & T16;
     M11 = T1 & T15;
     M13 = (T4 & T27) ^ M11;
     M15 = (T2 & T10) ^ M11;
     M20 = T14 ^ M1 ^ (T23 & T8) ^ M13;
     M21 = (T19 & D) ^ M1 ^ T24 ^ M15;
     M22 = T26 ^ M6 ^ (T22 & T9) ^ M13;
     M23 = (T20 & T17) ^ M6 ^ M15 ^ T25;
     M25 = M22 & M20;
     M37 = M21 ^ ((M20 ^ M21) & (M23 ^ M25));
     M38 = M20 ^ M25 ^ (M21 | (M20 & M23));
     M39 = M23 ^ ((M22 ^ M23) & (M21 ^ M25));
     M40 = M22 ^ M25 ^ (M23 | (M21 & M22));
     M41 = M38 ^ M40;
     M42 = M37 ^ M39;
     M43 = M37 ^ M38;
     M44 = M39 ^ M40;
     M45 = M42 ^ M41;
     M46 = M44 & T6;
     M47 = M40 & T8;
     M48 = M39 & D;
     M49 = M43 & T16;
     M50 = M38 & T9;
     M51 = M37 & T17;
     M52 = M42 & T15;
     M53 = M45 & T27;
     M54 = M41 & T10;
     M55 = M44 & T13;
     M56 = M40 & T23;
     M57 = M39 & T19;
     M58 = M43 & T3;
     M59 = M38 & T22;
     M60 = M37 & T20;
     M61 = M42 & T1;
     M62 = M45 & T4;
     M63 = M41 & T2;
 
     if (inv) {
         /* Undo linear preprocessing */
         uint16_t P0 = M52 ^ M61;
         uint16_t P1 = M58 ^ M59;
         uint16_t P2 = M54 ^ M62;
         uint16_t P3 = M47 ^ M50;
         uint16_t P4 = M48 ^ M56;
         uint16_t P5 = M46 ^ M51;
         uint16_t P6 = M49 ^ M60;
         uint16_t P7 = P0 ^ P1;
         uint16_t P8 = M50 ^ M53;
         uint16_t P9 = M55 ^ M63;
         uint16_t P10 = M57 ^ P4;
         uint16_t P11 = P0 ^ P3;
         uint16_t P12 = M46 ^ M48;
         uint16_t P13 = M49 ^ M51;
         uint16_t P14 = M49 ^ M62;
         uint16_t P15 = M54 ^ M59;
         uint16_t P16 = M57 ^ M61;
         uint16_t P17 = M58 ^ P2;
         uint16_t P18 = M63 ^ P5;
         uint16_t P19 = P2 ^ P3;
         uint16_t P20 = P4 ^ P6;
         uint16_t P22 = P2 ^ P7;
         uint16_t P23 = P7 ^ P8;
         uint16_t P24 = P5 ^ P7;
         uint16_t P25 = P6 ^ P10;
         uint16_t P26 = P9 ^ P11;
         uint16_t P27 = P10 ^ P18;
         uint16_t P28 = P11 ^ P25;
         uint16_t P29 = P15 ^ P20;
         s->slice[7] = P13 ^ P22;
         s->slice[6] = P26 ^ P29;
         s->slice[5] = P17 ^ P28;
         s->slice[4] = P12 ^ P22;
         s->slice[3] = P23 ^ P27;
         s->slice[2] = P19 ^ P24;
         s->slice[1] = P14 ^ P23;
         s->slice[0] = P9 ^ P16;
     } else {
         /* Linear postprocessing */
         uint16_t L0 = M61 ^ M62;
         uint16_t L1 = M50 ^ M56;
         uint16_t L2 = M46 ^ M48;
         uint16_t L3 = M47 ^ M55;
         uint16_t L4 = M54 ^ M58;
         uint16_t L5 = M49 ^ M61;
         uint16_t L6 = M62 ^ L5;
         uint16_t L7 = M46 ^ L3;
         uint16_t L8 = M51 ^ M59;
         uint16_t L9 = M52 ^ M53;
         uint16_t L10 = M53 ^ L4;
         uint16_t L11 = M60 ^ L2;
         uint16_t L12 = M48 ^ M51;
         uint16_t L13 = M50 ^ L0;
         uint16_t L14 = M52 ^ M61;
         uint16_t L15 = M55 ^ L1;
         uint16_t L16 = M56 ^ L0;
         uint16_t L17 = M57 ^ L1;
         uint16_t L18 = M58 ^ L8;
         uint16_t L19 = M63 ^ L4;
         uint16_t L20 = L0 ^ L1;
         uint16_t L21 = L1 ^ L7;
         uint16_t L22 = L3 ^ L12;
         uint16_t L23 = L18 ^ L2;
         uint16_t L24 = L15 ^ L9;
         uint16_t L25 = L6 ^ L10;
         uint16_t L26 = L7 ^ L9;
         uint16_t L27 = L8 ^ L10;
         uint16_t L28 = L11 ^ L14;
         uint16_t L29 = L11 ^ L17;
         s->slice[7] = L6 ^ L24;
         s->slice[6] = ~(L16 ^ L26);
         s->slice[5] = ~(L19 ^ L28);
         s->slice[4] = L6 ^ L21;
         s->slice[3] = L20 ^ L22;
         s->slice[2] = L25 ^ L29;
         s->slice[1] = ~(L13 ^ L27);
         s->slice[0] = ~(L6 ^ L23);
     }
 }
 
 #define BIT_RANGE(from, to) (((1 << ((to) - (from))) - 1) << (from))
 
 #define BIT_RANGE_LEFT(x, from, to, shift)                                     \
     (((x)&BIT_RANGE((from), (to))) << (shift))
 #define BIT_RANGE_RIGHT(x, from, to, shift)                                    \
     (((x)&BIT_RANGE((from), (to))) >> (shift))
 
 static void ShiftRows(AES_state *s) {
     int i;
     for (i = 0; i < 8; i++) {
         uint16_t v = s->slice[i];
         s->slice[i] =
             (v & BIT_RANGE(0, 4)) | BIT_RANGE_LEFT(v, 4, 5, 3) |
             BIT_RANGE_RIGHT(v, 5, 8, 1) | BIT_RANGE_LEFT(v, 8, 10, 2) |
             BIT_RANGE_RIGHT(v, 10, 12, 2) | BIT_RANGE_LEFT(v, 12, 15, 1) |
             BIT_RANGE_RIGHT(v, 15, 16, 3);
     }
 }
 
 static void InvShiftRows(AES_state *s) {
     int i;
     for (i = 0; i < 8; i++) {
         uint16_t v = s->slice[i];
         s->slice[i] =
             (v & BIT_RANGE(0, 4)) | BIT_RANGE_LEFT(v, 4, 7, 1) |
             BIT_RANGE_RIGHT(v, 7, 8, 3) | BIT_RANGE_LEFT(v, 8, 10, 2) |
             BIT_RANGE_RIGHT(v, 10, 12, 2) | BIT_RANGE_LEFT(v, 12, 13, 3) |
             BIT_RANGE_RIGHT(v, 13, 16, 1);
     }
 }
 
 #define ROT(x, b) (((x) >> ((b)*4)) | ((x) << ((4 - (b)) * 4)))
 
 static void MixColumns(AES_state *s, int inv) {
     /* The MixColumns transform treats the bytes of the columns of the state as
      * coefficients of a 3rd degree polynomial over GF(2^8) and multiplies them
      * by the fixed polynomial a(x) = {03}x^3 + {01}x^2 + {01}x + {02}, modulo
      * x^4 + {01}.
      *
      * In the inverse transform, we multiply by the inverse of a(x),
      * a^-1(x) = {0b}x^3 + {0d}x^2 + {09}x + {0e}. This is equal to
      * a(x) * ({04}x^2 + {05}), so we can reuse the forward transform's code
      * (found in OpenSSL's bsaes-x86_64.pl, attributed to Jussi Kivilinna)
      *
      * In the bitsliced representation, a multiplication of every column by x
      * mod x^4 + 1 is simply a right rotation.
      */
 
     /* Shared for both directions is a multiplication by a(x), which can be
      * rewritten as (x^3 + x^2 + x) + {02}*(x^3 + {01}).
      *
      * First compute s into the s? variables, (x^3 + {01}) * s into the s?_01
      * variables and (x^3 + x^2 + x)*s into the s?_123 variables.
      */
     uint16_t s0 = s->slice[0], s1 = s->slice[1], s2 = s->slice[2],
              s3 = s->slice[3];
     uint16_t s4 = s->slice[4], s5 = s->slice[5], s6 = s->slice[6],
              s7 = s->slice[7];
     uint16_t s0_01 = s0 ^ ROT(s0, 1), s0_123 = ROT(s0_01, 1) ^ ROT(s0, 3);
     uint16_t s1_01 = s1 ^ ROT(s1, 1), s1_123 = ROT(s1_01, 1) ^ ROT(s1, 3);
     uint16_t s2_01 = s2 ^ ROT(s2, 1), s2_123 = ROT(s2_01, 1) ^ ROT(s2, 3);
     uint16_t s3_01 = s3 ^ ROT(s3, 1), s3_123 = ROT(s3_01, 1) ^ ROT(s3, 3);
     uint16_t s4_01 = s4 ^ ROT(s4, 1), s4_123 = ROT(s4_01, 1) ^ ROT(s4, 3);
     uint16_t s5_01 = s5 ^ ROT(s5, 1), s5_123 = ROT(s5_01, 1) ^ ROT(s5, 3);
     uint16_t s6_01 = s6 ^ ROT(s6, 1), s6_123 = ROT(s6_01, 1) ^ ROT(s6, 3);
     uint16_t s7_01 = s7 ^ ROT(s7, 1), s7_123 = ROT(s7_01, 1) ^ ROT(s7, 3);
     /* Now compute s = s?_123 + {02} * s?_01. */
     s->slice[0] = s7_01 ^ s0_123;
     s->slice[1] = s7_01 ^ s0_01 ^ s1_123;
     s->slice[2] = s1_01 ^ s2_123;
     s->slice[3] = s7_01 ^ s2_01 ^ s3_123;
     s->slice[4] = s7_01 ^ s3_01 ^ s4_123;
     s->slice[5] = s4_01 ^ s5_123;
     s->slice[6] = s5_01 ^ s6_123;
     s->slice[7] = s6_01 ^ s7_123;
     if (inv) {
         /* In the reverse direction, we further need to multiply by
          * {04}x^2 + {05}, which can be written as {04} * (x^2 + {01}) + {01}.
          *
          * First compute (x^2 + {01}) * s into the t?_02 variables: */
         uint16_t t0_02 = s->slice[0] ^ ROT(s->slice[0], 2);
         uint16_t t1_02 = s->slice[1] ^ ROT(s->slice[1], 2);
         uint16_t t2_02 = s->slice[2] ^ ROT(s->slice[2], 2);
         uint16_t t3_02 = s->slice[3] ^ ROT(s->slice[3], 2);
         uint16_t t4_02 = s->slice[4] ^ ROT(s->slice[4], 2);
         uint16_t t5_02 = s->slice[5] ^ ROT(s->slice[5], 2);
         uint16_t t6_02 = s->slice[6] ^ ROT(s->slice[6], 2);
         uint16_t t7_02 = s->slice[7] ^ ROT(s->slice[7], 2);
         /* And then update s += {04} * t?_02 */
         s->slice[0] ^= t6_02;
         s->slice[1] ^= t6_02 ^ t7_02;
         s->slice[2] ^= t0_02 ^ t7_02;
         s->slice[3] ^= t1_02 ^ t6_02;
         s->slice[4] ^= t2_02 ^ t6_02 ^ t7_02;
         s->slice[5] ^= t3_02 ^ t7_02;
         s->slice[6] ^= t4_02;
         s->slice[7] ^= t5_02;
     }
 }
 
 static void AddRoundKey(AES_state *s, const AES_state *round) {
     int b;
     for (b = 0; b < 8; b++) {
         s->slice[b] ^= round->slice[b];
     }
 }
 
 /** column_0(s) = column_c(a) */
 static void GetOneColumn(AES_state *s, const AES_state *a, int c) {
     int b;
     for (b = 0; b < 8; b++) {
         s->slice[b] = (a->slice[b] >> c) & 0x1111;
     }
 }
 
 /** column_c1(r) |= (column_0(s) ^= column_c2(a)) */
 static void KeySetupColumnMix(AES_state *s, AES_state *r, const AES_state *a,
                               int c1, int c2) {
     int b;
     for (b = 0; b < 8; b++) {
         r->slice[b] |=
             ((s->slice[b] ^= ((a->slice[b] >> c2) & 0x1111)) & 0x1111) << c1;
     }
 }
 
 /** Rotate the rows in s one position upwards, and xor in r */
 static void KeySetupTransform(AES_state *s, const AES_state *r) {
     int b;
     for (b = 0; b < 8; b++) {
         s->slice[b] = ((s->slice[b] >> 4) | (s->slice[b] << 12)) ^ r->slice[b];
     }
 }
 
 /* Multiply the cells in s by x, as polynomials over GF(2) mod x^8 + x^4 + x^3 +
  * x + 1 */
 static void MultX(AES_state *s) {
     uint16_t top = s->slice[7];
     s->slice[7] = s->slice[6];
     s->slice[6] = s->slice[5];
     s->slice[5] = s->slice[4];
     s->slice[4] = s->slice[3] ^ top;
     s->slice[3] = s->slice[2] ^ top;
     s->slice[2] = s->slice[1];
     s->slice[1] = s->slice[0] ^ top;
     s->slice[0] = top;
 }
 
 /** Expand the cipher key into the key schedule.
  *
  *  state must be a pointer to an array of size nrounds + 1.
  *  key must be a pointer to 4 * nkeywords bytes.
  *
  *  AES128 uses nkeywords = 4, nrounds = 10
  *  AES192 uses nkeywords = 6, nrounds = 12
  *  AES256 uses nkeywords = 8, nrounds = 14
  */
 static void AES_setup(AES_state *rounds, const uint8_t *key, int nkeywords,
                       int nrounds) {
     int i;
 
     /* The one-byte round constant */
     AES_state rcon = {{1, 0, 0, 0, 0, 0, 0, 0}};
     /* The number of the word being generated, modulo nkeywords */
     int pos = 0;
     /* The column representing the word currently being processed */
     AES_state column;
 
     for (i = 0; i < nrounds + 1; i++) {
         int b;
         for (b = 0; b < 8; b++) {
             rounds[i].slice[b] = 0;
         }
     }
 
     /* The first nkeywords round columns are just taken from the key directly.
      */
     for (i = 0; i < nkeywords; i++) {
         int r;
         for (r = 0; r < 4; r++) {
             LoadByte(&rounds[i >> 2], *(key++), r, i & 3);
         }
     }
 
     GetOneColumn(&column, &rounds[(nkeywords - 1) >> 2], (nkeywords - 1) & 3);
 
     for (i = nkeywords; i < 4 * (nrounds + 1); i++) {
         /* Transform column */
         if (pos == 0) {
             SubBytes(&column, 0);
             KeySetupTransform(&column, &rcon);
             MultX(&rcon);
         } else if (nkeywords > 6 && pos == 4) {
             SubBytes(&column, 0);
         }
         if (++pos == nkeywords) pos = 0;
         KeySetupColumnMix(&column, &rounds[i >> 2],
                           &rounds[(i - nkeywords) >> 2], i & 3,
                           (i - nkeywords) & 3);
     }
 }
 
-static void AES_encrypt(const AES_state *rounds, int nrounds,
-                        unsigned char *cipher16, const unsigned char *plain16) {
+static void AES_encrypt(const AES_state *rounds, int nrounds, uint8_t *cipher16,
+                        const uint8_t *plain16) {
     AES_state s = {{0}};
     int round;
 
     LoadBytes(&s, plain16);
     AddRoundKey(&s, rounds++);
 
     for (round = 1; round < nrounds; round++) {
         SubBytes(&s, 0);
         ShiftRows(&s);
         MixColumns(&s, 0);
         AddRoundKey(&s, rounds++);
     }
 
     SubBytes(&s, 0);
     ShiftRows(&s);
     AddRoundKey(&s, rounds);
 
     SaveBytes(cipher16, &s);
 }
 
-static void AES_decrypt(const AES_state *rounds, int nrounds,
-                        unsigned char *plain16, const unsigned char *cipher16) {
+static void AES_decrypt(const AES_state *rounds, int nrounds, uint8_t *plain16,
+                        const uint8_t *cipher16) {
     /* Most AES decryption implementations use the alternate scheme
      * (the Equivalent Inverse Cipher), which allows for more code reuse between
      * the encryption and decryption code, but requires separate setup for both.
      */
     AES_state s = {{0}};
     int round;
 
     rounds += nrounds;
 
     LoadBytes(&s, cipher16);
     AddRoundKey(&s, rounds--);
 
     for (round = 1; round < nrounds; round++) {
         InvShiftRows(&s);
         SubBytes(&s, 1);
         AddRoundKey(&s, rounds--);
         MixColumns(&s, 1);
     }
 
     InvShiftRows(&s);
     SubBytes(&s, 1);
     AddRoundKey(&s, rounds);
 
     SaveBytes(plain16, &s);
 }
 
-void AES128_init(AES128_ctx *ctx, const unsigned char *key16) {
+void AES128_init(AES128_ctx *ctx, const uint8_t *key16) {
     AES_setup(ctx->rk, key16, 4, 10);
 }
 
-void AES128_encrypt(const AES128_ctx *ctx, size_t blocks,
-                    unsigned char *cipher16, const unsigned char *plain16) {
+void AES128_encrypt(const AES128_ctx *ctx, size_t blocks, uint8_t *cipher16,
+                    const uint8_t *plain16) {
     while (blocks--) {
         AES_encrypt(ctx->rk, 10, cipher16, plain16);
         cipher16 += 16;
         plain16 += 16;
     }
 }
 
-void AES128_decrypt(const AES128_ctx *ctx, size_t blocks,
-                    unsigned char *plain16, const unsigned char *cipher16) {
+void AES128_decrypt(const AES128_ctx *ctx, size_t blocks, uint8_t *plain16,
+                    const uint8_t *cipher16) {
     while (blocks--) {
         AES_decrypt(ctx->rk, 10, plain16, cipher16);
         cipher16 += 16;
         plain16 += 16;
     }
 }
 
-void AES192_init(AES192_ctx *ctx, const unsigned char *key24) {
+void AES192_init(AES192_ctx *ctx, const uint8_t *key24) {
     AES_setup(ctx->rk, key24, 6, 12);
 }
 
-void AES192_encrypt(const AES192_ctx *ctx, size_t blocks,
-                    unsigned char *cipher16, const unsigned char *plain16) {
+void AES192_encrypt(const AES192_ctx *ctx, size_t blocks, uint8_t *cipher16,
+                    const uint8_t *plain16) {
     while (blocks--) {
         AES_encrypt(ctx->rk, 12, cipher16, plain16);
         cipher16 += 16;
         plain16 += 16;
     }
 }
 
-void AES192_decrypt(const AES192_ctx *ctx, size_t blocks,
-                    unsigned char *plain16, const unsigned char *cipher16) {
+void AES192_decrypt(const AES192_ctx *ctx, size_t blocks, uint8_t *plain16,
+                    const uint8_t *cipher16) {
     while (blocks--) {
         AES_decrypt(ctx->rk, 12, plain16, cipher16);
         cipher16 += 16;
         plain16 += 16;
     }
 }
 
-void AES256_init(AES256_ctx *ctx, const unsigned char *key32) {
+void AES256_init(AES256_ctx *ctx, const uint8_t *key32) {
     AES_setup(ctx->rk, key32, 8, 14);
 }
 
-void AES256_encrypt(const AES256_ctx *ctx, size_t blocks,
-                    unsigned char *cipher16, const unsigned char *plain16) {
+void AES256_encrypt(const AES256_ctx *ctx, size_t blocks, uint8_t *cipher16,
+                    const uint8_t *plain16) {
     while (blocks--) {
         AES_encrypt(ctx->rk, 14, cipher16, plain16);
         cipher16 += 16;
         plain16 += 16;
     }
 }
 
-void AES256_decrypt(const AES256_ctx *ctx, size_t blocks,
-                    unsigned char *plain16, const unsigned char *cipher16) {
+void AES256_decrypt(const AES256_ctx *ctx, size_t blocks, uint8_t *plain16,
+                    const uint8_t *cipher16) {
     while (blocks--) {
         AES_decrypt(ctx->rk, 14, plain16, cipher16);
         cipher16 += 16;
         plain16 += 16;
     }
 }
diff --git a/src/crypto/ctaes/ctaes.h b/src/crypto/ctaes/ctaes.h
index 4bd694d13..a5c1e97cc 100644
--- a/src/crypto/ctaes/ctaes.h
+++ b/src/crypto/ctaes/ctaes.h
@@ -1,39 +1,39 @@
 /**********************************************************************
  * Copyright (c) 2016 Pieter Wuille                                   *
  * Distributed under the MIT software license, see the accompanying   *
  * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
  **********************************************************************/
 
 #ifndef _CTAES_H_
 #define _CTAES_H_ 1
 
 #include <stdint.h>
 #include <stdlib.h>
 
 typedef struct { uint16_t slice[8]; } AES_state;
 
 typedef struct { AES_state rk[11]; } AES128_ctx;
 
 typedef struct { AES_state rk[13]; } AES192_ctx;
 
 typedef struct { AES_state rk[15]; } AES256_ctx;
 
-void AES128_init(AES128_ctx *ctx, const unsigned char *key16);
-void AES128_encrypt(const AES128_ctx *ctx, size_t blocks,
-                    unsigned char *cipher16, const unsigned char *plain16);
-void AES128_decrypt(const AES128_ctx *ctx, size_t blocks,
-                    unsigned char *plain16, const unsigned char *cipher16);
-
-void AES192_init(AES192_ctx *ctx, const unsigned char *key24);
-void AES192_encrypt(const AES192_ctx *ctx, size_t blocks,
-                    unsigned char *cipher16, const unsigned char *plain16);
-void AES192_decrypt(const AES192_ctx *ctx, size_t blocks,
-                    unsigned char *plain16, const unsigned char *cipher16);
-
-void AES256_init(AES256_ctx *ctx, const unsigned char *key32);
-void AES256_encrypt(const AES256_ctx *ctx, size_t blocks,
-                    unsigned char *cipher16, const unsigned char *plain16);
-void AES256_decrypt(const AES256_ctx *ctx, size_t blocks,
-                    unsigned char *plain16, const unsigned char *cipher16);
+void AES128_init(AES128_ctx *ctx, const uint8_t *key16);
+void AES128_encrypt(const AES128_ctx *ctx, size_t blocks, uint8_t *cipher16,
+                    const uint8_t *plain16);
+void AES128_decrypt(const AES128_ctx *ctx, size_t blocks, uint8_t *plain16,
+                    const uint8_t *cipher16);
+
+void AES192_init(AES192_ctx *ctx, const uint8_t *key24);
+void AES192_encrypt(const AES192_ctx *ctx, size_t blocks, uint8_t *cipher16,
+                    const uint8_t *plain16);
+void AES192_decrypt(const AES192_ctx *ctx, size_t blocks, uint8_t *plain16,
+                    const uint8_t *cipher16);
+
+void AES256_init(AES256_ctx *ctx, const uint8_t *key32);
+void AES256_encrypt(const AES256_ctx *ctx, size_t blocks, uint8_t *cipher16,
+                    const uint8_t *plain16);
+void AES256_decrypt(const AES256_ctx *ctx, size_t blocks, uint8_t *plain16,
+                    const uint8_t *cipher16);
 
 #endif
diff --git a/src/crypto/ctaes/test.c b/src/crypto/ctaes/test.c
index 4d65f7500..11c6cea65 100644
--- a/src/crypto/ctaes/test.c
+++ b/src/crypto/ctaes/test.c
@@ -1,129 +1,128 @@
 /*********************************************************************
 * Copyright (c) 2016 Pieter Wuille                                   *
 * Distributed under the MIT software license, see the accompanying   *
 * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
 **********************************************************************/
 
 #include "ctaes.h"
 
 #include <assert.h>
 #include <stdio.h>
 #include <string.h>
 
 typedef struct {
     int keysize;
     const char *key;
     const char *plain;
     const char *cipher;
 } ctaes_test;
 
 static const ctaes_test ctaes_tests[] = {
     /* AES test vectors from FIPS 197. */
     {128, "000102030405060708090a0b0c0d0e0f",
      "00112233445566778899aabbccddeeff", "69c4e0d86a7b0430d8cdb78070b4c55a"},
     {192, "000102030405060708090a0b0c0d0e0f1011121314151617",
      "00112233445566778899aabbccddeeff", "dda97ca4864cdfe06eaf70a0ec0d7191"},
     {256, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
      "00112233445566778899aabbccddeeff", "8ea2b7ca516745bfeafc49904b496089"},
 
     /* AES-ECB test vectors from NIST sp800-38a. */
     {128, "2b7e151628aed2a6abf7158809cf4f3c",
      "6bc1bee22e409f96e93d7e117393172a", "3ad77bb40d7a3660a89ecaf32466ef97"},
     {128, "2b7e151628aed2a6abf7158809cf4f3c",
      "ae2d8a571e03ac9c9eb76fac45af8e51", "f5d3d58503b9699de785895a96fdbaaf"},
     {128, "2b7e151628aed2a6abf7158809cf4f3c",
      "30c81c46a35ce411e5fbc1191a0a52ef", "43b1cd7f598ece23881b00e3ed030688"},
     {128, "2b7e151628aed2a6abf7158809cf4f3c",
      "f69f2445df4f9b17ad2b417be66c3710", "7b0c785e27e8ad3f8223207104725dd4"},
     {192, "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b",
      "6bc1bee22e409f96e93d7e117393172a", "bd334f1d6e45f25ff712a214571fa5cc"},
     {192, "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b",
      "ae2d8a571e03ac9c9eb76fac45af8e51", "974104846d0ad3ad7734ecb3ecee4eef"},
     {192, "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b",
      "30c81c46a35ce411e5fbc1191a0a52ef", "ef7afd2270e2e60adce0ba2face6444e"},
     {192, "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b",
      "f69f2445df4f9b17ad2b417be66c3710", "9a4b41ba738d6c72fb16691603c18e0e"},
     {256, "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
      "6bc1bee22e409f96e93d7e117393172a", "f3eed1bdb5d2a03c064b5a7e3db181f8"},
     {256, "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
      "ae2d8a571e03ac9c9eb76fac45af8e51", "591ccb10d410ed26dc5ba74a31362870"},
     {256, "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
      "30c81c46a35ce411e5fbc1191a0a52ef", "b6ed21b99ca6f4f9f153e7b1beafed1d"},
     {256, "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
      "f69f2445df4f9b17ad2b417be66c3710", "23304b7a39f9f3ff067d8d8f9e24ecc7"}};
 
-static void from_hex(unsigned char *data, int len, const char *hex) {
+static void from_hex(uint8_t *data, int len, const char *hex) {
     int p;
     for (p = 0; p < len; p++) {
         int v = 0;
         int n;
         for (n = 0; n < 2; n++) {
             assert((*hex >= '0' && *hex <= '9') ||
                    (*hex >= 'a' && *hex <= 'f'));
             if (*hex >= '0' && *hex <= '9') {
                 v |= (*hex - '0') << (4 * (1 - n));
             } else {
                 v |= (*hex - 'a' + 10) << (4 * (1 - n));
             }
             hex++;
         }
         *(data++) = v;
     }
     assert(*hex == 0);
 }
 
 int main(void) {
     int i;
     int fail = 0;
     for (i = 0; i < sizeof(ctaes_tests) / sizeof(ctaes_tests[0]); i++) {
-        unsigned char key[32], plain[16], cipher[16], ciphered[16],
-            deciphered[16];
+        uint8_t key[32], plain[16], cipher[16], ciphered[16], deciphered[16];
         const ctaes_test *test = &ctaes_tests[i];
         assert(test->keysize == 128 || test->keysize == 192 ||
                test->keysize == 256);
         from_hex(plain, 16, test->plain);
         from_hex(cipher, 16, test->cipher);
         switch (test->keysize) {
             case 128: {
                 AES128_ctx ctx;
                 from_hex(key, 16, test->key);
                 AES128_init(&ctx, key);
                 AES128_encrypt(&ctx, 1, ciphered, plain);
                 AES128_decrypt(&ctx, 1, deciphered, cipher);
                 break;
             }
             case 192: {
                 AES192_ctx ctx;
                 from_hex(key, 24, test->key);
                 AES192_init(&ctx, key);
                 AES192_encrypt(&ctx, 1, ciphered, plain);
                 AES192_decrypt(&ctx, 1, deciphered, cipher);
                 break;
             }
             case 256: {
                 AES256_ctx ctx;
                 from_hex(key, 32, test->key);
                 AES256_init(&ctx, key);
                 AES256_encrypt(&ctx, 1, ciphered, plain);
                 AES256_decrypt(&ctx, 1, deciphered, cipher);
                 break;
             }
         }
         if (memcmp(cipher, ciphered, 16)) {
             fprintf(stderr, "E(key=\"%s\", plain=\"%s\") != \"%s\"\n",
                     test->key, test->plain, test->cipher);
             fail++;
         }
         if (memcmp(plain, deciphered, 16)) {
             fprintf(stderr, "D(key=\"%s\", cipher=\"%s\") != \"%s\"\n",
                     test->key, test->cipher, test->plain);
             fail++;
         }
     }
     if (fail == 0) {
         fprintf(stderr, "All tests successful\n");
     } else {
         fprintf(stderr, "%i tests failed\n", fail);
     }
     return (fail != 0);
 }
diff --git a/src/crypto/hmac_sha256.cpp b/src/crypto/hmac_sha256.cpp
index b8c479d72..d01227ab7 100644
--- a/src/crypto/hmac_sha256.cpp
+++ b/src/crypto/hmac_sha256.cpp
@@ -1,32 +1,32 @@
 // Copyright (c) 2014 The Bitcoin Core developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #include "crypto/hmac_sha256.h"
 
 #include <cstring>
 
-CHMAC_SHA256::CHMAC_SHA256(const unsigned char *key, size_t keylen) {
-    unsigned char rkey[64];
+CHMAC_SHA256::CHMAC_SHA256(const uint8_t *key, size_t keylen) {
+    uint8_t rkey[64];
     if (keylen <= 64) {
         memcpy(rkey, key, keylen);
         memset(rkey + keylen, 0, 64 - keylen);
     } else {
         CSHA256().Write(key, keylen).Finalize(rkey);
         memset(rkey + 32, 0, 32);
     }
 
     for (int n = 0; n < 64; n++)
         rkey[n] ^= 0x5c;
     outer.Write(rkey, 64);
 
     for (int n = 0; n < 64; n++)
         rkey[n] ^= 0x5c ^ 0x36;
     inner.Write(rkey, 64);
 }
 
-void CHMAC_SHA256::Finalize(unsigned char hash[OUTPUT_SIZE]) {
-    unsigned char temp[32];
+void CHMAC_SHA256::Finalize(uint8_t hash[OUTPUT_SIZE]) {
+    uint8_t temp[32];
     inner.Finalize(temp);
     outer.Write(temp, 32).Finalize(hash);
 }
diff --git a/src/crypto/hmac_sha256.h b/src/crypto/hmac_sha256.h
index 9b7f00d1e..7edf0bff6 100644
--- a/src/crypto/hmac_sha256.h
+++ b/src/crypto/hmac_sha256.h
@@ -1,30 +1,30 @@
 // Copyright (c) 2014 The Bitcoin Core developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #ifndef BITCOIN_CRYPTO_HMAC_SHA256_H
 #define BITCOIN_CRYPTO_HMAC_SHA256_H
 
 #include "crypto/sha256.h"
 
 #include <cstdint>
 #include <cstdlib>
 
 /** A hasher class for HMAC-SHA-512. */
 class CHMAC_SHA256 {
 private:
     CSHA256 outer;
     CSHA256 inner;
 
 public:
     static const size_t OUTPUT_SIZE = 32;
 
-    CHMAC_SHA256(const unsigned char *key, size_t keylen);
-    CHMAC_SHA256 &Write(const unsigned char *data, size_t len) {
+    CHMAC_SHA256(const uint8_t *key, size_t keylen);
+    CHMAC_SHA256 &Write(const uint8_t *data, size_t len) {
         inner.Write(data, len);
         return *this;
     }
-    void Finalize(unsigned char hash[OUTPUT_SIZE]);
+    void Finalize(uint8_t hash[OUTPUT_SIZE]);
 };
 
 #endif // BITCOIN_CRYPTO_HMAC_SHA256_H
diff --git a/src/crypto/hmac_sha512.cpp b/src/crypto/hmac_sha512.cpp
index f1155ce88..9a4e7cd16 100644
--- a/src/crypto/hmac_sha512.cpp
+++ b/src/crypto/hmac_sha512.cpp
@@ -1,32 +1,32 @@
 // Copyright (c) 2014 The Bitcoin Core developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #include "crypto/hmac_sha512.h"
 
 #include <cstring>
 
-CHMAC_SHA512::CHMAC_SHA512(const unsigned char *key, size_t keylen) {
-    unsigned char rkey[128];
+CHMAC_SHA512::CHMAC_SHA512(const uint8_t *key, size_t keylen) {
+    uint8_t rkey[128];
     if (keylen <= 128) {
         memcpy(rkey, key, keylen);
         memset(rkey + keylen, 0, 128 - keylen);
     } else {
         CSHA512().Write(key, keylen).Finalize(rkey);
         memset(rkey + 64, 0, 64);
     }
 
     for (int n = 0; n < 128; n++)
         rkey[n] ^= 0x5c;
     outer.Write(rkey, 128);
 
     for (int n = 0; n < 128; n++)
         rkey[n] ^= 0x5c ^ 0x36;
     inner.Write(rkey, 128);
 }
 
-void CHMAC_SHA512::Finalize(unsigned char hash[OUTPUT_SIZE]) {
-    unsigned char temp[64];
+void CHMAC_SHA512::Finalize(uint8_t hash[OUTPUT_SIZE]) {
+    uint8_t temp[64];
     inner.Finalize(temp);
     outer.Write(temp, 64).Finalize(hash);
 }
diff --git a/src/crypto/hmac_sha512.h b/src/crypto/hmac_sha512.h
index 5e670426d..911508867 100644
--- a/src/crypto/hmac_sha512.h
+++ b/src/crypto/hmac_sha512.h
@@ -1,30 +1,30 @@
 // Copyright (c) 2014 The Bitcoin Core developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #ifndef BITCOIN_CRYPTO_HMAC_SHA512_H
 #define BITCOIN_CRYPTO_HMAC_SHA512_H
 
 #include "crypto/sha512.h"
 
 #include <cstdint>
 #include <cstdlib>
 
 /** A hasher class for HMAC-SHA-512. */
 class CHMAC_SHA512 {
 private:
     CSHA512 outer;
     CSHA512 inner;
 
 public:
     static const size_t OUTPUT_SIZE = 64;
 
-    CHMAC_SHA512(const unsigned char *key, size_t keylen);
-    CHMAC_SHA512 &Write(const unsigned char *data, size_t len) {
+    CHMAC_SHA512(const uint8_t *key, size_t keylen);
+    CHMAC_SHA512 &Write(const uint8_t *data, size_t len) {
         inner.Write(data, len);
         return *this;
     }
-    void Finalize(unsigned char hash[OUTPUT_SIZE]);
+    void Finalize(uint8_t hash[OUTPUT_SIZE]);
 };
 
 #endif // BITCOIN_CRYPTO_HMAC_SHA512_H
diff --git a/src/crypto/ripemd160.cpp b/src/crypto/ripemd160.cpp
index eba451a4f..9f8f80222 100644
--- a/src/crypto/ripemd160.cpp
+++ b/src/crypto/ripemd160.cpp
@@ -1,328 +1,328 @@
 // Copyright (c) 2014 The Bitcoin Core developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #include "crypto/ripemd160.h"
 
 #include "crypto/common.h"
 
 #include <cstring>
 
 // Internal implementation code.
 namespace {
 /// Internal RIPEMD-160 implementation.
 namespace ripemd160 {
     inline uint32_t f1(uint32_t x, uint32_t y, uint32_t z) { return x ^ y ^ z; }
     inline uint32_t f2(uint32_t x, uint32_t y, uint32_t z) {
         return (x & y) | (~x & z);
     }
     inline uint32_t f3(uint32_t x, uint32_t y, uint32_t z) {
         return (x | ~y) ^ z;
     }
     inline uint32_t f4(uint32_t x, uint32_t y, uint32_t z) {
         return (x & z) | (y & ~z);
     }
     inline uint32_t f5(uint32_t x, uint32_t y, uint32_t z) {
         return x ^ (y | ~z);
     }
 
     /** Initialize RIPEMD-160 state. */
     inline void Initialize(uint32_t *s) {
         s[0] = 0x67452301ul;
         s[1] = 0xEFCDAB89ul;
         s[2] = 0x98BADCFEul;
         s[3] = 0x10325476ul;
         s[4] = 0xC3D2E1F0ul;
     }
 
     inline uint32_t rol(uint32_t x, int i) {
         return (x << i) | (x >> (32 - i));
     }
 
     inline void Round(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d,
                       uint32_t e, uint32_t f, uint32_t x, uint32_t k, int r) {
         a = rol(a + f + x + k, r) + e;
         c = rol(c, 10);
     }
 
     inline void R11(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d,
                     uint32_t e, uint32_t x, int r) {
         Round(a, b, c, d, e, f1(b, c, d), x, 0, r);
     }
     inline void R21(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d,
                     uint32_t e, uint32_t x, int r) {
         Round(a, b, c, d, e, f2(b, c, d), x, 0x5A827999ul, r);
     }
     inline void R31(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d,
                     uint32_t e, uint32_t x, int r) {
         Round(a, b, c, d, e, f3(b, c, d), x, 0x6ED9EBA1ul, r);
     }
     inline void R41(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d,
                     uint32_t e, uint32_t x, int r) {
         Round(a, b, c, d, e, f4(b, c, d), x, 0x8F1BBCDCul, r);
     }
     inline void R51(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d,
                     uint32_t e, uint32_t x, int r) {
         Round(a, b, c, d, e, f5(b, c, d), x, 0xA953FD4Eul, r);
     }
 
     inline void R12(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d,
                     uint32_t e, uint32_t x, int r) {
         Round(a, b, c, d, e, f5(b, c, d), x, 0x50A28BE6ul, r);
     }
     inline void R22(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d,
                     uint32_t e, uint32_t x, int r) {
         Round(a, b, c, d, e, f4(b, c, d), x, 0x5C4DD124ul, r);
     }
     inline void R32(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d,
                     uint32_t e, uint32_t x, int r) {
         Round(a, b, c, d, e, f3(b, c, d), x, 0x6D703EF3ul, r);
     }
     inline void R42(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d,
                     uint32_t e, uint32_t x, int r) {
         Round(a, b, c, d, e, f2(b, c, d), x, 0x7A6D76E9ul, r);
     }
     inline void R52(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d,
                     uint32_t e, uint32_t x, int r) {
         Round(a, b, c, d, e, f1(b, c, d), x, 0, r);
     }
 
     /** Perform a RIPEMD-160 transformation, processing a 64-byte chunk. */
-    void Transform(uint32_t *s, const unsigned char *chunk) {
+    void Transform(uint32_t *s, const uint8_t *chunk) {
         uint32_t a1 = s[0], b1 = s[1], c1 = s[2], d1 = s[3], e1 = s[4];
         uint32_t a2 = a1, b2 = b1, c2 = c1, d2 = d1, e2 = e1;
         uint32_t w0 = ReadLE32(chunk + 0), w1 = ReadLE32(chunk + 4),
                  w2 = ReadLE32(chunk + 8), w3 = ReadLE32(chunk + 12);
         uint32_t w4 = ReadLE32(chunk + 16), w5 = ReadLE32(chunk + 20),
                  w6 = ReadLE32(chunk + 24), w7 = ReadLE32(chunk + 28);
         uint32_t w8 = ReadLE32(chunk + 32), w9 = ReadLE32(chunk + 36),
                  w10 = ReadLE32(chunk + 40), w11 = ReadLE32(chunk + 44);
         uint32_t w12 = ReadLE32(chunk + 48), w13 = ReadLE32(chunk + 52),
                  w14 = ReadLE32(chunk + 56), w15 = ReadLE32(chunk + 60);
 
         R11(a1, b1, c1, d1, e1, w0, 11);
         R12(a2, b2, c2, d2, e2, w5, 8);
         R11(e1, a1, b1, c1, d1, w1, 14);
         R12(e2, a2, b2, c2, d2, w14, 9);
         R11(d1, e1, a1, b1, c1, w2, 15);
         R12(d2, e2, a2, b2, c2, w7, 9);
         R11(c1, d1, e1, a1, b1, w3, 12);
         R12(c2, d2, e2, a2, b2, w0, 11);
         R11(b1, c1, d1, e1, a1, w4, 5);
         R12(b2, c2, d2, e2, a2, w9, 13);
         R11(a1, b1, c1, d1, e1, w5, 8);
         R12(a2, b2, c2, d2, e2, w2, 15);
         R11(e1, a1, b1, c1, d1, w6, 7);
         R12(e2, a2, b2, c2, d2, w11, 15);
         R11(d1, e1, a1, b1, c1, w7, 9);
         R12(d2, e2, a2, b2, c2, w4, 5);
         R11(c1, d1, e1, a1, b1, w8, 11);
         R12(c2, d2, e2, a2, b2, w13, 7);
         R11(b1, c1, d1, e1, a1, w9, 13);
         R12(b2, c2, d2, e2, a2, w6, 7);
         R11(a1, b1, c1, d1, e1, w10, 14);
         R12(a2, b2, c2, d2, e2, w15, 8);
         R11(e1, a1, b1, c1, d1, w11, 15);
         R12(e2, a2, b2, c2, d2, w8, 11);
         R11(d1, e1, a1, b1, c1, w12, 6);
         R12(d2, e2, a2, b2, c2, w1, 14);
         R11(c1, d1, e1, a1, b1, w13, 7);
         R12(c2, d2, e2, a2, b2, w10, 14);
         R11(b1, c1, d1, e1, a1, w14, 9);
         R12(b2, c2, d2, e2, a2, w3, 12);
         R11(a1, b1, c1, d1, e1, w15, 8);
         R12(a2, b2, c2, d2, e2, w12, 6);
 
         R21(e1, a1, b1, c1, d1, w7, 7);
         R22(e2, a2, b2, c2, d2, w6, 9);
         R21(d1, e1, a1, b1, c1, w4, 6);
         R22(d2, e2, a2, b2, c2, w11, 13);
         R21(c1, d1, e1, a1, b1, w13, 8);
         R22(c2, d2, e2, a2, b2, w3, 15);
         R21(b1, c1, d1, e1, a1, w1, 13);
         R22(b2, c2, d2, e2, a2, w7, 7);
         R21(a1, b1, c1, d1, e1, w10, 11);
         R22(a2, b2, c2, d2, e2, w0, 12);
         R21(e1, a1, b1, c1, d1, w6, 9);
         R22(e2, a2, b2, c2, d2, w13, 8);
         R21(d1, e1, a1, b1, c1, w15, 7);
         R22(d2, e2, a2, b2, c2, w5, 9);
         R21(c1, d1, e1, a1, b1, w3, 15);
         R22(c2, d2, e2, a2, b2, w10, 11);
         R21(b1, c1, d1, e1, a1, w12, 7);
         R22(b2, c2, d2, e2, a2, w14, 7);
         R21(a1, b1, c1, d1, e1, w0, 12);
         R22(a2, b2, c2, d2, e2, w15, 7);
         R21(e1, a1, b1, c1, d1, w9, 15);
         R22(e2, a2, b2, c2, d2, w8, 12);
         R21(d1, e1, a1, b1, c1, w5, 9);
         R22(d2, e2, a2, b2, c2, w12, 7);
         R21(c1, d1, e1, a1, b1, w2, 11);
         R22(c2, d2, e2, a2, b2, w4, 6);
         R21(b1, c1, d1, e1, a1, w14, 7);
         R22(b2, c2, d2, e2, a2, w9, 15);
         R21(a1, b1, c1, d1, e1, w11, 13);
         R22(a2, b2, c2, d2, e2, w1, 13);
         R21(e1, a1, b1, c1, d1, w8, 12);
         R22(e2, a2, b2, c2, d2, w2, 11);
 
         R31(d1, e1, a1, b1, c1, w3, 11);
         R32(d2, e2, a2, b2, c2, w15, 9);
         R31(c1, d1, e1, a1, b1, w10, 13);
         R32(c2, d2, e2, a2, b2, w5, 7);
         R31(b1, c1, d1, e1, a1, w14, 6);
         R32(b2, c2, d2, e2, a2, w1, 15);
         R31(a1, b1, c1, d1, e1, w4, 7);
         R32(a2, b2, c2, d2, e2, w3, 11);
         R31(e1, a1, b1, c1, d1, w9, 14);
         R32(e2, a2, b2, c2, d2, w7, 8);
         R31(d1, e1, a1, b1, c1, w15, 9);
         R32(d2, e2, a2, b2, c2, w14, 6);
         R31(c1, d1, e1, a1, b1, w8, 13);
         R32(c2, d2, e2, a2, b2, w6, 6);
         R31(b1, c1, d1, e1, a1, w1, 15);
         R32(b2, c2, d2, e2, a2, w9, 14);
         R31(a1, b1, c1, d1, e1, w2, 14);
         R32(a2, b2, c2, d2, e2, w11, 12);
         R31(e1, a1, b1, c1, d1, w7, 8);
         R32(e2, a2, b2, c2, d2, w8, 13);
         R31(d1, e1, a1, b1, c1, w0, 13);
         R32(d2, e2, a2, b2, c2, w12, 5);
         R31(c1, d1, e1, a1, b1, w6, 6);
         R32(c2, d2, e2, a2, b2, w2, 14);
         R31(b1, c1, d1, e1, a1, w13, 5);
         R32(b2, c2, d2, e2, a2, w10, 13);
         R31(a1, b1, c1, d1, e1, w11, 12);
         R32(a2, b2, c2, d2, e2, w0, 13);
         R31(e1, a1, b1, c1, d1, w5, 7);
         R32(e2, a2, b2, c2, d2, w4, 7);
         R31(d1, e1, a1, b1, c1, w12, 5);
         R32(d2, e2, a2, b2, c2, w13, 5);
 
         R41(c1, d1, e1, a1, b1, w1, 11);
         R42(c2, d2, e2, a2, b2, w8, 15);
         R41(b1, c1, d1, e1, a1, w9, 12);
         R42(b2, c2, d2, e2, a2, w6, 5);
         R41(a1, b1, c1, d1, e1, w11, 14);
         R42(a2, b2, c2, d2, e2, w4, 8);
         R41(e1, a1, b1, c1, d1, w10, 15);
         R42(e2, a2, b2, c2, d2, w1, 11);
         R41(d1, e1, a1, b1, c1, w0, 14);
         R42(d2, e2, a2, b2, c2, w3, 14);
         R41(c1, d1, e1, a1, b1, w8, 15);
         R42(c2, d2, e2, a2, b2, w11, 14);
         R41(b1, c1, d1, e1, a1, w12, 9);
         R42(b2, c2, d2, e2, a2, w15, 6);
         R41(a1, b1, c1, d1, e1, w4, 8);
         R42(a2, b2, c2, d2, e2, w0, 14);
         R41(e1, a1, b1, c1, d1, w13, 9);
         R42(e2, a2, b2, c2, d2, w5, 6);
         R41(d1, e1, a1, b1, c1, w3, 14);
         R42(d2, e2, a2, b2, c2, w12, 9);
         R41(c1, d1, e1, a1, b1, w7, 5);
         R42(c2, d2, e2, a2, b2, w2, 12);
         R41(b1, c1, d1, e1, a1, w15, 6);
         R42(b2, c2, d2, e2, a2, w13, 9);
         R41(a1, b1, c1, d1, e1, w14, 8);
         R42(a2, b2, c2, d2, e2, w9, 12);
         R41(e1, a1, b1, c1, d1, w5, 6);
         R42(e2, a2, b2, c2, d2, w7, 5);
         R41(d1, e1, a1, b1, c1, w6, 5);
         R42(d2, e2, a2, b2, c2, w10, 15);
         R41(c1, d1, e1, a1, b1, w2, 12);
         R42(c2, d2, e2, a2, b2, w14, 8);
 
         R51(b1, c1, d1, e1, a1, w4, 9);
         R52(b2, c2, d2, e2, a2, w12, 8);
         R51(a1, b1, c1, d1, e1, w0, 15);
         R52(a2, b2, c2, d2, e2, w15, 5);
         R51(e1, a1, b1, c1, d1, w5, 5);
         R52(e2, a2, b2, c2, d2, w10, 12);
         R51(d1, e1, a1, b1, c1, w9, 11);
         R52(d2, e2, a2, b2, c2, w4, 9);
         R51(c1, d1, e1, a1, b1, w7, 6);
         R52(c2, d2, e2, a2, b2, w1, 12);
         R51(b1, c1, d1, e1, a1, w12, 8);
         R52(b2, c2, d2, e2, a2, w5, 5);
         R51(a1, b1, c1, d1, e1, w2, 13);
         R52(a2, b2, c2, d2, e2, w8, 14);
         R51(e1, a1, b1, c1, d1, w10, 12);
         R52(e2, a2, b2, c2, d2, w7, 6);
         R51(d1, e1, a1, b1, c1, w14, 5);
         R52(d2, e2, a2, b2, c2, w6, 8);
         R51(c1, d1, e1, a1, b1, w1, 12);
         R52(c2, d2, e2, a2, b2, w2, 13);
         R51(b1, c1, d1, e1, a1, w3, 13);
         R52(b2, c2, d2, e2, a2, w13, 6);
         R51(a1, b1, c1, d1, e1, w8, 14);
         R52(a2, b2, c2, d2, e2, w14, 5);
         R51(e1, a1, b1, c1, d1, w11, 11);
         R52(e2, a2, b2, c2, d2, w0, 15);
         R51(d1, e1, a1, b1, c1, w6, 8);
         R52(d2, e2, a2, b2, c2, w3, 13);
         R51(c1, d1, e1, a1, b1, w15, 5);
         R52(c2, d2, e2, a2, b2, w9, 11);
         R51(b1, c1, d1, e1, a1, w13, 6);
         R52(b2, c2, d2, e2, a2, w11, 11);
 
         uint32_t t = s[0];
         s[0] = s[1] + c1 + d2;
         s[1] = s[2] + d1 + e2;
         s[2] = s[3] + e1 + a2;
         s[3] = s[4] + a1 + b2;
         s[4] = t + b1 + c2;
     }
 
 } // namespace ripemd160
 
 } // namespace
 
 ////// RIPEMD160
 
 CRIPEMD160::CRIPEMD160() : bytes(0) {
     ripemd160::Initialize(s);
 }
 
-CRIPEMD160 &CRIPEMD160::Write(const unsigned char *data, size_t len) {
-    const unsigned char *end = data + len;
+CRIPEMD160 &CRIPEMD160::Write(const uint8_t *data, size_t len) {
+    const uint8_t *end = data + len;
     size_t bufsize = bytes % 64;
     if (bufsize && bufsize + len >= 64) {
         // Fill the buffer, and process it.
         memcpy(buf + bufsize, data, 64 - bufsize);
         bytes += 64 - bufsize;
         data += 64 - bufsize;
         ripemd160::Transform(s, buf);
         bufsize = 0;
     }
     while (end >= data + 64) {
         // Process full chunks directly from the source.
         ripemd160::Transform(s, data);
         bytes += 64;
         data += 64;
     }
     if (end > data) {
         // Fill the buffer with what remains.
         memcpy(buf + bufsize, data, end - data);
         bytes += end - data;
     }
     return *this;
 }
 
-void CRIPEMD160::Finalize(unsigned char hash[OUTPUT_SIZE]) {
-    static const unsigned char pad[64] = {0x80};
-    unsigned char sizedesc[8];
+void CRIPEMD160::Finalize(uint8_t hash[OUTPUT_SIZE]) {
+    static const uint8_t pad[64] = {0x80};
+    uint8_t sizedesc[8];
     WriteLE64(sizedesc, bytes << 3);
     Write(pad, 1 + ((119 - (bytes % 64)) % 64));
     Write(sizedesc, 8);
     WriteLE32(hash, s[0]);
     WriteLE32(hash + 4, s[1]);
     WriteLE32(hash + 8, s[2]);
     WriteLE32(hash + 12, s[3]);
     WriteLE32(hash + 16, s[4]);
 }
 
 CRIPEMD160 &CRIPEMD160::Reset() {
     bytes = 0;
     ripemd160::Initialize(s);
     return *this;
 }
diff --git a/src/crypto/ripemd160.h b/src/crypto/ripemd160.h
index 1b3be1e17..5fcf0c1f9 100644
--- a/src/crypto/ripemd160.h
+++ b/src/crypto/ripemd160.h
@@ -1,27 +1,27 @@
 // Copyright (c) 2014-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.
 
 #ifndef BITCOIN_CRYPTO_RIPEMD160_H
 #define BITCOIN_CRYPTO_RIPEMD160_H
 
 #include <cstdint>
 #include <cstdlib>
 
 /** A hasher class for RIPEMD-160. */
 class CRIPEMD160 {
 private:
     uint32_t s[5];
-    unsigned char buf[64];
+    uint8_t buf[64];
     uint64_t bytes;
 
 public:
     static const size_t OUTPUT_SIZE = 20;
 
     CRIPEMD160();
-    CRIPEMD160 &Write(const unsigned char *data, size_t len);
-    void Finalize(unsigned char hash[OUTPUT_SIZE]);
+    CRIPEMD160 &Write(const uint8_t *data, size_t len);
+    void Finalize(uint8_t hash[OUTPUT_SIZE]);
     CRIPEMD160 &Reset();
 };
 
 #endif // BITCOIN_CRYPTO_RIPEMD160_H
diff --git a/src/crypto/sha1.cpp b/src/crypto/sha1.cpp
index 15847824d..559c64405 100644
--- a/src/crypto/sha1.cpp
+++ b/src/crypto/sha1.cpp
@@ -1,196 +1,196 @@
 // Copyright (c) 2014 The Bitcoin Core developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #include "crypto/sha1.h"
 
 #include "crypto/common.h"
 
 #include <cstring>
 
 // Internal implementation code.
 namespace {
 /// Internal SHA-1 implementation.
 namespace sha1 {
     /** One round of SHA-1. */
     inline void Round(uint32_t a, uint32_t &b, uint32_t c, uint32_t d,
                       uint32_t &e, uint32_t f, uint32_t k, uint32_t w) {
         e += ((a << 5) | (a >> 27)) + f + k + w;
         b = (b << 30) | (b >> 2);
     }
 
     inline uint32_t f1(uint32_t b, uint32_t c, uint32_t d) {
         return d ^ (b & (c ^ d));
     }
     inline uint32_t f2(uint32_t b, uint32_t c, uint32_t d) { return b ^ c ^ d; }
     inline uint32_t f3(uint32_t b, uint32_t c, uint32_t d) {
         return (b & c) | (d & (b | c));
     }
 
     inline uint32_t left(uint32_t x) { return (x << 1) | (x >> 31); }
 
     /** Initialize SHA-1 state. */
     inline void Initialize(uint32_t *s) {
         s[0] = 0x67452301ul;
         s[1] = 0xEFCDAB89ul;
         s[2] = 0x98BADCFEul;
         s[3] = 0x10325476ul;
         s[4] = 0xC3D2E1F0ul;
     }
 
     const uint32_t k1 = 0x5A827999ul;
     const uint32_t k2 = 0x6ED9EBA1ul;
     const uint32_t k3 = 0x8F1BBCDCul;
     const uint32_t k4 = 0xCA62C1D6ul;
 
     /** Perform a SHA-1 transformation, processing a 64-byte chunk. */
-    void Transform(uint32_t *s, const unsigned char *chunk) {
+    void Transform(uint32_t *s, const uint8_t *chunk) {
         uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4];
         uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13,
             w14, w15;
 
         Round(a, b, c, d, e, f1(b, c, d), k1, w0 = ReadBE32(chunk + 0));
         Round(e, a, b, c, d, f1(a, b, c), k1, w1 = ReadBE32(chunk + 4));
         Round(d, e, a, b, c, f1(e, a, b), k1, w2 = ReadBE32(chunk + 8));
         Round(c, d, e, a, b, f1(d, e, a), k1, w3 = ReadBE32(chunk + 12));
         Round(b, c, d, e, a, f1(c, d, e), k1, w4 = ReadBE32(chunk + 16));
         Round(a, b, c, d, e, f1(b, c, d), k1, w5 = ReadBE32(chunk + 20));
         Round(e, a, b, c, d, f1(a, b, c), k1, w6 = ReadBE32(chunk + 24));
         Round(d, e, a, b, c, f1(e, a, b), k1, w7 = ReadBE32(chunk + 28));
         Round(c, d, e, a, b, f1(d, e, a), k1, w8 = ReadBE32(chunk + 32));
         Round(b, c, d, e, a, f1(c, d, e), k1, w9 = ReadBE32(chunk + 36));
         Round(a, b, c, d, e, f1(b, c, d), k1, w10 = ReadBE32(chunk + 40));
         Round(e, a, b, c, d, f1(a, b, c), k1, w11 = ReadBE32(chunk + 44));
         Round(d, e, a, b, c, f1(e, a, b), k1, w12 = ReadBE32(chunk + 48));
         Round(c, d, e, a, b, f1(d, e, a), k1, w13 = ReadBE32(chunk + 52));
         Round(b, c, d, e, a, f1(c, d, e), k1, w14 = ReadBE32(chunk + 56));
         Round(a, b, c, d, e, f1(b, c, d), k1, w15 = ReadBE32(chunk + 60));
 
         Round(e, a, b, c, d, f1(a, b, c), k1, w0 = left(w0 ^ w13 ^ w8 ^ w2));
         Round(d, e, a, b, c, f1(e, a, b), k1, w1 = left(w1 ^ w14 ^ w9 ^ w3));
         Round(c, d, e, a, b, f1(d, e, a), k1, w2 = left(w2 ^ w15 ^ w10 ^ w4));
         Round(b, c, d, e, a, f1(c, d, e), k1, w3 = left(w3 ^ w0 ^ w11 ^ w5));
         Round(a, b, c, d, e, f2(b, c, d), k2, w4 = left(w4 ^ w1 ^ w12 ^ w6));
         Round(e, a, b, c, d, f2(a, b, c), k2, w5 = left(w5 ^ w2 ^ w13 ^ w7));
         Round(d, e, a, b, c, f2(e, a, b), k2, w6 = left(w6 ^ w3 ^ w14 ^ w8));
         Round(c, d, e, a, b, f2(d, e, a), k2, w7 = left(w7 ^ w4 ^ w15 ^ w9));
         Round(b, c, d, e, a, f2(c, d, e), k2, w8 = left(w8 ^ w5 ^ w0 ^ w10));
         Round(a, b, c, d, e, f2(b, c, d), k2, w9 = left(w9 ^ w6 ^ w1 ^ w11));
         Round(e, a, b, c, d, f2(a, b, c), k2, w10 = left(w10 ^ w7 ^ w2 ^ w12));
         Round(d, e, a, b, c, f2(e, a, b), k2, w11 = left(w11 ^ w8 ^ w3 ^ w13));
         Round(c, d, e, a, b, f2(d, e, a), k2, w12 = left(w12 ^ w9 ^ w4 ^ w14));
         Round(b, c, d, e, a, f2(c, d, e), k2, w13 = left(w13 ^ w10 ^ w5 ^ w15));
         Round(a, b, c, d, e, f2(b, c, d), k2, w14 = left(w14 ^ w11 ^ w6 ^ w0));
         Round(e, a, b, c, d, f2(a, b, c), k2, w15 = left(w15 ^ w12 ^ w7 ^ w1));
 
         Round(d, e, a, b, c, f2(e, a, b), k2, w0 = left(w0 ^ w13 ^ w8 ^ w2));
         Round(c, d, e, a, b, f2(d, e, a), k2, w1 = left(w1 ^ w14 ^ w9 ^ w3));
         Round(b, c, d, e, a, f2(c, d, e), k2, w2 = left(w2 ^ w15 ^ w10 ^ w4));
         Round(a, b, c, d, e, f2(b, c, d), k2, w3 = left(w3 ^ w0 ^ w11 ^ w5));
         Round(e, a, b, c, d, f2(a, b, c), k2, w4 = left(w4 ^ w1 ^ w12 ^ w6));
         Round(d, e, a, b, c, f2(e, a, b), k2, w5 = left(w5 ^ w2 ^ w13 ^ w7));
         Round(c, d, e, a, b, f2(d, e, a), k2, w6 = left(w6 ^ w3 ^ w14 ^ w8));
         Round(b, c, d, e, a, f2(c, d, e), k2, w7 = left(w7 ^ w4 ^ w15 ^ w9));
         Round(a, b, c, d, e, f3(b, c, d), k3, w8 = left(w8 ^ w5 ^ w0 ^ w10));
         Round(e, a, b, c, d, f3(a, b, c), k3, w9 = left(w9 ^ w6 ^ w1 ^ w11));
         Round(d, e, a, b, c, f3(e, a, b), k3, w10 = left(w10 ^ w7 ^ w2 ^ w12));
         Round(c, d, e, a, b, f3(d, e, a), k3, w11 = left(w11 ^ w8 ^ w3 ^ w13));
         Round(b, c, d, e, a, f3(c, d, e), k3, w12 = left(w12 ^ w9 ^ w4 ^ w14));
         Round(a, b, c, d, e, f3(b, c, d), k3, w13 = left(w13 ^ w10 ^ w5 ^ w15));
         Round(e, a, b, c, d, f3(a, b, c), k3, w14 = left(w14 ^ w11 ^ w6 ^ w0));
         Round(d, e, a, b, c, f3(e, a, b), k3, w15 = left(w15 ^ w12 ^ w7 ^ w1));
 
         Round(c, d, e, a, b, f3(d, e, a), k3, w0 = left(w0 ^ w13 ^ w8 ^ w2));
         Round(b, c, d, e, a, f3(c, d, e), k3, w1 = left(w1 ^ w14 ^ w9 ^ w3));
         Round(a, b, c, d, e, f3(b, c, d), k3, w2 = left(w2 ^ w15 ^ w10 ^ w4));
         Round(e, a, b, c, d, f3(a, b, c), k3, w3 = left(w3 ^ w0 ^ w11 ^ w5));
         Round(d, e, a, b, c, f3(e, a, b), k3, w4 = left(w4 ^ w1 ^ w12 ^ w6));
         Round(c, d, e, a, b, f3(d, e, a), k3, w5 = left(w5 ^ w2 ^ w13 ^ w7));
         Round(b, c, d, e, a, f3(c, d, e), k3, w6 = left(w6 ^ w3 ^ w14 ^ w8));
         Round(a, b, c, d, e, f3(b, c, d), k3, w7 = left(w7 ^ w4 ^ w15 ^ w9));
         Round(e, a, b, c, d, f3(a, b, c), k3, w8 = left(w8 ^ w5 ^ w0 ^ w10));
         Round(d, e, a, b, c, f3(e, a, b), k3, w9 = left(w9 ^ w6 ^ w1 ^ w11));
         Round(c, d, e, a, b, f3(d, e, a), k3, w10 = left(w10 ^ w7 ^ w2 ^ w12));
         Round(b, c, d, e, a, f3(c, d, e), k3, w11 = left(w11 ^ w8 ^ w3 ^ w13));
         Round(a, b, c, d, e, f2(b, c, d), k4, w12 = left(w12 ^ w9 ^ w4 ^ w14));
         Round(e, a, b, c, d, f2(a, b, c), k4, w13 = left(w13 ^ w10 ^ w5 ^ w15));
         Round(d, e, a, b, c, f2(e, a, b), k4, w14 = left(w14 ^ w11 ^ w6 ^ w0));
         Round(c, d, e, a, b, f2(d, e, a), k4, w15 = left(w15 ^ w12 ^ w7 ^ w1));
 
         Round(b, c, d, e, a, f2(c, d, e), k4, w0 = left(w0 ^ w13 ^ w8 ^ w2));
         Round(a, b, c, d, e, f2(b, c, d), k4, w1 = left(w1 ^ w14 ^ w9 ^ w3));
         Round(e, a, b, c, d, f2(a, b, c), k4, w2 = left(w2 ^ w15 ^ w10 ^ w4));
         Round(d, e, a, b, c, f2(e, a, b), k4, w3 = left(w3 ^ w0 ^ w11 ^ w5));
         Round(c, d, e, a, b, f2(d, e, a), k4, w4 = left(w4 ^ w1 ^ w12 ^ w6));
         Round(b, c, d, e, a, f2(c, d, e), k4, w5 = left(w5 ^ w2 ^ w13 ^ w7));
         Round(a, b, c, d, e, f2(b, c, d), k4, w6 = left(w6 ^ w3 ^ w14 ^ w8));
         Round(e, a, b, c, d, f2(a, b, c), k4, w7 = left(w7 ^ w4 ^ w15 ^ w9));
         Round(d, e, a, b, c, f2(e, a, b), k4, w8 = left(w8 ^ w5 ^ w0 ^ w10));
         Round(c, d, e, a, b, f2(d, e, a), k4, w9 = left(w9 ^ w6 ^ w1 ^ w11));
         Round(b, c, d, e, a, f2(c, d, e), k4, w10 = left(w10 ^ w7 ^ w2 ^ w12));
         Round(a, b, c, d, e, f2(b, c, d), k4, w11 = left(w11 ^ w8 ^ w3 ^ w13));
         Round(e, a, b, c, d, f2(a, b, c), k4, w12 = left(w12 ^ w9 ^ w4 ^ w14));
         Round(d, e, a, b, c, f2(e, a, b), k4, left(w13 ^ w10 ^ w5 ^ w15));
         Round(c, d, e, a, b, f2(d, e, a), k4, left(w14 ^ w11 ^ w6 ^ w0));
         Round(b, c, d, e, a, f2(c, d, e), k4, left(w15 ^ w12 ^ w7 ^ w1));
 
         s[0] += a;
         s[1] += b;
         s[2] += c;
         s[3] += d;
         s[4] += e;
     }
 
 } // namespace sha1
 
 } // namespace
 
 ////// SHA1
 
 CSHA1::CSHA1() : bytes(0) {
     sha1::Initialize(s);
 }
 
-CSHA1 &CSHA1::Write(const unsigned char *data, size_t len) {
-    const unsigned char *end = data + len;
+CSHA1 &CSHA1::Write(const uint8_t *data, size_t len) {
+    const uint8_t *end = data + len;
     size_t bufsize = bytes % 64;
     if (bufsize && bufsize + len >= 64) {
         // Fill the buffer, and process it.
         memcpy(buf + bufsize, data, 64 - bufsize);
         bytes += 64 - bufsize;
         data += 64 - bufsize;
         sha1::Transform(s, buf);
         bufsize = 0;
     }
     while (end >= data + 64) {
         // Process full chunks directly from the source.
         sha1::Transform(s, data);
         bytes += 64;
         data += 64;
     }
     if (end > data) {
         // Fill the buffer with what remains.
         memcpy(buf + bufsize, data, end - data);
         bytes += end - data;
     }
     return *this;
 }
 
-void CSHA1::Finalize(unsigned char hash[OUTPUT_SIZE]) {
-    static const unsigned char pad[64] = {0x80};
-    unsigned char sizedesc[8];
+void CSHA1::Finalize(uint8_t hash[OUTPUT_SIZE]) {
+    static const uint8_t pad[64] = {0x80};
+    uint8_t sizedesc[8];
     WriteBE64(sizedesc, bytes << 3);
     Write(pad, 1 + ((119 - (bytes % 64)) % 64));
     Write(sizedesc, 8);
     WriteBE32(hash, s[0]);
     WriteBE32(hash + 4, s[1]);
     WriteBE32(hash + 8, s[2]);
     WriteBE32(hash + 12, s[3]);
     WriteBE32(hash + 16, s[4]);
 }
 
 CSHA1 &CSHA1::Reset() {
     bytes = 0;
     sha1::Initialize(s);
     return *this;
 }
diff --git a/src/crypto/sha1.h b/src/crypto/sha1.h
index 6f81b0749..69923a43d 100644
--- a/src/crypto/sha1.h
+++ b/src/crypto/sha1.h
@@ -1,27 +1,27 @@
 // Copyright (c) 2014-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.
 
 #ifndef BITCOIN_CRYPTO_SHA1_H
 #define BITCOIN_CRYPTO_SHA1_H
 
 #include <cstdint>
 #include <cstdlib>
 
 /** A hasher class for SHA1. */
 class CSHA1 {
 private:
     uint32_t s[5];
-    unsigned char buf[64];
+    uint8_t buf[64];
     uint64_t bytes;
 
 public:
     static const size_t OUTPUT_SIZE = 20;
 
     CSHA1();
-    CSHA1 &Write(const unsigned char *data, size_t len);
-    void Finalize(unsigned char hash[OUTPUT_SIZE]);
+    CSHA1 &Write(const uint8_t *data, size_t len);
+    void Finalize(uint8_t hash[OUTPUT_SIZE]);
     CSHA1 &Reset();
 };
 
 #endif // BITCOIN_CRYPTO_SHA1_H
diff --git a/src/crypto/sha256.cpp b/src/crypto/sha256.cpp
index 17889ed7d..d00ab93b9 100644
--- a/src/crypto/sha256.cpp
+++ b/src/crypto/sha256.cpp
@@ -1,243 +1,243 @@
 // Copyright (c) 2014 The Bitcoin Core developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #include "crypto/sha256.h"
 
 #include "crypto/common.h"
 
 #include <cstring>
 
 // Internal implementation code.
 namespace {
 /// Internal SHA-256 implementation.
 namespace sha256 {
     inline uint32_t Ch(uint32_t x, uint32_t y, uint32_t z) {
         return z ^ (x & (y ^ z));
     }
     inline uint32_t Maj(uint32_t x, uint32_t y, uint32_t z) {
         return (x & y) | (z & (x | y));
     }
     inline uint32_t Sigma0(uint32_t x) {
         return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10);
     }
     inline uint32_t Sigma1(uint32_t x) {
         return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7);
     }
     inline uint32_t sigma0(uint32_t x) {
         return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3);
     }
     inline uint32_t sigma1(uint32_t x) {
         return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10);
     }
 
     /** One round of SHA-256. */
     inline void Round(uint32_t a, uint32_t b, uint32_t c, uint32_t &d,
                       uint32_t e, uint32_t f, uint32_t g, uint32_t &h,
                       uint32_t k, uint32_t w) {
         uint32_t t1 = h + Sigma1(e) + Ch(e, f, g) + k + w;
         uint32_t t2 = Sigma0(a) + Maj(a, b, c);
         d += t1;
         h = t1 + t2;
     }
 
     /** Initialize SHA-256 state. */
     inline void Initialize(uint32_t *s) {
         s[0] = 0x6a09e667ul;
         s[1] = 0xbb67ae85ul;
         s[2] = 0x3c6ef372ul;
         s[3] = 0xa54ff53aul;
         s[4] = 0x510e527ful;
         s[5] = 0x9b05688cul;
         s[6] = 0x1f83d9abul;
         s[7] = 0x5be0cd19ul;
     }
 
     /** Perform one SHA-256 transformation, processing a 64-byte chunk. */
-    void Transform(uint32_t *s, const unsigned char *chunk) {
+    void Transform(uint32_t *s, const uint8_t *chunk) {
         uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5],
                  g = s[6], h = s[7];
         uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13,
             w14, w15;
 
         Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = ReadBE32(chunk + 0));
         Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = ReadBE32(chunk + 4));
         Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = ReadBE32(chunk + 8));
         Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = ReadBE32(chunk + 12));
         Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = ReadBE32(chunk + 16));
         Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = ReadBE32(chunk + 20));
         Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = ReadBE32(chunk + 24));
         Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = ReadBE32(chunk + 28));
         Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = ReadBE32(chunk + 32));
         Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = ReadBE32(chunk + 36));
         Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = ReadBE32(chunk + 40));
         Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = ReadBE32(chunk + 44));
         Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = ReadBE32(chunk + 48));
         Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = ReadBE32(chunk + 52));
         Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = ReadBE32(chunk + 56));
         Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = ReadBE32(chunk + 60));
 
         Round(a, b, c, d, e, f, g, h, 0xe49b69c1,
               w0 += sigma1(w14) + w9 + sigma0(w1));
         Round(h, a, b, c, d, e, f, g, 0xefbe4786,
               w1 += sigma1(w15) + w10 + sigma0(w2));
         Round(g, h, a, b, c, d, e, f, 0x0fc19dc6,
               w2 += sigma1(w0) + w11 + sigma0(w3));
         Round(f, g, h, a, b, c, d, e, 0x240ca1cc,
               w3 += sigma1(w1) + w12 + sigma0(w4));
         Round(e, f, g, h, a, b, c, d, 0x2de92c6f,
               w4 += sigma1(w2) + w13 + sigma0(w5));
         Round(d, e, f, g, h, a, b, c, 0x4a7484aa,
               w5 += sigma1(w3) + w14 + sigma0(w6));
         Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc,
               w6 += sigma1(w4) + w15 + sigma0(w7));
         Round(b, c, d, e, f, g, h, a, 0x76f988da,
               w7 += sigma1(w5) + w0 + sigma0(w8));
         Round(a, b, c, d, e, f, g, h, 0x983e5152,
               w8 += sigma1(w6) + w1 + sigma0(w9));
         Round(h, a, b, c, d, e, f, g, 0xa831c66d,
               w9 += sigma1(w7) + w2 + sigma0(w10));
         Round(g, h, a, b, c, d, e, f, 0xb00327c8,
               w10 += sigma1(w8) + w3 + sigma0(w11));
         Round(f, g, h, a, b, c, d, e, 0xbf597fc7,
               w11 += sigma1(w9) + w4 + sigma0(w12));
         Round(e, f, g, h, a, b, c, d, 0xc6e00bf3,
               w12 += sigma1(w10) + w5 + sigma0(w13));
         Round(d, e, f, g, h, a, b, c, 0xd5a79147,
               w13 += sigma1(w11) + w6 + sigma0(w14));
         Round(c, d, e, f, g, h, a, b, 0x06ca6351,
               w14 += sigma1(w12) + w7 + sigma0(w15));
         Round(b, c, d, e, f, g, h, a, 0x14292967,
               w15 += sigma1(w13) + w8 + sigma0(w0));
 
         Round(a, b, c, d, e, f, g, h, 0x27b70a85,
               w0 += sigma1(w14) + w9 + sigma0(w1));
         Round(h, a, b, c, d, e, f, g, 0x2e1b2138,
               w1 += sigma1(w15) + w10 + sigma0(w2));
         Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc,
               w2 += sigma1(w0) + w11 + sigma0(w3));
         Round(f, g, h, a, b, c, d, e, 0x53380d13,
               w3 += sigma1(w1) + w12 + sigma0(w4));
         Round(e, f, g, h, a, b, c, d, 0x650a7354,
               w4 += sigma1(w2) + w13 + sigma0(w5));
         Round(d, e, f, g, h, a, b, c, 0x766a0abb,
               w5 += sigma1(w3) + w14 + sigma0(w6));
         Round(c, d, e, f, g, h, a, b, 0x81c2c92e,
               w6 += sigma1(w4) + w15 + sigma0(w7));
         Round(b, c, d, e, f, g, h, a, 0x92722c85,
               w7 += sigma1(w5) + w0 + sigma0(w8));
         Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1,
               w8 += sigma1(w6) + w1 + sigma0(w9));
         Round(h, a, b, c, d, e, f, g, 0xa81a664b,
               w9 += sigma1(w7) + w2 + sigma0(w10));
         Round(g, h, a, b, c, d, e, f, 0xc24b8b70,
               w10 += sigma1(w8) + w3 + sigma0(w11));
         Round(f, g, h, a, b, c, d, e, 0xc76c51a3,
               w11 += sigma1(w9) + w4 + sigma0(w12));
         Round(e, f, g, h, a, b, c, d, 0xd192e819,
               w12 += sigma1(w10) + w5 + sigma0(w13));
         Round(d, e, f, g, h, a, b, c, 0xd6990624,
               w13 += sigma1(w11) + w6 + sigma0(w14));
         Round(c, d, e, f, g, h, a, b, 0xf40e3585,
               w14 += sigma1(w12) + w7 + sigma0(w15));
         Round(b, c, d, e, f, g, h, a, 0x106aa070,
               w15 += sigma1(w13) + w8 + sigma0(w0));
 
         Round(a, b, c, d, e, f, g, h, 0x19a4c116,
               w0 += sigma1(w14) + w9 + sigma0(w1));
         Round(h, a, b, c, d, e, f, g, 0x1e376c08,
               w1 += sigma1(w15) + w10 + sigma0(w2));
         Round(g, h, a, b, c, d, e, f, 0x2748774c,
               w2 += sigma1(w0) + w11 + sigma0(w3));
         Round(f, g, h, a, b, c, d, e, 0x34b0bcb5,
               w3 += sigma1(w1) + w12 + sigma0(w4));
         Round(e, f, g, h, a, b, c, d, 0x391c0cb3,
               w4 += sigma1(w2) + w13 + sigma0(w5));
         Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a,
               w5 += sigma1(w3) + w14 + sigma0(w6));
         Round(c, d, e, f, g, h, a, b, 0x5b9cca4f,
               w6 += sigma1(w4) + w15 + sigma0(w7));
         Round(b, c, d, e, f, g, h, a, 0x682e6ff3,
               w7 += sigma1(w5) + w0 + sigma0(w8));
         Round(a, b, c, d, e, f, g, h, 0x748f82ee,
               w8 += sigma1(w6) + w1 + sigma0(w9));
         Round(h, a, b, c, d, e, f, g, 0x78a5636f,
               w9 += sigma1(w7) + w2 + sigma0(w10));
         Round(g, h, a, b, c, d, e, f, 0x84c87814,
               w10 += sigma1(w8) + w3 + sigma0(w11));
         Round(f, g, h, a, b, c, d, e, 0x8cc70208,
               w11 += sigma1(w9) + w4 + sigma0(w12));
         Round(e, f, g, h, a, b, c, d, 0x90befffa,
               w12 += sigma1(w10) + w5 + sigma0(w13));
         Round(d, e, f, g, h, a, b, c, 0xa4506ceb,
               w13 += sigma1(w11) + w6 + sigma0(w14));
         Round(c, d, e, f, g, h, a, b, 0xbef9a3f7,
               w14 + sigma1(w12) + w7 + sigma0(w15));
         Round(b, c, d, e, f, g, h, a, 0xc67178f2,
               w15 + sigma1(w13) + w8 + sigma0(w0));
 
         s[0] += a;
         s[1] += b;
         s[2] += c;
         s[3] += d;
         s[4] += e;
         s[5] += f;
         s[6] += g;
         s[7] += h;
     }
 
 } // namespace sha256
 } // namespace
 
 ////// SHA-256
 
 CSHA256::CSHA256() : bytes(0) {
     sha256::Initialize(s);
 }
 
-CSHA256 &CSHA256::Write(const unsigned char *data, size_t len) {
-    const unsigned char *end = data + len;
+CSHA256 &CSHA256::Write(const uint8_t *data, size_t len) {
+    const uint8_t *end = data + len;
     size_t bufsize = bytes % 64;
     if (bufsize && bufsize + len >= 64) {
         // Fill the buffer, and process it.
         memcpy(buf + bufsize, data, 64 - bufsize);
         bytes += 64 - bufsize;
         data += 64 - bufsize;
         sha256::Transform(s, buf);
         bufsize = 0;
     }
     while (end >= data + 64) {
         // Process full chunks directly from the source.
         sha256::Transform(s, data);
         bytes += 64;
         data += 64;
     }
     if (end > data) {
         // Fill the buffer with what remains.
         memcpy(buf + bufsize, data, end - data);
         bytes += end - data;
     }
     return *this;
 }
 
-void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE]) {
-    static const unsigned char pad[64] = {0x80};
-    unsigned char sizedesc[8];
+void CSHA256::Finalize(uint8_t hash[OUTPUT_SIZE]) {
+    static const uint8_t pad[64] = {0x80};
+    uint8_t sizedesc[8];
     WriteBE64(sizedesc, bytes << 3);
     Write(pad, 1 + ((119 - (bytes % 64)) % 64));
     Write(sizedesc, 8);
     WriteBE32(hash, s[0]);
     WriteBE32(hash + 4, s[1]);
     WriteBE32(hash + 8, s[2]);
     WriteBE32(hash + 12, s[3]);
     WriteBE32(hash + 16, s[4]);
     WriteBE32(hash + 20, s[5]);
     WriteBE32(hash + 24, s[6]);
     WriteBE32(hash + 28, s[7]);
 }
 
 CSHA256 &CSHA256::Reset() {
     bytes = 0;
     sha256::Initialize(s);
     return *this;
 }
diff --git a/src/crypto/sha256.h b/src/crypto/sha256.h
index f3e6b25f8..471adcef1 100644
--- a/src/crypto/sha256.h
+++ b/src/crypto/sha256.h
@@ -1,27 +1,27 @@
 // Copyright (c) 2014-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.
 
 #ifndef BITCOIN_CRYPTO_SHA256_H
 #define BITCOIN_CRYPTO_SHA256_H
 
 #include <cstdint>
 #include <cstdlib>
 
 /** A hasher class for SHA-256. */
 class CSHA256 {
 private:
     uint32_t s[8];
-    unsigned char buf[64];
+    uint8_t buf[64];
     uint64_t bytes;
 
 public:
     static const size_t OUTPUT_SIZE = 32;
 
     CSHA256();
-    CSHA256 &Write(const unsigned char *data, size_t len);
-    void Finalize(unsigned char hash[OUTPUT_SIZE]);
+    CSHA256 &Write(const uint8_t *data, size_t len);
+    void Finalize(uint8_t hash[OUTPUT_SIZE]);
     CSHA256 &Reset();
 };
 
 #endif // BITCOIN_CRYPTO_SHA256_H
diff --git a/src/crypto/sha512.cpp b/src/crypto/sha512.cpp
index 3a945a51b..ccdc79e18 100644
--- a/src/crypto/sha512.cpp
+++ b/src/crypto/sha512.cpp
@@ -1,293 +1,293 @@
 // Copyright (c) 2014 The Bitcoin Core developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #include "crypto/sha512.h"
 
 #include "crypto/common.h"
 
 #include <cstring>
 
 // Internal implementation code.
 namespace {
 /// Internal SHA-512 implementation.
 namespace sha512 {
     inline uint64_t Ch(uint64_t x, uint64_t y, uint64_t z) {
         return z ^ (x & (y ^ z));
     }
     inline uint64_t Maj(uint64_t x, uint64_t y, uint64_t z) {
         return (x & y) | (z & (x | y));
     }
     inline uint64_t Sigma0(uint64_t x) {
         return (x >> 28 | x << 36) ^ (x >> 34 | x << 30) ^ (x >> 39 | x << 25);
     }
     inline uint64_t Sigma1(uint64_t x) {
         return (x >> 14 | x << 50) ^ (x >> 18 | x << 46) ^ (x >> 41 | x << 23);
     }
     inline uint64_t sigma0(uint64_t x) {
         return (x >> 1 | x << 63) ^ (x >> 8 | x << 56) ^ (x >> 7);
     }
     inline uint64_t sigma1(uint64_t x) {
         return (x >> 19 | x << 45) ^ (x >> 61 | x << 3) ^ (x >> 6);
     }
 
     /** One round of SHA-512. */
     inline void Round(uint64_t a, uint64_t b, uint64_t c, uint64_t &d,
                       uint64_t e, uint64_t f, uint64_t g, uint64_t &h,
                       uint64_t k, uint64_t w) {
         uint64_t t1 = h + Sigma1(e) + Ch(e, f, g) + k + w;
         uint64_t t2 = Sigma0(a) + Maj(a, b, c);
         d += t1;
         h = t1 + t2;
     }
 
     /** Initialize SHA-256 state. */
     inline void Initialize(uint64_t *s) {
         s[0] = 0x6a09e667f3bcc908ull;
         s[1] = 0xbb67ae8584caa73bull;
         s[2] = 0x3c6ef372fe94f82bull;
         s[3] = 0xa54ff53a5f1d36f1ull;
         s[4] = 0x510e527fade682d1ull;
         s[5] = 0x9b05688c2b3e6c1full;
         s[6] = 0x1f83d9abfb41bd6bull;
         s[7] = 0x5be0cd19137e2179ull;
     }
 
     /** Perform one SHA-512 transformation, processing a 128-byte chunk. */
-    void Transform(uint64_t *s, const unsigned char *chunk) {
+    void Transform(uint64_t *s, const uint8_t *chunk) {
         uint64_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5],
                  g = s[6], h = s[7];
         uint64_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13,
             w14, w15;
 
         Round(a, b, c, d, e, f, g, h, 0x428a2f98d728ae22ull,
               w0 = ReadBE64(chunk + 0));
         Round(h, a, b, c, d, e, f, g, 0x7137449123ef65cdull,
               w1 = ReadBE64(chunk + 8));
         Round(g, h, a, b, c, d, e, f, 0xb5c0fbcfec4d3b2full,
               w2 = ReadBE64(chunk + 16));
         Round(f, g, h, a, b, c, d, e, 0xe9b5dba58189dbbcull,
               w3 = ReadBE64(chunk + 24));
         Round(e, f, g, h, a, b, c, d, 0x3956c25bf348b538ull,
               w4 = ReadBE64(chunk + 32));
         Round(d, e, f, g, h, a, b, c, 0x59f111f1b605d019ull,
               w5 = ReadBE64(chunk + 40));
         Round(c, d, e, f, g, h, a, b, 0x923f82a4af194f9bull,
               w6 = ReadBE64(chunk + 48));
         Round(b, c, d, e, f, g, h, a, 0xab1c5ed5da6d8118ull,
               w7 = ReadBE64(chunk + 56));
         Round(a, b, c, d, e, f, g, h, 0xd807aa98a3030242ull,
               w8 = ReadBE64(chunk + 64));
         Round(h, a, b, c, d, e, f, g, 0x12835b0145706fbeull,
               w9 = ReadBE64(chunk + 72));
         Round(g, h, a, b, c, d, e, f, 0x243185be4ee4b28cull,
               w10 = ReadBE64(chunk + 80));
         Round(f, g, h, a, b, c, d, e, 0x550c7dc3d5ffb4e2ull,
               w11 = ReadBE64(chunk + 88));
         Round(e, f, g, h, a, b, c, d, 0x72be5d74f27b896full,
               w12 = ReadBE64(chunk + 96));
         Round(d, e, f, g, h, a, b, c, 0x80deb1fe3b1696b1ull,
               w13 = ReadBE64(chunk + 104));
         Round(c, d, e, f, g, h, a, b, 0x9bdc06a725c71235ull,
               w14 = ReadBE64(chunk + 112));
         Round(b, c, d, e, f, g, h, a, 0xc19bf174cf692694ull,
               w15 = ReadBE64(chunk + 120));
 
         Round(a, b, c, d, e, f, g, h, 0xe49b69c19ef14ad2ull,
               w0 += sigma1(w14) + w9 + sigma0(w1));
         Round(h, a, b, c, d, e, f, g, 0xefbe4786384f25e3ull,
               w1 += sigma1(w15) + w10 + sigma0(w2));
         Round(g, h, a, b, c, d, e, f, 0x0fc19dc68b8cd5b5ull,
               w2 += sigma1(w0) + w11 + sigma0(w3));
         Round(f, g, h, a, b, c, d, e, 0x240ca1cc77ac9c65ull,
               w3 += sigma1(w1) + w12 + sigma0(w4));
         Round(e, f, g, h, a, b, c, d, 0x2de92c6f592b0275ull,
               w4 += sigma1(w2) + w13 + sigma0(w5));
         Round(d, e, f, g, h, a, b, c, 0x4a7484aa6ea6e483ull,
               w5 += sigma1(w3) + w14 + sigma0(w6));
         Round(c, d, e, f, g, h, a, b, 0x5cb0a9dcbd41fbd4ull,
               w6 += sigma1(w4) + w15 + sigma0(w7));
         Round(b, c, d, e, f, g, h, a, 0x76f988da831153b5ull,
               w7 += sigma1(w5) + w0 + sigma0(w8));
         Round(a, b, c, d, e, f, g, h, 0x983e5152ee66dfabull,
               w8 += sigma1(w6) + w1 + sigma0(w9));
         Round(h, a, b, c, d, e, f, g, 0xa831c66d2db43210ull,
               w9 += sigma1(w7) + w2 + sigma0(w10));
         Round(g, h, a, b, c, d, e, f, 0xb00327c898fb213full,
               w10 += sigma1(w8) + w3 + sigma0(w11));
         Round(f, g, h, a, b, c, d, e, 0xbf597fc7beef0ee4ull,
               w11 += sigma1(w9) + w4 + sigma0(w12));
         Round(e, f, g, h, a, b, c, d, 0xc6e00bf33da88fc2ull,
               w12 += sigma1(w10) + w5 + sigma0(w13));
         Round(d, e, f, g, h, a, b, c, 0xd5a79147930aa725ull,
               w13 += sigma1(w11) + w6 + sigma0(w14));
         Round(c, d, e, f, g, h, a, b, 0x06ca6351e003826full,
               w14 += sigma1(w12) + w7 + sigma0(w15));
         Round(b, c, d, e, f, g, h, a, 0x142929670a0e6e70ull,
               w15 += sigma1(w13) + w8 + sigma0(w0));
 
         Round(a, b, c, d, e, f, g, h, 0x27b70a8546d22ffcull,
               w0 += sigma1(w14) + w9 + sigma0(w1));
         Round(h, a, b, c, d, e, f, g, 0x2e1b21385c26c926ull,
               w1 += sigma1(w15) + w10 + sigma0(w2));
         Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc5ac42aedull,
               w2 += sigma1(w0) + w11 + sigma0(w3));
         Round(f, g, h, a, b, c, d, e, 0x53380d139d95b3dfull,
               w3 += sigma1(w1) + w12 + sigma0(w4));
         Round(e, f, g, h, a, b, c, d, 0x650a73548baf63deull,
               w4 += sigma1(w2) + w13 + sigma0(w5));
         Round(d, e, f, g, h, a, b, c, 0x766a0abb3c77b2a8ull,
               w5 += sigma1(w3) + w14 + sigma0(w6));
         Round(c, d, e, f, g, h, a, b, 0x81c2c92e47edaee6ull,
               w6 += sigma1(w4) + w15 + sigma0(w7));
         Round(b, c, d, e, f, g, h, a, 0x92722c851482353bull,
               w7 += sigma1(w5) + w0 + sigma0(w8));
         Round(a, b, c, d, e, f, g, h, 0xa2bfe8a14cf10364ull,
               w8 += sigma1(w6) + w1 + sigma0(w9));
         Round(h, a, b, c, d, e, f, g, 0xa81a664bbc423001ull,
               w9 += sigma1(w7) + w2 + sigma0(w10));
         Round(g, h, a, b, c, d, e, f, 0xc24b8b70d0f89791ull,
               w10 += sigma1(w8) + w3 + sigma0(w11));
         Round(f, g, h, a, b, c, d, e, 0xc76c51a30654be30ull,
               w11 += sigma1(w9) + w4 + sigma0(w12));
         Round(e, f, g, h, a, b, c, d, 0xd192e819d6ef5218ull,
               w12 += sigma1(w10) + w5 + sigma0(w13));
         Round(d, e, f, g, h, a, b, c, 0xd69906245565a910ull,
               w13 += sigma1(w11) + w6 + sigma0(w14));
         Round(c, d, e, f, g, h, a, b, 0xf40e35855771202aull,
               w14 += sigma1(w12) + w7 + sigma0(w15));
         Round(b, c, d, e, f, g, h, a, 0x106aa07032bbd1b8ull,
               w15 += sigma1(w13) + w8 + sigma0(w0));
 
         Round(a, b, c, d, e, f, g, h, 0x19a4c116b8d2d0c8ull,
               w0 += sigma1(w14) + w9 + sigma0(w1));
         Round(h, a, b, c, d, e, f, g, 0x1e376c085141ab53ull,
               w1 += sigma1(w15) + w10 + sigma0(w2));
         Round(g, h, a, b, c, d, e, f, 0x2748774cdf8eeb99ull,
               w2 += sigma1(w0) + w11 + sigma0(w3));
         Round(f, g, h, a, b, c, d, e, 0x34b0bcb5e19b48a8ull,
               w3 += sigma1(w1) + w12 + sigma0(w4));
         Round(e, f, g, h, a, b, c, d, 0x391c0cb3c5c95a63ull,
               w4 += sigma1(w2) + w13 + sigma0(w5));
         Round(d, e, f, g, h, a, b, c, 0x4ed8aa4ae3418acbull,
               w5 += sigma1(w3) + w14 + sigma0(w6));
         Round(c, d, e, f, g, h, a, b, 0x5b9cca4f7763e373ull,
               w6 += sigma1(w4) + w15 + sigma0(w7));
         Round(b, c, d, e, f, g, h, a, 0x682e6ff3d6b2b8a3ull,
               w7 += sigma1(w5) + w0 + sigma0(w8));
         Round(a, b, c, d, e, f, g, h, 0x748f82ee5defb2fcull,
               w8 += sigma1(w6) + w1 + sigma0(w9));
         Round(h, a, b, c, d, e, f, g, 0x78a5636f43172f60ull,
               w9 += sigma1(w7) + w2 + sigma0(w10));
         Round(g, h, a, b, c, d, e, f, 0x84c87814a1f0ab72ull,
               w10 += sigma1(w8) + w3 + sigma0(w11));
         Round(f, g, h, a, b, c, d, e, 0x8cc702081a6439ecull,
               w11 += sigma1(w9) + w4 + sigma0(w12));
         Round(e, f, g, h, a, b, c, d, 0x90befffa23631e28ull,
               w12 += sigma1(w10) + w5 + sigma0(w13));
         Round(d, e, f, g, h, a, b, c, 0xa4506cebde82bde9ull,
               w13 += sigma1(w11) + w6 + sigma0(w14));
         Round(c, d, e, f, g, h, a, b, 0xbef9a3f7b2c67915ull,
               w14 += sigma1(w12) + w7 + sigma0(w15));
         Round(b, c, d, e, f, g, h, a, 0xc67178f2e372532bull,
               w15 += sigma1(w13) + w8 + sigma0(w0));
 
         Round(a, b, c, d, e, f, g, h, 0xca273eceea26619cull,
               w0 += sigma1(w14) + w9 + sigma0(w1));
         Round(h, a, b, c, d, e, f, g, 0xd186b8c721c0c207ull,
               w1 += sigma1(w15) + w10 + sigma0(w2));
         Round(g, h, a, b, c, d, e, f, 0xeada7dd6cde0eb1eull,
               w2 += sigma1(w0) + w11 + sigma0(w3));
         Round(f, g, h, a, b, c, d, e, 0xf57d4f7fee6ed178ull,
               w3 += sigma1(w1) + w12 + sigma0(w4));
         Round(e, f, g, h, a, b, c, d, 0x06f067aa72176fbaull,
               w4 += sigma1(w2) + w13 + sigma0(w5));
         Round(d, e, f, g, h, a, b, c, 0x0a637dc5a2c898a6ull,
               w5 += sigma1(w3) + w14 + sigma0(w6));
         Round(c, d, e, f, g, h, a, b, 0x113f9804bef90daeull,
               w6 += sigma1(w4) + w15 + sigma0(w7));
         Round(b, c, d, e, f, g, h, a, 0x1b710b35131c471bull,
               w7 += sigma1(w5) + w0 + sigma0(w8));
         Round(a, b, c, d, e, f, g, h, 0x28db77f523047d84ull,
               w8 += sigma1(w6) + w1 + sigma0(w9));
         Round(h, a, b, c, d, e, f, g, 0x32caab7b40c72493ull,
               w9 += sigma1(w7) + w2 + sigma0(w10));
         Round(g, h, a, b, c, d, e, f, 0x3c9ebe0a15c9bebcull,
               w10 += sigma1(w8) + w3 + sigma0(w11));
         Round(f, g, h, a, b, c, d, e, 0x431d67c49c100d4cull,
               w11 += sigma1(w9) + w4 + sigma0(w12));
         Round(e, f, g, h, a, b, c, d, 0x4cc5d4becb3e42b6ull,
               w12 += sigma1(w10) + w5 + sigma0(w13));
         Round(d, e, f, g, h, a, b, c, 0x597f299cfc657e2aull,
               w13 += sigma1(w11) + w6 + sigma0(w14));
         Round(c, d, e, f, g, h, a, b, 0x5fcb6fab3ad6faecull,
               w14 + sigma1(w12) + w7 + sigma0(w15));
         Round(b, c, d, e, f, g, h, a, 0x6c44198c4a475817ull,
               w15 + sigma1(w13) + w8 + sigma0(w0));
 
         s[0] += a;
         s[1] += b;
         s[2] += c;
         s[3] += d;
         s[4] += e;
         s[5] += f;
         s[6] += g;
         s[7] += h;
     }
 
 } // namespace sha512
 
 } // namespace
 
 ////// SHA-512
 
 CSHA512::CSHA512() : bytes(0) {
     sha512::Initialize(s);
 }
 
-CSHA512 &CSHA512::Write(const unsigned char *data, size_t len) {
-    const unsigned char *end = data + len;
+CSHA512 &CSHA512::Write(const uint8_t *data, size_t len) {
+    const uint8_t *end = data + len;
     size_t bufsize = bytes % 128;
     if (bufsize && bufsize + len >= 128) {
         // Fill the buffer, and process it.
         memcpy(buf + bufsize, data, 128 - bufsize);
         bytes += 128 - bufsize;
         data += 128 - bufsize;
         sha512::Transform(s, buf);
         bufsize = 0;
     }
     while (end >= data + 128) {
         // Process full chunks directly from the source.
         sha512::Transform(s, data);
         data += 128;
         bytes += 128;
     }
     if (end > data) {
         // Fill the buffer with what remains.
         memcpy(buf + bufsize, data, end - data);
         bytes += end - data;
     }
     return *this;
 }
 
-void CSHA512::Finalize(unsigned char hash[OUTPUT_SIZE]) {
-    static const unsigned char pad[128] = {0x80};
-    unsigned char sizedesc[16] = {0x00};
+void CSHA512::Finalize(uint8_t hash[OUTPUT_SIZE]) {
+    static const uint8_t pad[128] = {0x80};
+    uint8_t sizedesc[16] = {0x00};
     WriteBE64(sizedesc + 8, bytes << 3);
     Write(pad, 1 + ((239 - (bytes % 128)) % 128));
     Write(sizedesc, 16);
     WriteBE64(hash, s[0]);
     WriteBE64(hash + 8, s[1]);
     WriteBE64(hash + 16, s[2]);
     WriteBE64(hash + 24, s[3]);
     WriteBE64(hash + 32, s[4]);
     WriteBE64(hash + 40, s[5]);
     WriteBE64(hash + 48, s[6]);
     WriteBE64(hash + 56, s[7]);
 }
 
 CSHA512 &CSHA512::Reset() {
     bytes = 0;
     sha512::Initialize(s);
     return *this;
 }
diff --git a/src/crypto/sha512.h b/src/crypto/sha512.h
index 2703dd895..8195ba59f 100644
--- a/src/crypto/sha512.h
+++ b/src/crypto/sha512.h
@@ -1,27 +1,27 @@
 // Copyright (c) 2014-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.
 
 #ifndef BITCOIN_CRYPTO_SHA512_H
 #define BITCOIN_CRYPTO_SHA512_H
 
 #include <cstdint>
 #include <cstdlib>
 
 /** A hasher class for SHA-512. */
 class CSHA512 {
 private:
     uint64_t s[8];
-    unsigned char buf[128];
+    uint8_t buf[128];
     uint64_t bytes;
 
 public:
     static const size_t OUTPUT_SIZE = 64;
 
     CSHA512();
-    CSHA512 &Write(const unsigned char *data, size_t len);
-    void Finalize(unsigned char hash[OUTPUT_SIZE]);
+    CSHA512 &Write(const uint8_t *data, size_t len);
+    void Finalize(uint8_t hash[OUTPUT_SIZE]);
     CSHA512 &Reset();
 };
 
 #endif // BITCOIN_CRYPTO_SHA512_H
diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp
index b2292ff0d..c42b895a9 100644
--- a/src/dbwrapper.cpp
+++ b/src/dbwrapper.cpp
@@ -1,159 +1,159 @@
 // Copyright (c) 2012-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.
 
 #include "dbwrapper.h"
 
 #include "random.h"
 #include "util.h"
 
 #include <boost/filesystem.hpp>
 
 #include <cstdint>
 #include <leveldb/cache.h>
 #include <leveldb/env.h>
 #include <leveldb/filter_policy.h>
 #include <memenv.h>
 
 static leveldb::Options GetOptions(size_t nCacheSize) {
     leveldb::Options options;
     options.block_cache = leveldb::NewLRUCache(nCacheSize / 2);
     // up to two write buffers may be held in memory simultaneously
     options.write_buffer_size = nCacheSize / 4;
     options.filter_policy = leveldb::NewBloomFilterPolicy(10);
     options.compression = leveldb::kNoCompression;
     options.max_open_files = 64;
     if (leveldb::kMajorVersion > 1 ||
         (leveldb::kMajorVersion == 1 && leveldb::kMinorVersion >= 16)) {
         // LevelDB versions before 1.16 consider short writes to be corruption.
         // Only trigger error on corruption in later versions.
         options.paranoid_checks = true;
     }
     return options;
 }
 
 CDBWrapper::CDBWrapper(const boost::filesystem::path &path, size_t nCacheSize,
                        bool fMemory, bool fWipe, bool obfuscate) {
     penv = nullptr;
     readoptions.verify_checksums = true;
     iteroptions.verify_checksums = true;
     iteroptions.fill_cache = false;
     syncoptions.sync = true;
     options = GetOptions(nCacheSize);
     options.create_if_missing = true;
     if (fMemory) {
         penv = leveldb::NewMemEnv(leveldb::Env::Default());
         options.env = penv;
     } else {
         if (fWipe) {
             LogPrintf("Wiping LevelDB in %s\n", path.string());
             leveldb::Status result = leveldb::DestroyDB(path.string(), options);
             dbwrapper_private::HandleError(result);
         }
         TryCreateDirectory(path);
         LogPrintf("Opening LevelDB in %s\n", path.string());
     }
     leveldb::Status status = leveldb::DB::Open(options, path.string(), &pdb);
     dbwrapper_private::HandleError(status);
     LogPrintf("Opened LevelDB successfully\n");
 
     // The base-case obfuscation key, which is a noop.
-    obfuscate_key = std::vector<unsigned char>(OBFUSCATE_KEY_NUM_BYTES, '\000');
+    obfuscate_key = std::vector<uint8_t>(OBFUSCATE_KEY_NUM_BYTES, '\000');
 
     bool key_exists = Read(OBFUSCATE_KEY_KEY, obfuscate_key);
 
     if (!key_exists && obfuscate && IsEmpty()) {
         // Initialize non-degenerate obfuscation if it won't upset existing,
         // non-obfuscated data.
-        std::vector<unsigned char> new_key = CreateObfuscateKey();
+        std::vector<uint8_t> new_key = CreateObfuscateKey();
 
         // Write `new_key` so we don't obfuscate the key with itself
         Write(OBFUSCATE_KEY_KEY, new_key);
         obfuscate_key = new_key;
 
         LogPrintf("Wrote new obfuscate key for %s: %s\n", path.string(),
                   HexStr(obfuscate_key));
     }
 
     LogPrintf("Using obfuscation key for %s: %s\n", path.string(),
               HexStr(obfuscate_key));
 }
 
 CDBWrapper::~CDBWrapper() {
     delete pdb;
     pdb = nullptr;
     delete options.filter_policy;
     options.filter_policy = nullptr;
     delete options.block_cache;
     options.block_cache = nullptr;
     delete penv;
     options.env = nullptr;
 }
 
 bool CDBWrapper::WriteBatch(CDBBatch &batch, bool fSync) {
     leveldb::Status status =
         pdb->Write(fSync ? syncoptions : writeoptions, &batch.batch);
     dbwrapper_private::HandleError(status);
     return true;
 }
 
 // Prefixed with null character to avoid collisions with other keys
 //
 // We must use a string constructor which specifies length so that we copy past
 // the null-terminator.
 const std::string CDBWrapper::OBFUSCATE_KEY_KEY("\000obfuscate_key", 14);
 
 const unsigned int CDBWrapper::OBFUSCATE_KEY_NUM_BYTES = 8;
 
 /**
  * Returns a string (consisting of 8 random bytes) suitable for use as an
  * obfuscating XOR key.
  */
-std::vector<unsigned char> CDBWrapper::CreateObfuscateKey() const {
-    unsigned char buff[OBFUSCATE_KEY_NUM_BYTES];
+std::vector<uint8_t> CDBWrapper::CreateObfuscateKey() const {
+    uint8_t buff[OBFUSCATE_KEY_NUM_BYTES];
     GetRandBytes(buff, OBFUSCATE_KEY_NUM_BYTES);
-    return std::vector<unsigned char>(&buff[0], &buff[OBFUSCATE_KEY_NUM_BYTES]);
+    return std::vector<uint8_t>(&buff[0], &buff[OBFUSCATE_KEY_NUM_BYTES]);
 }
 
 bool CDBWrapper::IsEmpty() {
     std::unique_ptr<CDBIterator> it(NewIterator());
     it->SeekToFirst();
     return !(it->Valid());
 }
 
 CDBIterator::~CDBIterator() {
     delete piter;
 }
 bool CDBIterator::Valid() {
     return piter->Valid();
 }
 void CDBIterator::SeekToFirst() {
     piter->SeekToFirst();
 }
 void CDBIterator::Next() {
     piter->Next();
 }
 
 namespace dbwrapper_private {
 
 void HandleError(const leveldb::Status &status) {
     if (status.ok()) {
         return;
     }
     LogPrintf("%s\n", status.ToString());
     if (status.IsCorruption()) {
         throw dbwrapper_error("Database corrupted");
     }
     if (status.IsIOError()) {
         throw dbwrapper_error("Database I/O error");
     }
     if (status.IsNotFound()) {
         throw dbwrapper_error("Database entry missing");
     }
     throw dbwrapper_error("Unknown database error");
 }
 
-const std::vector<unsigned char> &GetObfuscateKey(const CDBWrapper &w) {
+const std::vector<uint8_t> &GetObfuscateKey(const CDBWrapper &w) {
     return w.obfuscate_key;
 }
 };
diff --git a/src/dbwrapper.h b/src/dbwrapper.h
index 11e948236..6520f9ea6 100644
--- a/src/dbwrapper.h
+++ b/src/dbwrapper.h
@@ -1,278 +1,278 @@
 // Copyright (c) 2012-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.
 
 #ifndef BITCOIN_DBWRAPPER_H
 #define BITCOIN_DBWRAPPER_H
 
 #include "clientversion.h"
 #include "serialize.h"
 #include "streams.h"
 #include "util.h"
 #include "utilstrencodings.h"
 #include "version.h"
 
 #include <boost/filesystem/path.hpp>
 
 #include <leveldb/db.h>
 #include <leveldb/write_batch.h>
 
 static const size_t DBWRAPPER_PREALLOC_KEY_SIZE = 64;
 static const size_t DBWRAPPER_PREALLOC_VALUE_SIZE = 1024;
 
 class dbwrapper_error : public std::runtime_error {
 public:
     dbwrapper_error(const std::string &msg) : std::runtime_error(msg) {}
 };
 
 class CDBWrapper;
 
 /**
  * These should be considered an implementation detail of the specific database.
  */
 namespace dbwrapper_private {
 
 /**
  * Handle database error by throwing dbwrapper_error exception.
  */
 void HandleError(const leveldb::Status &status);
 
 /**
  * Work around circular dependency, as well as for testing in dbwrapper_tests.
  * Database obfuscation should be considered an implementation detail of the
  * specific database.
  */
-const std::vector<unsigned char> &GetObfuscateKey(const CDBWrapper &w);
+const std::vector<uint8_t> &GetObfuscateKey(const CDBWrapper &w);
 };
 
 /** Batch of changes queued to be written to a CDBWrapper */
 class CDBBatch {
     friend class CDBWrapper;
 
 private:
     const CDBWrapper &parent;
     leveldb::WriteBatch batch;
 
     CDataStream ssKey;
     CDataStream ssValue;
 
 public:
     /**
      * @param[in] _parent   CDBWrapper that this batch is to be submitted to
      */
     CDBBatch(const CDBWrapper &_parent)
         : parent(_parent), ssKey(SER_DISK, CLIENT_VERSION),
           ssValue(SER_DISK, CLIENT_VERSION){};
 
     template <typename K, typename V> void Write(const K &key, const V &value) {
         ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
         ssKey << key;
         leveldb::Slice slKey(ssKey.data(), ssKey.size());
 
         ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
         ssValue << value;
         ssValue.Xor(dbwrapper_private::GetObfuscateKey(parent));
         leveldb::Slice slValue(ssValue.data(), ssValue.size());
 
         batch.Put(slKey, slValue);
         ssKey.clear();
         ssValue.clear();
     }
 
     template <typename K> void Erase(const K &key) {
         ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
         ssKey << key;
         leveldb::Slice slKey(ssKey.data(), ssKey.size());
 
         batch.Delete(slKey);
         ssKey.clear();
     }
 };
 
 class CDBIterator {
 private:
     const CDBWrapper &parent;
     leveldb::Iterator *piter;
 
 public:
     /**
      * @param[in] _parent          Parent CDBWrapper instance.
      * @param[in] _piter           The original leveldb iterator.
      */
     CDBIterator(const CDBWrapper &_parent, leveldb::Iterator *_piter)
         : parent(_parent), piter(_piter){};
     ~CDBIterator();
 
     bool Valid();
 
     void SeekToFirst();
 
     template <typename K> void Seek(const K &key) {
         CDataStream ssKey(SER_DISK, CLIENT_VERSION);
         ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
         ssKey << key;
         leveldb::Slice slKey(ssKey.data(), ssKey.size());
         piter->Seek(slKey);
     }
 
     void Next();
 
     template <typename K> bool GetKey(K &key) {
         leveldb::Slice slKey = piter->key();
         try {
             CDataStream ssKey(slKey.data(), slKey.data() + slKey.size(),
                               SER_DISK, CLIENT_VERSION);
             ssKey >> key;
         } catch (const std::exception &) {
             return false;
         }
         return true;
     }
 
     unsigned int GetKeySize() { return piter->key().size(); }
 
     template <typename V> bool GetValue(V &value) {
         leveldb::Slice slValue = piter->value();
         try {
             CDataStream ssValue(slValue.data(), slValue.data() + slValue.size(),
                                 SER_DISK, CLIENT_VERSION);
             ssValue.Xor(dbwrapper_private::GetObfuscateKey(parent));
             ssValue >> value;
         } catch (const std::exception &) {
             return false;
         }
         return true;
     }
 
     unsigned int GetValueSize() { return piter->value().size(); }
 };
 
 class CDBWrapper {
-    friend const std::vector<unsigned char> &
+    friend const std::vector<uint8_t> &
     dbwrapper_private::GetObfuscateKey(const CDBWrapper &w);
 
 private:
     //! custom environment this database is using (may be nullptr in case of
     //! default environment)
     leveldb::Env *penv;
 
     //! database options used
     leveldb::Options options;
 
     //! options used when reading from the database
     leveldb::ReadOptions readoptions;
 
     //! options used when iterating over values of the database
     leveldb::ReadOptions iteroptions;
 
     //! options used when writing to the database
     leveldb::WriteOptions writeoptions;
 
     //! options used when sync writing to the database
     leveldb::WriteOptions syncoptions;
 
     //! the database itself
     leveldb::DB *pdb;
 
     //! a key used for optional XOR-obfuscation of the database
-    std::vector<unsigned char> obfuscate_key;
+    std::vector<uint8_t> obfuscate_key;
 
     //! the key under which the obfuscation key is stored
     static const std::string OBFUSCATE_KEY_KEY;
 
     //! the length of the obfuscate key in number of bytes
     static const unsigned int OBFUSCATE_KEY_NUM_BYTES;
 
-    std::vector<unsigned char> CreateObfuscateKey() const;
+    std::vector<uint8_t> CreateObfuscateKey() const;
 
 public:
     /**
      * @param[in] path        Location in the filesystem where leveldb data will
      * be stored.
      * @param[in] nCacheSize  Configures various leveldb cache settings.
      * @param[in] fMemory     If true, use leveldb's memory environment.
      * @param[in] fWipe       If true, remove all existing data.
      * @param[in] obfuscate   If true, store data obfuscated via simple XOR. If
      * false, XOR
      *                        with a zero'd byte array.
      */
     CDBWrapper(const boost::filesystem::path &path, size_t nCacheSize,
                bool fMemory = false, bool fWipe = false,
                bool obfuscate = false);
     ~CDBWrapper();
 
     template <typename K, typename V> bool Read(const K &key, V &value) const {
         CDataStream ssKey(SER_DISK, CLIENT_VERSION);
         ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
         ssKey << key;
         leveldb::Slice slKey(ssKey.data(), ssKey.size());
 
         std::string strValue;
         leveldb::Status status = pdb->Get(readoptions, slKey, &strValue);
         if (!status.ok()) {
             if (status.IsNotFound()) return false;
             LogPrintf("LevelDB read failure: %s\n", status.ToString());
             dbwrapper_private::HandleError(status);
         }
         try {
             CDataStream ssValue(strValue.data(),
                                 strValue.data() + strValue.size(), SER_DISK,
                                 CLIENT_VERSION);
             ssValue.Xor(obfuscate_key);
             ssValue >> value;
         } catch (const std::exception &) {
             return false;
         }
         return true;
     }
 
     template <typename K, typename V>
     bool Write(const K &key, const V &value, bool fSync = false) {
         CDBBatch batch(*this);
         batch.Write(key, value);
         return WriteBatch(batch, fSync);
     }
 
     template <typename K> bool Exists(const K &key) const {
         CDataStream ssKey(SER_DISK, CLIENT_VERSION);
         ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
         ssKey << key;
         leveldb::Slice slKey(ssKey.data(), ssKey.size());
 
         std::string strValue;
         leveldb::Status status = pdb->Get(readoptions, slKey, &strValue);
         if (!status.ok()) {
             if (status.IsNotFound()) return false;
             LogPrintf("LevelDB read failure: %s\n", status.ToString());
             dbwrapper_private::HandleError(status);
         }
         return true;
     }
 
     template <typename K> bool Erase(const K &key, bool fSync = false) {
         CDBBatch batch(*this);
         batch.Erase(key);
         return WriteBatch(batch, fSync);
     }
 
     bool WriteBatch(CDBBatch &batch, bool fSync = false);
 
     // not available for LevelDB; provide for compatibility with BDB
     bool Flush() { return true; }
 
     bool Sync() {
         CDBBatch batch(*this);
         return WriteBatch(batch, true);
     }
 
     CDBIterator *NewIterator() {
         return new CDBIterator(*this, pdb->NewIterator(iteroptions));
     }
 
     /**
      * Return true if the database managed by this class contains no entries.
      */
     bool IsEmpty();
 };
 
 #endif // BITCOIN_DBWRAPPER_H
diff --git a/src/hash.cpp b/src/hash.cpp
index 3fb598d82..35c7e8161 100644
--- a/src/hash.cpp
+++ b/src/hash.cpp
@@ -1,219 +1,218 @@
 // 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.
 
 #include "hash.h"
 #include "crypto/common.h"
 #include "crypto/hmac_sha512.h"
 #include "pubkey.h"
 
 inline uint32_t ROTL32(uint32_t x, int8_t r) {
     return (x << r) | (x >> (32 - r));
 }
 
 unsigned int MurmurHash3(unsigned int nHashSeed,
-                         const std::vector<unsigned char> &vDataToHash) {
+                         const std::vector<uint8_t> &vDataToHash) {
     // The following is MurmurHash3 (x86_32), see
     // http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp
     uint32_t h1 = nHashSeed;
     if (vDataToHash.size() > 0) {
         const uint32_t c1 = 0xcc9e2d51;
         const uint32_t c2 = 0x1b873593;
 
         const int nblocks = vDataToHash.size() / 4;
 
         //----------
         // body
         const uint8_t *blocks = &vDataToHash[0] + nblocks * 4;
 
         for (int i = -nblocks; i; i++) {
             uint32_t k1 = ReadLE32(blocks + i * 4);
 
             k1 *= c1;
             k1 = ROTL32(k1, 15);
             k1 *= c2;
 
             h1 ^= k1;
             h1 = ROTL32(h1, 13);
             h1 = h1 * 5 + 0xe6546b64;
         }
 
         //----------
         // tail
         const uint8_t *tail = (const uint8_t *)(&vDataToHash[0] + nblocks * 4);
 
         uint32_t k1 = 0;
 
         switch (vDataToHash.size() & 3) {
             case 3:
                 k1 ^= tail[2] << 16;
             // FALLTHROUGH
             case 2:
                 k1 ^= tail[1] << 8;
             // FALLTHROUGH
             case 1:
                 k1 ^= tail[0];
                 k1 *= c1;
                 k1 = ROTL32(k1, 15);
                 k1 *= c2;
                 h1 ^= k1;
         }
     }
 
     //----------
     // finalization
     h1 ^= vDataToHash.size();
     h1 ^= h1 >> 16;
     h1 *= 0x85ebca6b;
     h1 ^= h1 >> 13;
     h1 *= 0xc2b2ae35;
     h1 ^= h1 >> 16;
 
     return h1;
 }
 
-void BIP32Hash(const ChainCode &chainCode, unsigned int nChild,
-               unsigned char header, const unsigned char data[32],
-               unsigned char output[64]) {
-    unsigned char num[4];
+void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, uint8_t header,
+               const uint8_t data[32], uint8_t output[64]) {
+    uint8_t num[4];
     num[0] = (nChild >> 24) & 0xFF;
     num[1] = (nChild >> 16) & 0xFF;
     num[2] = (nChild >> 8) & 0xFF;
     num[3] = (nChild >> 0) & 0xFF;
     CHMAC_SHA512(chainCode.begin(), chainCode.size())
         .Write(&header, 1)
         .Write(data, 32)
         .Write(num, 4)
         .Finalize(output);
 }
 
 #define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
 
 #define SIPROUND                                                               \
     do {                                                                       \
         v0 += v1;                                                              \
         v1 = ROTL(v1, 13);                                                     \
         v1 ^= v0;                                                              \
         v0 = ROTL(v0, 32);                                                     \
         v2 += v3;                                                              \
         v3 = ROTL(v3, 16);                                                     \
         v3 ^= v2;                                                              \
         v0 += v3;                                                              \
         v3 = ROTL(v3, 21);                                                     \
         v3 ^= v0;                                                              \
         v2 += v1;                                                              \
         v1 = ROTL(v1, 17);                                                     \
         v1 ^= v2;                                                              \
         v2 = ROTL(v2, 32);                                                     \
     } while (0)
 
 CSipHasher::CSipHasher(uint64_t k0, uint64_t k1) {
     v[0] = 0x736f6d6570736575ULL ^ k0;
     v[1] = 0x646f72616e646f6dULL ^ k1;
     v[2] = 0x6c7967656e657261ULL ^ k0;
     v[3] = 0x7465646279746573ULL ^ k1;
     count = 0;
     tmp = 0;
 }
 
 CSipHasher &CSipHasher::Write(uint64_t data) {
     uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
 
     assert(count % 8 == 0);
 
     v3 ^= data;
     SIPROUND;
     SIPROUND;
     v0 ^= data;
 
     v[0] = v0;
     v[1] = v1;
     v[2] = v2;
     v[3] = v3;
 
     count += 8;
     return *this;
 }
 
-CSipHasher &CSipHasher::Write(const unsigned char *data, size_t size) {
+CSipHasher &CSipHasher::Write(const uint8_t *data, size_t size) {
     uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
     uint64_t t = tmp;
     int c = count;
 
     while (size--) {
         t |= ((uint64_t)(*(data++))) << (8 * (c % 8));
         c++;
         if ((c & 7) == 0) {
             v3 ^= t;
             SIPROUND;
             SIPROUND;
             v0 ^= t;
             t = 0;
         }
     }
 
     v[0] = v0;
     v[1] = v1;
     v[2] = v2;
     v[3] = v3;
     count = c;
     tmp = t;
 
     return *this;
 }
 
 uint64_t CSipHasher::Finalize() const {
     uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
 
     uint64_t t = tmp | (((uint64_t)count) << 56);
 
     v3 ^= t;
     SIPROUND;
     SIPROUND;
     v0 ^= t;
     v2 ^= 0xFF;
     SIPROUND;
     SIPROUND;
     SIPROUND;
     SIPROUND;
     return v0 ^ v1 ^ v2 ^ v3;
 }
 
 uint64_t SipHashUint256(uint64_t k0, uint64_t k1, const uint256 &val) {
     /* Specialized implementation for efficiency */
     uint64_t d = val.GetUint64(0);
 
     uint64_t v0 = 0x736f6d6570736575ULL ^ k0;
     uint64_t v1 = 0x646f72616e646f6dULL ^ k1;
     uint64_t v2 = 0x6c7967656e657261ULL ^ k0;
     uint64_t v3 = 0x7465646279746573ULL ^ k1 ^ d;
 
     SIPROUND;
     SIPROUND;
     v0 ^= d;
     d = val.GetUint64(1);
     v3 ^= d;
     SIPROUND;
     SIPROUND;
     v0 ^= d;
     d = val.GetUint64(2);
     v3 ^= d;
     SIPROUND;
     SIPROUND;
     v0 ^= d;
     d = val.GetUint64(3);
     v3 ^= d;
     SIPROUND;
     SIPROUND;
     v0 ^= d;
     v3 ^= ((uint64_t)4) << 59;
     SIPROUND;
     SIPROUND;
     v0 ^= ((uint64_t)4) << 59;
     v2 ^= 0xFF;
     SIPROUND;
     SIPROUND;
     SIPROUND;
     SIPROUND;
     return v0 ^ v1 ^ v2 ^ v3;
 }
diff --git a/src/hash.h b/src/hash.h
index 9cb765cd9..dbbe97ac3 100644
--- a/src/hash.h
+++ b/src/hash.h
@@ -1,220 +1,219 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_HASH_H
 #define BITCOIN_HASH_H
 
 #include "crypto/ripemd160.h"
 #include "crypto/sha256.h"
 #include "prevector.h"
 #include "serialize.h"
 #include "uint256.h"
 #include "version.h"
 
 #include <vector>
 
 typedef uint256 ChainCode;
 
 /** A hasher class for Bitcoin's 256-bit hash (double SHA-256). */
 class CHash256 {
 private:
     CSHA256 sha;
 
 public:
     static const size_t OUTPUT_SIZE = CSHA256::OUTPUT_SIZE;
 
-    void Finalize(unsigned char hash[OUTPUT_SIZE]) {
-        unsigned char buf[CSHA256::OUTPUT_SIZE];
+    void Finalize(uint8_t hash[OUTPUT_SIZE]) {
+        uint8_t buf[CSHA256::OUTPUT_SIZE];
         sha.Finalize(buf);
         sha.Reset().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(hash);
     }
 
-    CHash256 &Write(const unsigned char *data, size_t len) {
+    CHash256 &Write(const uint8_t *data, size_t len) {
         sha.Write(data, len);
         return *this;
     }
 
     CHash256 &Reset() {
         sha.Reset();
         return *this;
     }
 };
 
 /** A hasher class for Bitcoin's 160-bit hash (SHA-256 + RIPEMD-160). */
 class CHash160 {
 private:
     CSHA256 sha;
 
 public:
     static const size_t OUTPUT_SIZE = CRIPEMD160::OUTPUT_SIZE;
 
-    void Finalize(unsigned char hash[OUTPUT_SIZE]) {
-        unsigned char buf[CSHA256::OUTPUT_SIZE];
+    void Finalize(uint8_t hash[OUTPUT_SIZE]) {
+        uint8_t buf[CSHA256::OUTPUT_SIZE];
         sha.Finalize(buf);
         CRIPEMD160().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(hash);
     }
 
-    CHash160 &Write(const unsigned char *data, size_t len) {
+    CHash160 &Write(const uint8_t *data, size_t len) {
         sha.Write(data, len);
         return *this;
     }
 
     CHash160 &Reset() {
         sha.Reset();
         return *this;
     }
 };
 
 /** Compute the 256-bit hash of an object. */
 template <typename T1> inline uint256 Hash(const T1 pbegin, const T1 pend) {
-    static const unsigned char pblank[1] = {};
+    static const uint8_t pblank[1] = {};
     uint256 result;
     CHash256()
-        .Write(pbegin == pend ? pblank : (const unsigned char *)&pbegin[0],
+        .Write(pbegin == pend ? pblank : (const uint8_t *)&pbegin[0],
                (pend - pbegin) * sizeof(pbegin[0]))
-        .Finalize((unsigned char *)&result);
+        .Finalize((uint8_t *)&result);
     return result;
 }
 
 /** Compute the 256-bit hash of the concatenation of two objects. */
 template <typename T1, typename T2>
 inline uint256 Hash(const T1 p1begin, const T1 p1end, const T2 p2begin,
                     const T2 p2end) {
-    static const unsigned char pblank[1] = {};
+    static const uint8_t pblank[1] = {};
     uint256 result;
     CHash256()
-        .Write(p1begin == p1end ? pblank : (const unsigned char *)&p1begin[0],
+        .Write(p1begin == p1end ? pblank : (const uint8_t *)&p1begin[0],
                (p1end - p1begin) * sizeof(p1begin[0]))
-        .Write(p2begin == p2end ? pblank : (const unsigned char *)&p2begin[0],
+        .Write(p2begin == p2end ? pblank : (const uint8_t *)&p2begin[0],
                (p2end - p2begin) * sizeof(p2begin[0]))
-        .Finalize((unsigned char *)&result);
+        .Finalize((uint8_t *)&result);
     return result;
 }
 
 /** Compute the 256-bit hash of the concatenation of three objects. */
 template <typename T1, typename T2, typename T3>
 inline uint256 Hash(const T1 p1begin, const T1 p1end, const T2 p2begin,
                     const T2 p2end, const T3 p3begin, const T3 p3end) {
-    static const unsigned char pblank[1] = {};
+    static const uint8_t pblank[1] = {};
     uint256 result;
     CHash256()
-        .Write(p1begin == p1end ? pblank : (const unsigned char *)&p1begin[0],
+        .Write(p1begin == p1end ? pblank : (const uint8_t *)&p1begin[0],
                (p1end - p1begin) * sizeof(p1begin[0]))
-        .Write(p2begin == p2end ? pblank : (const unsigned char *)&p2begin[0],
+        .Write(p2begin == p2end ? pblank : (const uint8_t *)&p2begin[0],
                (p2end - p2begin) * sizeof(p2begin[0]))
-        .Write(p3begin == p3end ? pblank : (const unsigned char *)&p3begin[0],
+        .Write(p3begin == p3end ? pblank : (const uint8_t *)&p3begin[0],
                (p3end - p3begin) * sizeof(p3begin[0]))
-        .Finalize((unsigned char *)&result);
+        .Finalize((uint8_t *)&result);
     return result;
 }
 
 /** Compute the 160-bit hash an object. */
 template <typename T1> inline uint160 Hash160(const T1 pbegin, const T1 pend) {
-    static unsigned char pblank[1] = {};
+    static uint8_t pblank[1] = {};
     uint160 result;
     CHash160()
-        .Write(pbegin == pend ? pblank : (const unsigned char *)&pbegin[0],
+        .Write(pbegin == pend ? pblank : (const uint8_t *)&pbegin[0],
                (pend - pbegin) * sizeof(pbegin[0]))
-        .Finalize((unsigned char *)&result);
+        .Finalize((uint8_t *)&result);
     return result;
 }
 
 /** Compute the 160-bit hash of a vector. */
-inline uint160 Hash160(const std::vector<unsigned char> &vch) {
+inline uint160 Hash160(const std::vector<uint8_t> &vch) {
     return Hash160(vch.begin(), vch.end());
 }
 
 /** Compute the 160-bit hash of a vector. */
 template <unsigned int N>
-inline uint160 Hash160(const prevector<N, unsigned char> &vch) {
+inline uint160 Hash160(const prevector<N, uint8_t> &vch) {
     return Hash160(vch.begin(), vch.end());
 }
 
 /** A writer stream (for serialization) that computes a 256-bit hash. */
 class CHashWriter {
 private:
     CHash256 ctx;
 
     const int nType;
     const int nVersion;
 
 public:
     CHashWriter(int nTypeIn, int nVersionIn)
         : nType(nTypeIn), nVersion(nVersionIn) {}
 
     int GetType() const { return nType; }
     int GetVersion() const { return nVersion; }
 
     void write(const char *pch, size_t size) {
-        ctx.Write((const unsigned char *)pch, size);
+        ctx.Write((const uint8_t *)pch, size);
     }
 
     // invalidates the object
     uint256 GetHash() {
         uint256 result;
-        ctx.Finalize((unsigned char *)&result);
+        ctx.Finalize((uint8_t *)&result);
         return result;
     }
 
     template <typename T> CHashWriter &operator<<(const T &obj) {
         // Serialize to this stream
         ::Serialize(*this, obj);
         return (*this);
     }
 };
 
 /** Compute the 256-bit hash of an object's serialization. */
 template <typename T>
 uint256 SerializeHash(const T &obj, int nType = SER_GETHASH,
                       int nVersion = PROTOCOL_VERSION) {
     CHashWriter ss(nType, nVersion);
     ss << obj;
     return ss.GetHash();
 }
 
 unsigned int MurmurHash3(unsigned int nHashSeed,
-                         const std::vector<unsigned char> &vDataToHash);
+                         const std::vector<uint8_t> &vDataToHash);
 
-void BIP32Hash(const ChainCode &chainCode, unsigned int nChild,
-               unsigned char header, const unsigned char data[32],
-               unsigned char output[64]);
+void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, uint8_t header,
+               const uint8_t data[32], uint8_t output[64]);
 
 /** SipHash-2-4 */
 class CSipHasher {
 private:
     uint64_t v[4];
     uint64_t tmp;
     int count;
 
 public:
     /** Construct a SipHash calculator initialized with 128-bit key (k0, k1) */
     CSipHasher(uint64_t k0, uint64_t k1);
     /**
      * Hash a 64-bit integer worth of data.
      * It is treated as if this was the little-endian interpretation of 8 bytes.
      * This function can only be used when a multiple of 8 bytes have been
      * written so far.
      */
     CSipHasher &Write(uint64_t data);
     /** Hash arbitrary bytes. */
-    CSipHasher &Write(const unsigned char *data, size_t size);
+    CSipHasher &Write(const uint8_t *data, size_t size);
     /** Compute the 64-bit SipHash-2-4 of the data written so far. The object
      * remains untouched. */
     uint64_t Finalize() const;
 };
 
 /** Optimized SipHash-2-4 implementation for uint256.
  *
  *  It is identical to:
  *    SipHasher(k0, k1)
  *      .Write(val.GetUint64(0))
  *      .Write(val.GetUint64(1))
  *      .Write(val.GetUint64(2))
  *      .Write(val.GetUint64(3))
  *      .Finalize()
  */
 uint64_t SipHashUint256(uint64_t k0, uint64_t k1, const uint256 &val);
 
 #endif // BITCOIN_HASH_H
diff --git a/src/httprpc.cpp b/src/httprpc.cpp
index 24ebe1c22..d9ed62abb 100644
--- a/src/httprpc.cpp
+++ b/src/httprpc.cpp
@@ -1,268 +1,267 @@
 // Copyright (c) 2015-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.
 
 #include "httprpc.h"
 
 #include "base58.h"
 #include "chainparams.h"
 #include "config.h"
 #include "crypto/hmac_sha256.h"
 #include "httpserver.h"
 #include "random.h"
 #include "rpc/protocol.h"
 #include "rpc/server.h"
 #include "sync.h"
 #include "ui_interface.h"
 #include "util.h"
 #include "utilstrencodings.h"
 #include "utilstrencodings.h"
 
 #include <cstdio>
 
 #include <boost/algorithm/string.hpp> // boost::trim
 
 /** WWW-Authenticate to present with 401 Unauthorized response */
 static const char *WWW_AUTH_HEADER_DATA = "Basic realm=\"jsonrpc\"";
 
 /** Simple one-shot callback timer to be used by the RPC mechanism to e.g.
  * re-lock the wallet.
  */
 class HTTPRPCTimer : public RPCTimerBase {
 public:
     HTTPRPCTimer(struct event_base *eventBase,
                  boost::function<void(void)> &func, int64_t millis)
         : ev(eventBase, false, func) {
         struct timeval tv;
         tv.tv_sec = millis / 1000;
         tv.tv_usec = (millis % 1000) * 1000;
         ev.trigger(&tv);
     }
 
 private:
     HTTPEvent ev;
 };
 
 class HTTPRPCTimerInterface : public RPCTimerInterface {
 public:
     HTTPRPCTimerInterface(struct event_base *_base) : base(_base) {}
     const char *Name() { return "HTTP"; }
     RPCTimerBase *NewTimer(boost::function<void(void)> &func, int64_t millis) {
         return new HTTPRPCTimer(base, func, millis);
     }
 
 private:
     struct event_base *base;
 };
 
 /* Pre-base64-encoded authentication token */
 static std::string strRPCUserColonPass;
 /* Stored RPC timer interface (for unregistration) */
 static HTTPRPCTimerInterface *httpRPCTimerInterface = 0;
 
 static void JSONErrorReply(HTTPRequest *req, const UniValue &objError,
                            const UniValue &id) {
     // Send error reply from json-rpc error object.
     int nStatus = HTTP_INTERNAL_SERVER_ERROR;
     int code = find_value(objError, "code").get_int();
 
     if (code == RPC_INVALID_REQUEST)
         nStatus = HTTP_BAD_REQUEST;
     else if (code == RPC_METHOD_NOT_FOUND)
         nStatus = HTTP_NOT_FOUND;
 
     std::string strReply = JSONRPCReply(NullUniValue, objError, id);
 
     req->WriteHeader("Content-Type", "application/json");
     req->WriteReply(nStatus, strReply);
 }
 
 // This function checks username and password against -rpcauth entries from
 // config file.
 static bool multiUserAuthorized(std::string strUserPass) {
     if (strUserPass.find(":") == std::string::npos) {
         return false;
     }
     std::string strUser = strUserPass.substr(0, strUserPass.find(":"));
     std::string strPass = strUserPass.substr(strUserPass.find(":") + 1);
 
     if (mapMultiArgs.count("-rpcauth") > 0) {
         // Search for multi-user login/pass "rpcauth" from config
         for (const std::string &strRPCAuth : mapMultiArgs.at("-rpcauth")) {
             std::vector<std::string> vFields;
             boost::split(vFields, strRPCAuth, boost::is_any_of(":$"));
             if (vFields.size() != 3) {
                 // Incorrect formatting in config file
                 continue;
             }
 
             std::string strName = vFields[0];
             if (!TimingResistantEqual(strName, strUser)) {
                 continue;
             }
 
             std::string strSalt = vFields[1];
             std::string strHash = vFields[2];
 
             static const unsigned int KEY_SIZE = 32;
-            unsigned char out[KEY_SIZE];
+            uint8_t out[KEY_SIZE];
 
-            CHMAC_SHA256(
-                reinterpret_cast<const unsigned char *>(strSalt.c_str()),
-                strSalt.size())
-                .Write(reinterpret_cast<const unsigned char *>(strPass.c_str()),
+            CHMAC_SHA256(reinterpret_cast<const uint8_t *>(strSalt.c_str()),
+                         strSalt.size())
+                .Write(reinterpret_cast<const uint8_t *>(strPass.c_str()),
                        strPass.size())
                 .Finalize(out);
-            std::vector<unsigned char> hexvec(out, out + KEY_SIZE);
+            std::vector<uint8_t> hexvec(out, out + KEY_SIZE);
             std::string strHashFromPass = HexStr(hexvec);
 
             if (TimingResistantEqual(strHashFromPass, strHash)) {
                 return true;
             }
         }
     }
     return false;
 }
 
 static bool RPCAuthorized(const std::string &strAuth,
                           std::string &strAuthUsernameOut) {
     // Belt-and-suspenders measure if InitRPCAuthentication was not called.
     if (strRPCUserColonPass.empty()) {
         return false;
     }
 
     if (strAuth.substr(0, 6) != "Basic ") {
         return false;
     }
 
     std::string strUserPass64 = strAuth.substr(6);
     boost::trim(strUserPass64);
     std::string strUserPass = DecodeBase64(strUserPass64);
 
     if (strUserPass.find(":") != std::string::npos) {
         strAuthUsernameOut = strUserPass.substr(0, strUserPass.find(":"));
     }
 
     // Check if authorized under single-user field
     if (TimingResistantEqual(strUserPass, strRPCUserColonPass)) {
         return true;
     }
     return multiUserAuthorized(strUserPass);
 }
 
 static bool HTTPReq_JSONRPC(Config &config, HTTPRequest *req,
                             const std::string &) {
     // JSONRPC handles only POST
     if (req->GetRequestMethod() != HTTPRequest::POST) {
         req->WriteReply(HTTP_BAD_METHOD,
                         "JSONRPC server handles only POST requests");
         return false;
     }
     // Check authorization
     std::pair<bool, std::string> authHeader = req->GetHeader("authorization");
     if (!authHeader.first) {
         req->WriteHeader("WWW-Authenticate", WWW_AUTH_HEADER_DATA);
         req->WriteReply(HTTP_UNAUTHORIZED);
         return false;
     }
 
     JSONRPCRequest jreq;
     if (!RPCAuthorized(authHeader.second, jreq.authUser)) {
         LogPrintf("ThreadRPCServer incorrect password attempt from %s\n",
                   req->GetPeer().ToString());
 
         /* Deter brute-forcing.
          * If this results in a DoS the user really shouldn't have their RPC
          * port exposed. */
         MilliSleep(250);
 
         req->WriteHeader("WWW-Authenticate", WWW_AUTH_HEADER_DATA);
         req->WriteReply(HTTP_UNAUTHORIZED);
         return false;
     }
 
     try {
         // Parse request
         UniValue valRequest;
         if (!valRequest.read(req->ReadBody()))
             throw JSONRPCError(RPC_PARSE_ERROR, "Parse error");
 
         // Set the URI
         jreq.URI = req->GetURI();
 
         std::string strReply;
         // singleton request
         if (valRequest.isObject()) {
             jreq.parse(valRequest);
 
             UniValue result = tableRPC.execute(config, jreq);
 
             // Send reply
             strReply = JSONRPCReply(result, NullUniValue, jreq.id);
 
             // array of requests
         } else if (valRequest.isArray()) {
             strReply = JSONRPCExecBatch(config, valRequest.get_array());
         } else {
             throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error");
         }
 
         req->WriteHeader("Content-Type", "application/json");
         req->WriteReply(HTTP_OK, strReply);
     } catch (const UniValue &objError) {
         JSONErrorReply(req, objError, jreq.id);
         return false;
     } catch (const std::exception &e) {
         JSONErrorReply(req, JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);
         return false;
     }
     return true;
 }
 
 static bool InitRPCAuthentication() {
     if (GetArg("-rpcpassword", "") == "") {
         LogPrintf("No rpcpassword set - using random cookie authentication\n");
         if (!GenerateAuthCookie(&strRPCUserColonPass)) {
             // Same message as AbortNode.
             uiInterface.ThreadSafeMessageBox(
                 _("Error: A fatal internal error occurred, see debug.log for "
                   "details"),
                 "", CClientUIInterface::MSG_ERROR);
             return false;
         }
     } else {
         LogPrintf("Config options rpcuser and rpcpassword will soon be "
                   "deprecated. Locally-run instances may remove rpcuser to use "
                   "cookie-based auth, or may be replaced with rpcauth. Please "
                   "see share/rpcuser for rpcauth auth generation.\n");
         strRPCUserColonPass =
             GetArg("-rpcuser", "") + ":" + GetArg("-rpcpassword", "");
     }
     return true;
 }
 
 bool StartHTTPRPC() {
     LogPrint("rpc", "Starting HTTP RPC server\n");
     if (!InitRPCAuthentication()) return false;
 
     RegisterHTTPHandler("/", true, HTTPReq_JSONRPC);
 
     assert(EventBase());
     httpRPCTimerInterface = new HTTPRPCTimerInterface(EventBase());
     RPCSetTimerInterface(httpRPCTimerInterface);
     return true;
 }
 
 void InterruptHTTPRPC() {
     LogPrint("rpc", "Interrupting HTTP RPC server\n");
 }
 
 void StopHTTPRPC() {
     LogPrint("rpc", "Stopping HTTP RPC server\n");
     UnregisterHTTPHandler("/", true);
     if (httpRPCTimerInterface) {
         RPCUnsetTimerInterface(httpRPCTimerInterface);
         delete httpRPCTimerInterface;
         httpRPCTimerInterface = 0;
     }
 }
diff --git a/src/key.cpp b/src/key.cpp
index 403d2752a..1f9223856 100644
--- a/src/key.cpp
+++ b/src/key.cpp
@@ -1,370 +1,367 @@
 // Copyright (c) 2009-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.
 
 #include "key.h"
 
 #include "arith_uint256.h"
 #include "crypto/common.h"
 #include "crypto/hmac_sha512.h"
 #include "pubkey.h"
 #include "random.h"
 
 #include <secp256k1.h>
 #include <secp256k1_recovery.h>
 
 static secp256k1_context *secp256k1_context_sign = nullptr;
 
 /** These functions are taken from the libsecp256k1 distribution and are very
  * ugly. */
-static int ec_privkey_import_der(const secp256k1_context *ctx,
-                                 unsigned char *out32,
-                                 const unsigned char *privkey,
-                                 size_t privkeylen) {
-    const unsigned char *end = privkey + privkeylen;
+static int ec_privkey_import_der(const secp256k1_context *ctx, uint8_t *out32,
+                                 const uint8_t *privkey, size_t privkeylen) {
+    const uint8_t *end = privkey + privkeylen;
     int lenb = 0;
     int len = 0;
     memset(out32, 0, 32);
     /* sequence header */
     if (end < privkey + 1 || *privkey != 0x30) {
         return 0;
     }
     privkey++;
     /* sequence length constructor */
     if (end < privkey + 1 || !(*privkey & 0x80)) {
         return 0;
     }
     lenb = *privkey & ~0x80;
     privkey++;
     if (lenb < 1 || lenb > 2) {
         return 0;
     }
     if (end < privkey + lenb) {
         return 0;
     }
     /* sequence length */
     len = privkey[lenb - 1] | (lenb > 1 ? privkey[lenb - 2] << 8 : 0);
     privkey += lenb;
     if (end < privkey + len) {
         return 0;
     }
     /* sequence element 0: version number (=1) */
     if (end < privkey + 3 || privkey[0] != 0x02 || privkey[1] != 0x01 ||
         privkey[2] != 0x01) {
         return 0;
     }
     privkey += 3;
     /* sequence element 1: octet string, up to 32 bytes */
     if (end < privkey + 2 || privkey[0] != 0x04 || privkey[1] > 0x20 ||
         end < privkey + 2 + privkey[1]) {
         return 0;
     }
     memcpy(out32 + 32 - privkey[1], privkey + 2, privkey[1]);
     if (!secp256k1_ec_seckey_verify(ctx, out32)) {
         memset(out32, 0, 32);
         return 0;
     }
     return 1;
 }
 
-static int ec_privkey_export_der(const secp256k1_context *ctx,
-                                 unsigned char *privkey, size_t *privkeylen,
-                                 const unsigned char *key32, int compressed) {
+static int ec_privkey_export_der(const secp256k1_context *ctx, uint8_t *privkey,
+                                 size_t *privkeylen, const uint8_t *key32,
+                                 int compressed) {
     secp256k1_pubkey pubkey;
     size_t pubkeylen = 0;
     if (!secp256k1_ec_pubkey_create(ctx, &pubkey, key32)) {
         *privkeylen = 0;
         return 0;
     }
 
     if (compressed) {
-        static const unsigned char begin[] = {0x30, 0x81, 0xD3, 0x02,
-                                              0x01, 0x01, 0x04, 0x20};
-        static const unsigned char middle[] = {
+        static const uint8_t begin[] = {0x30, 0x81, 0xD3, 0x02,
+                                        0x01, 0x01, 0x04, 0x20};
+        static const uint8_t middle[] = {
             0xA0, 0x81, 0x85, 0x30, 0x81, 0x82, 0x02, 0x01, 0x01, 0x30, 0x2C,
             0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x01, 0x01, 0x02, 0x21,
             0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x2F,
             0x30, 0x06, 0x04, 0x01, 0x00, 0x04, 0x01, 0x07, 0x04, 0x21, 0x02,
             0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62,
             0x95, 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE,
             0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98, 0x02,
             0x21, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6,
             0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41,
             0x41, 0x02, 0x01, 0x01, 0xA1, 0x24, 0x03, 0x22, 0x00};
-        unsigned char *ptr = privkey;
+        uint8_t *ptr = privkey;
         memcpy(ptr, begin, sizeof(begin));
         ptr += sizeof(begin);
         memcpy(ptr, key32, 32);
         ptr += 32;
         memcpy(ptr, middle, sizeof(middle));
         ptr += sizeof(middle);
         pubkeylen = 33;
         secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey,
                                       SECP256K1_EC_COMPRESSED);
         ptr += pubkeylen;
         *privkeylen = ptr - privkey;
     } else {
-        static const unsigned char begin[] = {0x30, 0x82, 0x01, 0x13, 0x02,
-                                              0x01, 0x01, 0x04, 0x20};
-        static const unsigned char middle[] = {
+        static const uint8_t begin[] = {0x30, 0x82, 0x01, 0x13, 0x02,
+                                        0x01, 0x01, 0x04, 0x20};
+        static const uint8_t middle[] = {
             0xA0, 0x81, 0xA5, 0x30, 0x81, 0xA2, 0x02, 0x01, 0x01, 0x30, 0x2C,
             0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x01, 0x01, 0x02, 0x21,
             0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x2F,
             0x30, 0x06, 0x04, 0x01, 0x00, 0x04, 0x01, 0x07, 0x04, 0x41, 0x04,
             0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62,
             0x95, 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE,
             0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98, 0x48,
             0x3A, 0xDA, 0x77, 0x26, 0xA3, 0xC4, 0x65, 0x5D, 0xA4, 0xFB, 0xFC,
             0x0E, 0x11, 0x08, 0xA8, 0xFD, 0x17, 0xB4, 0x48, 0xA6, 0x85, 0x54,
             0x19, 0x9C, 0x47, 0xD0, 0x8F, 0xFB, 0x10, 0xD4, 0xB8, 0x02, 0x21,
             0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF,
             0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41,
             0x02, 0x01, 0x01, 0xA1, 0x44, 0x03, 0x42, 0x00};
-        unsigned char *ptr = privkey;
+        uint8_t *ptr = privkey;
         memcpy(ptr, begin, sizeof(begin));
         ptr += sizeof(begin);
         memcpy(ptr, key32, 32);
         ptr += 32;
         memcpy(ptr, middle, sizeof(middle));
         ptr += sizeof(middle);
         pubkeylen = 65;
         secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey,
                                       SECP256K1_EC_UNCOMPRESSED);
         ptr += pubkeylen;
         *privkeylen = ptr - privkey;
     }
     return 1;
 }
 
-bool CKey::Check(const unsigned char *vch) {
+bool CKey::Check(const uint8_t *vch) {
     return secp256k1_ec_seckey_verify(secp256k1_context_sign, vch);
 }
 
 void CKey::MakeNewKey(bool fCompressedIn) {
     do {
         GetStrongRandBytes(keydata.data(), keydata.size());
     } while (!Check(keydata.data()));
     fValid = true;
     fCompressed = fCompressedIn;
 }
 
 bool CKey::SetPrivKey(const CPrivKey &privkey, bool fCompressedIn) {
-    if (!ec_privkey_import_der(secp256k1_context_sign, (unsigned char *)begin(),
+    if (!ec_privkey_import_der(secp256k1_context_sign, (uint8_t *)begin(),
                                &privkey[0], privkey.size()))
         return false;
     fCompressed = fCompressedIn;
     fValid = true;
     return true;
 }
 
 CPrivKey CKey::GetPrivKey() const {
     assert(fValid);
     CPrivKey privkey;
     int ret;
     size_t privkeylen;
     privkey.resize(279);
     privkeylen = 279;
     ret = ec_privkey_export_der(
-        secp256k1_context_sign, (unsigned char *)&privkey[0], &privkeylen,
-        begin(),
+        secp256k1_context_sign, (uint8_t *)&privkey[0], &privkeylen, begin(),
         fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
     assert(ret);
     privkey.resize(privkeylen);
     return privkey;
 }
 
 CPubKey CKey::GetPubKey() const {
     assert(fValid);
     secp256k1_pubkey pubkey;
     size_t clen = 65;
     CPubKey result;
     int ret =
         secp256k1_ec_pubkey_create(secp256k1_context_sign, &pubkey, begin());
     assert(ret);
     secp256k1_ec_pubkey_serialize(
-        secp256k1_context_sign, (unsigned char *)result.begin(), &clen, &pubkey,
+        secp256k1_context_sign, (uint8_t *)result.begin(), &clen, &pubkey,
         fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
     assert(result.size() == clen);
     assert(result.IsValid());
     return result;
 }
 
-bool CKey::Sign(const uint256 &hash, std::vector<unsigned char> &vchSig,
+bool CKey::Sign(const uint256 &hash, std::vector<uint8_t> &vchSig,
                 uint32_t test_case) const {
     if (!fValid) return false;
     vchSig.resize(72);
     size_t nSigLen = 72;
-    unsigned char extra_entropy[32] = {0};
+    uint8_t extra_entropy[32] = {0};
     WriteLE32(extra_entropy, test_case);
     secp256k1_ecdsa_signature sig;
     int ret = secp256k1_ecdsa_sign(secp256k1_context_sign, &sig, hash.begin(),
                                    begin(), secp256k1_nonce_function_rfc6979,
                                    test_case ? extra_entropy : nullptr);
     assert(ret);
     secp256k1_ecdsa_signature_serialize_der(
-        secp256k1_context_sign, (unsigned char *)&vchSig[0], &nSigLen, &sig);
+        secp256k1_context_sign, (uint8_t *)&vchSig[0], &nSigLen, &sig);
     vchSig.resize(nSigLen);
     return true;
 }
 
 bool CKey::VerifyPubKey(const CPubKey &pubkey) const {
     if (pubkey.IsCompressed() != fCompressed) {
         return false;
     }
-    unsigned char rnd[8];
+    uint8_t rnd[8];
     std::string str = "Bitcoin key verification\n";
     GetRandBytes(rnd, sizeof(rnd));
     uint256 hash;
     CHash256()
-        .Write((unsigned char *)str.data(), str.size())
+        .Write((uint8_t *)str.data(), str.size())
         .Write(rnd, sizeof(rnd))
         .Finalize(hash.begin());
-    std::vector<unsigned char> vchSig;
+    std::vector<uint8_t> vchSig;
     Sign(hash, vchSig);
     return pubkey.Verify(hash, vchSig);
 }
 
 bool CKey::SignCompact(const uint256 &hash,
-                       std::vector<unsigned char> &vchSig) const {
+                       std::vector<uint8_t> &vchSig) const {
     if (!fValid) return false;
     vchSig.resize(65);
     int rec = -1;
     secp256k1_ecdsa_recoverable_signature sig;
     int ret = secp256k1_ecdsa_sign_recoverable(
         secp256k1_context_sign, &sig, hash.begin(), begin(),
         secp256k1_nonce_function_rfc6979, nullptr);
     assert(ret);
     secp256k1_ecdsa_recoverable_signature_serialize_compact(
-        secp256k1_context_sign, (unsigned char *)&vchSig[1], &rec, &sig);
+        secp256k1_context_sign, (uint8_t *)&vchSig[1], &rec, &sig);
     assert(ret);
     assert(rec != -1);
     vchSig[0] = 27 + rec + (fCompressed ? 4 : 0);
     return true;
 }
 
 bool CKey::Load(CPrivKey &privkey, CPubKey &vchPubKey,
                 bool fSkipCheck = false) {
-    if (!ec_privkey_import_der(secp256k1_context_sign, (unsigned char *)begin(),
+    if (!ec_privkey_import_der(secp256k1_context_sign, (uint8_t *)begin(),
                                &privkey[0], privkey.size()))
         return false;
     fCompressed = vchPubKey.IsCompressed();
     fValid = true;
 
     if (fSkipCheck) return true;
 
     return VerifyPubKey(vchPubKey);
 }
 
 bool CKey::Derive(CKey &keyChild, ChainCode &ccChild, unsigned int nChild,
                   const ChainCode &cc) const {
     assert(IsValid());
     assert(IsCompressed());
-    std::vector<unsigned char, secure_allocator<unsigned char>> vout(64);
+    std::vector<uint8_t, secure_allocator<uint8_t>> vout(64);
     if ((nChild >> 31) == 0) {
         CPubKey pubkey = GetPubKey();
         assert(pubkey.begin() + 33 == pubkey.end());
         BIP32Hash(cc, nChild, *pubkey.begin(), pubkey.begin() + 1, vout.data());
     } else {
         assert(begin() + 32 == end());
         BIP32Hash(cc, nChild, 0, begin(), vout.data());
     }
     memcpy(ccChild.begin(), vout.data() + 32, 32);
-    memcpy((unsigned char *)keyChild.begin(), begin(), 32);
+    memcpy((uint8_t *)keyChild.begin(), begin(), 32);
     bool ret = secp256k1_ec_privkey_tweak_add(
-        secp256k1_context_sign, (unsigned char *)keyChild.begin(), vout.data());
+        secp256k1_context_sign, (uint8_t *)keyChild.begin(), vout.data());
     keyChild.fCompressed = true;
     keyChild.fValid = ret;
     return ret;
 }
 
 bool CExtKey::Derive(CExtKey &out, unsigned int _nChild) const {
     out.nDepth = nDepth + 1;
     CKeyID id = key.GetPubKey().GetID();
     memcpy(&out.vchFingerprint[0], &id, 4);
     out.nChild = _nChild;
     return key.Derive(out.key, out.chaincode, _nChild, chaincode);
 }
 
-void CExtKey::SetMaster(const unsigned char *seed, unsigned int nSeedLen) {
-    static const unsigned char hashkey[] = {'B', 'i', 't', 'c', 'o', 'i',
-                                            'n', ' ', 's', 'e', 'e', 'd'};
-    std::vector<unsigned char, secure_allocator<unsigned char>> vout(64);
+void CExtKey::SetMaster(const uint8_t *seed, unsigned int nSeedLen) {
+    static const uint8_t hashkey[] = {'B', 'i', 't', 'c', 'o', 'i',
+                                      'n', ' ', 's', 'e', 'e', 'd'};
+    std::vector<uint8_t, secure_allocator<uint8_t>> vout(64);
     CHMAC_SHA512(hashkey, sizeof(hashkey))
         .Write(seed, nSeedLen)
         .Finalize(vout.data());
     key.Set(&vout[0], &vout[32], true);
     memcpy(chaincode.begin(), &vout[32], 32);
     nDepth = 0;
     nChild = 0;
     memset(vchFingerprint, 0, sizeof(vchFingerprint));
 }
 
 CExtPubKey CExtKey::Neuter() const {
     CExtPubKey ret;
     ret.nDepth = nDepth;
     memcpy(&ret.vchFingerprint[0], &vchFingerprint[0], 4);
     ret.nChild = nChild;
     ret.pubkey = key.GetPubKey();
     ret.chaincode = chaincode;
     return ret;
 }
 
-void CExtKey::Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const {
+void CExtKey::Encode(uint8_t code[BIP32_EXTKEY_SIZE]) const {
     code[0] = nDepth;
     memcpy(code + 1, vchFingerprint, 4);
     code[5] = (nChild >> 24) & 0xFF;
     code[6] = (nChild >> 16) & 0xFF;
     code[7] = (nChild >> 8) & 0xFF;
     code[8] = (nChild >> 0) & 0xFF;
     memcpy(code + 9, chaincode.begin(), 32);
     code[41] = 0;
     assert(key.size() == 32);
     memcpy(code + 42, key.begin(), 32);
 }
 
-void CExtKey::Decode(const unsigned char code[BIP32_EXTKEY_SIZE]) {
+void CExtKey::Decode(const uint8_t code[BIP32_EXTKEY_SIZE]) {
     nDepth = code[0];
     memcpy(vchFingerprint, code + 1, 4);
     nChild = (code[5] << 24) | (code[6] << 16) | (code[7] << 8) | code[8];
     memcpy(chaincode.begin(), code + 9, 32);
     key.Set(code + 42, code + BIP32_EXTKEY_SIZE, true);
 }
 
 bool ECC_InitSanityCheck() {
     CKey key;
     key.MakeNewKey(true);
     CPubKey pubkey = key.GetPubKey();
     return key.VerifyPubKey(pubkey);
 }
 
 void ECC_Start() {
     assert(secp256k1_context_sign == nullptr);
 
     secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
     assert(ctx != nullptr);
 
     {
         // Pass in a random blinding seed to the secp256k1 context.
-        std::vector<unsigned char, secure_allocator<unsigned char>> vseed(32);
+        std::vector<uint8_t, secure_allocator<uint8_t>> vseed(32);
         GetRandBytes(vseed.data(), 32);
         bool ret = secp256k1_context_randomize(ctx, vseed.data());
         assert(ret);
     }
 
     secp256k1_context_sign = ctx;
 }
 
 void ECC_Stop() {
     secp256k1_context *ctx = secp256k1_context_sign;
     secp256k1_context_sign = nullptr;
 
     if (ctx) {
         secp256k1_context_destroy(ctx);
     }
 }
diff --git a/src/key.h b/src/key.h
index 196cde61b..2099c476b 100644
--- a/src/key.h
+++ b/src/key.h
@@ -1,193 +1,192 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_KEY_H
 #define BITCOIN_KEY_H
 
 #include "pubkey.h"
 #include "serialize.h"
 #include "support/allocators/secure.h"
 #include "uint256.h"
 
 #include <stdexcept>
 #include <vector>
 
 /**
  * secp256k1:
  * const unsigned int PRIVATE_KEY_SIZE = 279;
  * const unsigned int PUBLIC_KEY_SIZE  = 65;
  * const unsigned int SIGNATURE_SIZE   = 72;
  *
  * see www.keylength.com
  * script supports up to 75 for single byte push
  */
 
 /**
  * secure_allocator is defined in allocators.h
  * CPrivKey is a serialized private key, with all parameters included (279
  * bytes)
  */
-typedef std::vector<unsigned char, secure_allocator<unsigned char>> CPrivKey;
+typedef std::vector<uint8_t, secure_allocator<uint8_t>> CPrivKey;
 
 /** An encapsulated private key. */
 class CKey {
 private:
     //! Whether this private key is valid. We check for correctness when
     //! modifying the key data, so fValid should always correspond to the actual
     //! state.
     bool fValid;
 
     //! Whether the public key corresponding to this private key is (to be)
     //! compressed.
     bool fCompressed;
 
     //! The actual byte data
-    std::vector<unsigned char, secure_allocator<unsigned char>> keydata;
+    std::vector<uint8_t, secure_allocator<uint8_t>> keydata;
 
     //! Check whether the 32-byte array pointed to be vch is valid keydata.
-    static bool Check(const unsigned char *vch);
+    static bool Check(const uint8_t *vch);
 
 public:
     //! Construct an invalid private key.
     CKey() : fValid(false), fCompressed(false) {
         // Important: vch must be 32 bytes in length to not break serialization
         keydata.resize(32);
     }
 
     //! Destructor (again necessary because of memlocking).
     ~CKey() {}
 
     friend bool operator==(const CKey &a, const CKey &b) {
         return a.fCompressed == b.fCompressed && a.size() == b.size() &&
                memcmp(a.keydata.data(), b.keydata.data(), a.size()) == 0;
     }
 
     //! Initialize using begin and end iterators to byte data.
     template <typename T>
     void Set(const T pbegin, const T pend, bool fCompressedIn) {
         if (size_t(pend - pbegin) != keydata.size()) {
             fValid = false;
         } else if (Check(&pbegin[0])) {
-            memcpy(keydata.data(), (unsigned char *)&pbegin[0], keydata.size());
+            memcpy(keydata.data(), (uint8_t *)&pbegin[0], keydata.size());
             fValid = true;
             fCompressed = fCompressedIn;
         } else {
             fValid = false;
         }
     }
 
     //! Simple read-only vector-like interface.
     unsigned int size() const { return (fValid ? keydata.size() : 0); }
-    const unsigned char *begin() const { return keydata.data(); }
-    const unsigned char *end() const { return keydata.data() + size(); }
+    const uint8_t *begin() const { return keydata.data(); }
+    const uint8_t *end() const { return keydata.data() + size(); }
 
     //! Check whether this private key is valid.
     bool IsValid() const { return fValid; }
 
     //! Check whether the public key corresponding to this private key is (to
     //! be) compressed.
     bool IsCompressed() const { return fCompressed; }
 
     //! Initialize from a CPrivKey (serialized OpenSSL private key data).
     bool SetPrivKey(const CPrivKey &vchPrivKey, bool fCompressed);
 
     //! Generate a new private key using a cryptographic PRNG.
     void MakeNewKey(bool fCompressed);
 
     /**
      * Convert the private key to a CPrivKey (serialized OpenSSL private key
      * data).
      * This is expensive.
      */
     CPrivKey GetPrivKey() const;
 
     /**
      * Compute the public key from a private key.
      * This is expensive.
      */
     CPubKey GetPubKey() const;
 
     /**
      * Create a DER-serialized signature.
      * The test_case parameter tweaks the deterministic nonce.
      */
-    bool Sign(const uint256 &hash, std::vector<unsigned char> &vchSig,
+    bool Sign(const uint256 &hash, std::vector<uint8_t> &vchSig,
               uint32_t test_case = 0) const;
 
     /**
      * Create a compact signature (65 bytes), which allows reconstructing the
      * used public key.
      * The format is one header byte, followed by two times 32 bytes for the
      * serialized r and s values.
      * The header byte: 0x1B = first key with even y, 0x1C = first key with odd
      * y,
      *                  0x1D = second key with even y, 0x1E = second key with
      * odd y,
      *                  add 0x04 for compressed keys.
      */
-    bool SignCompact(const uint256 &hash,
-                     std::vector<unsigned char> &vchSig) const;
+    bool SignCompact(const uint256 &hash, std::vector<uint8_t> &vchSig) const;
 
     //! Derive BIP32 child key.
     bool Derive(CKey &keyChild, ChainCode &ccChild, unsigned int nChild,
                 const ChainCode &cc) const;
 
     /**
      * Verify thoroughly whether a private key and a public key match.
      * This is done using a different mechanism than just regenerating it.
      */
     bool VerifyPubKey(const CPubKey &vchPubKey) const;
 
     //! Load private key and check that public key matches.
     bool Load(CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck);
 };
 
 struct CExtKey {
-    unsigned char nDepth;
-    unsigned char vchFingerprint[4];
+    uint8_t nDepth;
+    uint8_t vchFingerprint[4];
     unsigned int nChild;
     ChainCode chaincode;
     CKey key;
 
     friend bool operator==(const CExtKey &a, const CExtKey &b) {
         return a.nDepth == b.nDepth &&
                memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0],
                       sizeof(vchFingerprint)) == 0 &&
                a.nChild == b.nChild && a.chaincode == b.chaincode &&
                a.key == b.key;
     }
 
-    void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const;
-    void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]);
+    void Encode(uint8_t code[BIP32_EXTKEY_SIZE]) const;
+    void Decode(const uint8_t code[BIP32_EXTKEY_SIZE]);
     bool Derive(CExtKey &out, unsigned int nChild) const;
     CExtPubKey Neuter() const;
-    void SetMaster(const unsigned char *seed, unsigned int nSeedLen);
+    void SetMaster(const uint8_t *seed, unsigned int nSeedLen);
     template <typename Stream> void Serialize(Stream &s) const {
         unsigned int len = BIP32_EXTKEY_SIZE;
         ::WriteCompactSize(s, len);
-        unsigned char code[BIP32_EXTKEY_SIZE];
+        uint8_t code[BIP32_EXTKEY_SIZE];
         Encode(code);
         s.write((const char *)&code[0], len);
     }
     template <typename Stream> void Unserialize(Stream &s) {
         unsigned int len = ::ReadCompactSize(s);
-        unsigned char code[BIP32_EXTKEY_SIZE];
+        uint8_t code[BIP32_EXTKEY_SIZE];
         s.read((char *)&code[0], len);
         Decode(code);
     }
 };
 
 /** Initialize the elliptic curve support. May not be called twice without
  * calling ECC_Stop first. */
 void ECC_Start(void);
 
 /** Deinitialize the elliptic curve support. No-op if ECC_Start wasn't called
  * first. */
 void ECC_Stop(void);
 
 /** Check that required EC support is available at runtime. */
 bool ECC_InitSanityCheck(void);
 
 #endif // BITCOIN_KEY_H
diff --git a/src/keystore.cpp b/src/keystore.cpp
index a352d6583..a38c2f88e 100644
--- a/src/keystore.cpp
+++ b/src/keystore.cpp
@@ -1,104 +1,104 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #include "keystore.h"
 
 #include "key.h"
 #include "pubkey.h"
 #include "util.h"
 
 bool CKeyStore::AddKey(const CKey &key) {
     return AddKeyPubKey(key, key.GetPubKey());
 }
 
 bool CBasicKeyStore::GetPubKey(const CKeyID &address,
                                CPubKey &vchPubKeyOut) const {
     CKey key;
     if (!GetKey(address, key)) {
         LOCK(cs_KeyStore);
         WatchKeyMap::const_iterator it = mapWatchKeys.find(address);
         if (it != mapWatchKeys.end()) {
             vchPubKeyOut = it->second;
             return true;
         }
         return false;
     }
     vchPubKeyOut = key.GetPubKey();
     return true;
 }
 
 bool CBasicKeyStore::AddKeyPubKey(const CKey &key, const CPubKey &pubkey) {
     LOCK(cs_KeyStore);
     mapKeys[pubkey.GetID()] = key;
     return true;
 }
 
 bool CBasicKeyStore::AddCScript(const CScript &redeemScript) {
     if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
         return error("CBasicKeyStore::AddCScript(): redeemScripts > %i bytes "
                      "are invalid",
                      MAX_SCRIPT_ELEMENT_SIZE);
 
     LOCK(cs_KeyStore);
     mapScripts[CScriptID(redeemScript)] = redeemScript;
     return true;
 }
 
 bool CBasicKeyStore::HaveCScript(const CScriptID &hash) const {
     LOCK(cs_KeyStore);
     return mapScripts.count(hash) > 0;
 }
 
 bool CBasicKeyStore::GetCScript(const CScriptID &hash,
                                 CScript &redeemScriptOut) const {
     LOCK(cs_KeyStore);
     ScriptMap::const_iterator mi = mapScripts.find(hash);
     if (mi != mapScripts.end()) {
         redeemScriptOut = (*mi).second;
         return true;
     }
     return false;
 }
 
 static bool ExtractPubKey(const CScript &dest, CPubKey &pubKeyOut) {
     // TODO: Use Solver to extract this?
     CScript::const_iterator pc = dest.begin();
     opcodetype opcode;
-    std::vector<unsigned char> vch;
+    std::vector<uint8_t> vch;
     if (!dest.GetOp(pc, opcode, vch) || vch.size() < 33 || vch.size() > 65)
         return false;
     pubKeyOut = CPubKey(vch);
     if (!pubKeyOut.IsFullyValid()) return false;
     if (!dest.GetOp(pc, opcode, vch) || opcode != OP_CHECKSIG ||
         dest.GetOp(pc, opcode, vch))
         return false;
     return true;
 }
 
 bool CBasicKeyStore::AddWatchOnly(const CScript &dest) {
     LOCK(cs_KeyStore);
     setWatchOnly.insert(dest);
     CPubKey pubKey;
     if (ExtractPubKey(dest, pubKey)) mapWatchKeys[pubKey.GetID()] = pubKey;
     return true;
 }
 
 bool CBasicKeyStore::RemoveWatchOnly(const CScript &dest) {
     LOCK(cs_KeyStore);
     setWatchOnly.erase(dest);
     CPubKey pubKey;
     if (ExtractPubKey(dest, pubKey)) mapWatchKeys.erase(pubKey.GetID());
     return true;
 }
 
 bool CBasicKeyStore::HaveWatchOnly(const CScript &dest) const {
     LOCK(cs_KeyStore);
     return setWatchOnly.count(dest) > 0;
 }
 
 bool CBasicKeyStore::HaveWatchOnly() const {
     LOCK(cs_KeyStore);
     return (!setWatchOnly.empty());
 }
diff --git a/src/keystore.h b/src/keystore.h
index e3cd478d4..157721b25 100644
--- a/src/keystore.h
+++ b/src/keystore.h
@@ -1,114 +1,113 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-2015 The Bitcoin Core developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #ifndef BITCOIN_KEYSTORE_H
 #define BITCOIN_KEYSTORE_H
 
 #include "key.h"
 #include "pubkey.h"
 #include "script/script.h"
 #include "script/standard.h"
 #include "sync.h"
 
 #include <boost/signals2/signal.hpp>
 #include <boost/variant.hpp>
 
 /** A virtual base class for key stores */
 class CKeyStore {
 protected:
     mutable CCriticalSection cs_KeyStore;
 
 public:
     virtual ~CKeyStore() {}
 
     //! Add a key to the store.
     virtual bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey) = 0;
     virtual bool AddKey(const CKey &key);
 
     //! Check whether a key corresponding to a given address is present in the
     //! store.
     virtual bool HaveKey(const CKeyID &address) const = 0;
     virtual bool GetKey(const CKeyID &address, CKey &keyOut) const = 0;
     virtual void GetKeys(std::set<CKeyID> &setAddress) const = 0;
     virtual bool GetPubKey(const CKeyID &address,
                            CPubKey &vchPubKeyOut) const = 0;
 
     //! Support for BIP 0013 : see
     //! https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki
     virtual bool AddCScript(const CScript &redeemScript) = 0;
     virtual bool HaveCScript(const CScriptID &hash) const = 0;
     virtual bool GetCScript(const CScriptID &hash,
                             CScript &redeemScriptOut) const = 0;
 
     //! Support for Watch-only addresses
     virtual bool AddWatchOnly(const CScript &dest) = 0;
     virtual bool RemoveWatchOnly(const CScript &dest) = 0;
     virtual bool HaveWatchOnly(const CScript &dest) const = 0;
     virtual bool HaveWatchOnly() const = 0;
 };
 
 typedef std::map<CKeyID, CKey> KeyMap;
 typedef std::map<CKeyID, CPubKey> WatchKeyMap;
 typedef std::map<CScriptID, CScript> ScriptMap;
 typedef std::set<CScript> WatchOnlySet;
 
 /** Basic key store, that keeps keys in an address->secret map */
 class CBasicKeyStore : public CKeyStore {
 protected:
     KeyMap mapKeys;
     WatchKeyMap mapWatchKeys;
     ScriptMap mapScripts;
     WatchOnlySet setWatchOnly;
 
 public:
     bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey);
     bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const;
     bool HaveKey(const CKeyID &address) const {
         bool result;
         {
             LOCK(cs_KeyStore);
             result = (mapKeys.count(address) > 0);
         }
         return result;
     }
     void GetKeys(std::set<CKeyID> &setAddress) const {
         setAddress.clear();
         {
             LOCK(cs_KeyStore);
             KeyMap::const_iterator mi = mapKeys.begin();
             while (mi != mapKeys.end()) {
                 setAddress.insert((*mi).first);
                 mi++;
             }
         }
     }
     bool GetKey(const CKeyID &address, CKey &keyOut) const {
         {
             LOCK(cs_KeyStore);
             KeyMap::const_iterator mi = mapKeys.find(address);
             if (mi != mapKeys.end()) {
                 keyOut = mi->second;
                 return true;
             }
         }
         return false;
     }
     virtual bool AddCScript(const CScript &redeemScript);
     virtual bool HaveCScript(const CScriptID &hash) const;
     virtual bool GetCScript(const CScriptID &hash,
                             CScript &redeemScriptOut) const;
 
     virtual bool AddWatchOnly(const CScript &dest);
     virtual bool RemoveWatchOnly(const CScript &dest);
     virtual bool HaveWatchOnly(const CScript &dest) const;
     virtual bool HaveWatchOnly() const;
 };
 
-typedef std::vector<unsigned char, secure_allocator<unsigned char>>
-    CKeyingMaterial;
-typedef std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char>>>
+typedef std::vector<uint8_t, secure_allocator<uint8_t>> CKeyingMaterial;
+typedef std::map<CKeyID, std::pair<CPubKey, std::vector<uint8_t>>>
     CryptedKeyMap;
 
 #endif // BITCOIN_KEYSTORE_H
diff --git a/src/merkleblock.h b/src/merkleblock.h
index cb633b2a7..33aaf4f38 100644
--- a/src/merkleblock.h
+++ b/src/merkleblock.h
@@ -1,168 +1,168 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_MERKLEBLOCK_H
 #define BITCOIN_MERKLEBLOCK_H
 
 #include "bloom.h"
 #include "primitives/block.h"
 #include "serialize.h"
 #include "uint256.h"
 
 #include <vector>
 
 /**
  * Data structure that represents a partial merkle tree.
  *
  * It represents a subset of the txid's of a known block, in a way that
  * allows recovery of the list of txid's and the merkle root, in an
  * authenticated way.
  *
  * The encoding works as follows: we traverse the tree in depth-first order,
  * storing a bit for each traversed node, signifying whether the node is the
  * parent of at least one matched leaf txid (or a matched txid itself). In
  * case we are at the leaf level, or this bit is 0, its merkle node hash is
  * stored, and its children are not explorer further. Otherwise, no hash is
  * stored, but we recurse into both (or the only) child branch. During
  * decoding, the same depth-first traversal is performed, consuming bits and
  * hashes as they written during encoding.
  *
  * The serialization is fixed and provides a hard guarantee about the
  * encoded size:
  *
  *   SIZE <= 10 + ceil(32.25*N)
  *
  * Where N represents the number of leaf nodes of the partial tree. N itself
  * is bounded by:
  *
  *   N <= total_transactions
  *   N <= 1 + matched_transactions*tree_height
  *
  * The serialization format:
  *  - uint32     total_transactions (4 bytes)
  *  - varint     number of hashes   (1-3 bytes)
  *  - uint256[]  hashes in depth-first order (<= 32*N bytes)
  *  - varint     number of bytes of flag bits (1-3 bytes)
  *  - byte[]     flag bits, packed per 8 in a byte, least significant bit first
  * (<= 2*N-1 bits)
  * The size constraints follow from this.
  */
 class CPartialMerkleTree {
 protected:
     /** the total number of transactions in the block */
     unsigned int nTransactions;
 
     /** node-is-parent-of-matched-txid bits */
     std::vector<bool> vBits;
 
     /** txids and internal hashes */
     std::vector<uint256> vHash;
 
     /** flag set when encountering invalid data */
     bool fBad;
 
     /** helper function to efficiently calculate the number of nodes at given
      * height in the merkle tree. */
     unsigned int CalcTreeWidth(int height) {
         return (nTransactions + (1 << height) - 1) >> height;
     }
 
     /** Calculate the hash of a node in the merkle tree (at leaf level: the
      * txid's themselves) */
     uint256 CalcHash(int height, unsigned int pos,
                      const std::vector<uint256> &vTxid);
 
     /** Recursive function that traverses tree nodes, storing the data as bits
      * and hashes. */
     void TraverseAndBuild(int height, unsigned int pos,
                           const std::vector<uint256> &vTxid,
                           const std::vector<bool> &vMatch);
 
     /**
      * Recursive function that traverses tree nodes, consuming the bits and
      * hashes produced by TraverseAndBuild. It returns the hash of the
      * respective node and its respective index.
      */
     uint256 TraverseAndExtract(int height, unsigned int pos,
                                unsigned int &nBitsUsed, unsigned int &nHashUsed,
                                std::vector<uint256> &vMatch,
                                std::vector<unsigned int> &vnIndex);
 
 public:
     /** serialization implementation */
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
     inline void SerializationOp(Stream &s, Operation ser_action) {
         READWRITE(nTransactions);
         READWRITE(vHash);
-        std::vector<unsigned char> vBytes;
+        std::vector<uint8_t> vBytes;
         if (ser_action.ForRead()) {
             READWRITE(vBytes);
             CPartialMerkleTree &us = *(const_cast<CPartialMerkleTree *>(this));
             us.vBits.resize(vBytes.size() * 8);
             for (unsigned int p = 0; p < us.vBits.size(); p++)
                 us.vBits[p] = (vBytes[p / 8] & (1 << (p % 8))) != 0;
             us.fBad = false;
         } else {
             vBytes.resize((vBits.size() + 7) / 8);
             for (unsigned int p = 0; p < vBits.size(); p++)
                 vBytes[p / 8] |= vBits[p] << (p % 8);
             READWRITE(vBytes);
         }
     }
 
     /** Construct a partial merkle tree from a list of transaction ids, and a
      * mask that selects a subset of them. */
     CPartialMerkleTree(const std::vector<uint256> &vTxid,
                        const std::vector<bool> &vMatch);
 
     CPartialMerkleTree();
 
     /**
      * Extract the matching txid's represented by this partial merkle tree and
      * their respective indices within the partial tree. Returns the merkle
      * root, or 0 in case of failure
      */
     uint256 ExtractMatches(std::vector<uint256> &vMatch,
                            std::vector<unsigned int> &vnIndex);
 };
 
 /**
  * Used to relay blocks as header + vector<merkle branch>
  * to filtered nodes.
  */
 class CMerkleBlock {
 public:
     /** Public only for unit testing */
     CBlockHeader header;
     CPartialMerkleTree txn;
 
 public:
     /** Public only for unit testing and relay testing (not relayed) */
     std::vector<std::pair<unsigned int, uint256>> vMatchedTxn;
 
     /**
      * Create from a CBlock, filtering transactions according to filter. Note
      * that this will call IsRelevantAndUpdate on the filter for each
      * transaction, thus the filter will likely be modified.
      */
     CMerkleBlock(const CBlock &block, CBloomFilter &filter);
 
     // Create from a CBlock, matching the txids in the set.
     CMerkleBlock(const CBlock &block, const std::set<uint256> &txids);
 
     CMerkleBlock() {}
 
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
     inline void SerializationOp(Stream &s, Operation ser_action) {
         READWRITE(header);
         READWRITE(txn);
     }
 };
 
 #endif // BITCOIN_MERKLEBLOCK_H
diff --git a/src/miner.cpp b/src/miner.cpp
index 01c99b079..928432e0e 100644
--- a/src/miner.cpp
+++ b/src/miner.cpp
@@ -1,663 +1,663 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #include "miner.h"
 
 #include "amount.h"
 #include "chain.h"
 #include "chainparams.h"
 #include "coins.h"
 #include "config.h"
 #include "consensus/consensus.h"
 #include "consensus/merkle.h"
 #include "consensus/validation.h"
 #include "hash.h"
 #include "net.h"
 #include "policy/policy.h"
 #include "pow.h"
 #include "primitives/transaction.h"
 #include "script/standard.h"
 #include "timedata.h"
 #include "txmempool.h"
 #include "util.h"
 #include "utilmoneystr.h"
 #include "validation.h"
 #include "validationinterface.h"
 
 #include <algorithm>
 #include <queue>
 #include <utility>
 
 #include <boost/thread.hpp>
 #include <boost/tuple/tuple.hpp>
 
 static const int MAX_COINBASE_SCRIPTSIG_SIZE = 100;
 
 //////////////////////////////////////////////////////////////////////////////
 //
 // BitcoinMiner
 //
 
 //
 // Unconfirmed transactions in the memory pool often depend on other
 // transactions in the memory pool. When we select transactions from the
 // pool, we select by highest priority or fee rate, so we might consider
 // transactions that depend on transactions that aren't yet in the block.
 
 uint64_t nLastBlockTx = 0;
 uint64_t nLastBlockSize = 0;
 
 class ScoreCompare {
 public:
     ScoreCompare() {}
 
     bool operator()(const CTxMemPool::txiter a, const CTxMemPool::txiter b) {
         // Convert to less than.
         return CompareTxMemPoolEntryByScore()(*b, *a);
     }
 };
 
 int64_t UpdateTime(CBlockHeader *pblock,
                    const Consensus::Params &consensusParams,
                    const CBlockIndex *pindexPrev) {
     int64_t nOldTime = pblock->nTime;
     int64_t nNewTime =
         std::max(pindexPrev->GetMedianTimePast() + 1, GetAdjustedTime());
 
     if (nOldTime < nNewTime) {
         pblock->nTime = nNewTime;
     }
 
     // Updating time can change work required on testnet:
     if (consensusParams.fPowAllowMinDifficultyBlocks) {
         pblock->nBits =
             GetNextWorkRequired(pindexPrev, pblock, consensusParams);
     }
 
     return nNewTime - nOldTime;
 }
 
 static uint64_t ComputeMaxGeneratedBlockSize(const Config &config,
                                              const CBlockIndex *pindexPrev) {
     // Block resource limits
     // If -blockmaxsize is not given, limit to DEFAULT_MAX_GENERATED_BLOCK_SIZE
     // If only one is given, only restrict the specified resource.
     // If both are given, restrict both.
     uint64_t nMaxGeneratedBlockSize = DEFAULT_MAX_GENERATED_BLOCK_SIZE;
     if (IsArgSet("-blockmaxsize")) {
         nMaxGeneratedBlockSize =
             GetArg("-blockmaxsize", DEFAULT_MAX_GENERATED_BLOCK_SIZE);
     }
 
     // Limit size to between 1K and MaxBlockSize-1K for sanity:
     nMaxGeneratedBlockSize =
         std::max(uint64_t(1000), std::min(config.GetMaxBlockSize() - 1000,
                                           nMaxGeneratedBlockSize));
 
     return nMaxGeneratedBlockSize;
 }
 
 BlockAssembler::BlockAssembler(const Config &_config,
                                const CChainParams &_chainparams)
     : chainparams(_chainparams), config(&_config) {
     if (IsArgSet("-blockmintxfee")) {
         CAmount n = 0;
         ParseMoney(GetArg("-blockmintxfee", ""), n);
         blockMinFeeRate = CFeeRate(n);
     } else {
         blockMinFeeRate = CFeeRate(DEFAULT_BLOCK_MIN_TX_FEE);
     }
 
     LOCK(cs_main);
     nMaxGeneratedBlockSize =
         ComputeMaxGeneratedBlockSize(*config, chainActive.Tip());
 }
 
 void BlockAssembler::resetBlock() {
     inBlock.clear();
 
     // Reserve space for coinbase tx.
     nBlockSize = 1000;
     nBlockSigOps = 100;
 
     // These counters do not include coinbase tx.
     nBlockTx = 0;
     nFees = 0;
 
     lastFewTxs = 0;
     blockFinished = false;
 }
 
-static const std::vector<unsigned char>
+static const std::vector<uint8_t>
 getExcessiveBlockSizeSig(const Config &config) {
     std::string cbmsg = "/EB" + getSubVersionEB(config.GetMaxBlockSize()) + "/";
     const char *cbcstr = cbmsg.c_str();
-    std::vector<unsigned char> vec(cbcstr, cbcstr + cbmsg.size());
+    std::vector<uint8_t> vec(cbcstr, cbcstr + cbmsg.size());
     return vec;
 }
 
 std::unique_ptr<CBlockTemplate>
 BlockAssembler::CreateNewBlock(const CScript &scriptPubKeyIn) {
     int64_t nTimeStart = GetTimeMicros();
 
     resetBlock();
 
     pblocktemplate.reset(new CBlockTemplate());
     if (!pblocktemplate.get()) {
         return nullptr;
     }
 
     // Pointer for convenience.
     pblock = &pblocktemplate->block;
 
     // Add dummy coinbase tx as first transaction.
     pblock->vtx.emplace_back();
     // updated at end
     pblocktemplate->vTxFees.push_back(-1);
     // updated at end
     pblocktemplate->vTxSigOpsCount.push_back(-1);
 
     LOCK2(cs_main, mempool.cs);
     CBlockIndex *pindexPrev = chainActive.Tip();
     nHeight = pindexPrev->nHeight + 1;
 
     pblock->nVersion =
         ComputeBlockVersion(pindexPrev, chainparams.GetConsensus());
     // -regtest only: allow overriding block.nVersion with
     // -blockversion=N to test forking scenarios
     if (chainparams.MineBlocksOnDemand()) {
         pblock->nVersion = GetArg("-blockversion", pblock->nVersion);
     }
 
     pblock->nTime = GetAdjustedTime();
     nMedianTimePast = pindexPrev->GetMedianTimePast();
     nMaxGeneratedBlockSize = ComputeMaxGeneratedBlockSize(*config, pindexPrev);
 
     nLockTimeCutoff =
         (STANDARD_LOCKTIME_VERIFY_FLAGS & LOCKTIME_MEDIAN_TIME_PAST)
             ? nMedianTimePast
             : pblock->GetBlockTime();
 
     addPriorityTxs();
     int nPackagesSelected = 0;
     int nDescendantsUpdated = 0;
     addPackageTxs(nPackagesSelected, nDescendantsUpdated);
 
     int64_t nTime1 = GetTimeMicros();
 
     nLastBlockTx = nBlockTx;
     nLastBlockSize = nBlockSize;
 
     // Create coinbase transaction.
     CMutableTransaction coinbaseTx;
     coinbaseTx.vin.resize(1);
     coinbaseTx.vin[0].prevout.SetNull();
     coinbaseTx.vout.resize(1);
     coinbaseTx.vout[0].scriptPubKey = scriptPubKeyIn;
     coinbaseTx.vout[0].nValue =
         nFees + GetBlockSubsidy(nHeight, chainparams.GetConsensus());
     coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0;
     pblock->vtx[0] = MakeTransactionRef(coinbaseTx);
     pblocktemplate->vTxFees[0] = -nFees;
 
     uint64_t nSerializeSize =
         GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION);
 
     LogPrintf("CreateNewBlock(): total size: %u txs: %u fees: %ld sigops %d\n",
               nSerializeSize, nBlockTx, nFees, nBlockSigOps);
 
     // Fill in header.
     pblock->hashPrevBlock = pindexPrev->GetBlockHash();
     UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
     pblock->nBits =
         GetNextWorkRequired(pindexPrev, pblock, chainparams.GetConsensus());
     pblock->nNonce = 0;
     pblocktemplate->vTxSigOpsCount[0] =
         GetSigOpCountWithoutP2SH(*pblock->vtx[0]);
 
     CValidationState state;
     if (!TestBlockValidity(*config, state, chainparams, *pblock, pindexPrev,
                            false, false)) {
         throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s",
                                            __func__,
                                            FormatStateMessage(state)));
     }
     int64_t nTime2 = GetTimeMicros();
 
     LogPrint("bench", "CreateNewBlock() packages: %.2fms (%d packages, %d "
                       "updated descendants), validity: %.2fms (total %.2fms)\n",
              0.001 * (nTime1 - nTimeStart), nPackagesSelected,
              nDescendantsUpdated, 0.001 * (nTime2 - nTime1),
              0.001 * (nTime2 - nTimeStart));
 
     return std::move(pblocktemplate);
 }
 
 bool BlockAssembler::isStillDependent(CTxMemPool::txiter iter) {
     for (CTxMemPool::txiter parent : mempool.GetMemPoolParents(iter)) {
         if (!inBlock.count(parent)) {
             return true;
         }
     }
     return false;
 }
 
 void BlockAssembler::onlyUnconfirmed(CTxMemPool::setEntries &testSet) {
     for (CTxMemPool::setEntries::iterator iit = testSet.begin();
          iit != testSet.end();) {
         // Only test txs not already in the block.
         if (inBlock.count(*iit)) {
             testSet.erase(iit++);
         } else {
             iit++;
         }
     }
 }
 
 bool BlockAssembler::TestPackage(uint64_t packageSize, int64_t packageSigOps) {
     auto blockSizeWithPackage = nBlockSize + packageSize;
     if (blockSizeWithPackage >= nMaxGeneratedBlockSize) {
         return false;
     }
     if (nBlockSigOps + packageSigOps >=
         GetMaxBlockSigOpsCount(blockSizeWithPackage)) {
         return false;
     }
     return true;
 }
 
 // Perform transaction-level checks before adding to block:
 // - transaction finality (locktime)
 // - serialized size (in case -blockmaxsize is in use)
 bool BlockAssembler::TestPackageTransactions(
     const CTxMemPool::setEntries &package) {
     uint64_t nPotentialBlockSize = nBlockSize;
     for (const CTxMemPool::txiter it : package) {
         CValidationState state;
         if (!ContextualCheckTransaction(*config, it->GetTx(), state,
                                         chainparams.GetConsensus(), nHeight,
                                         nLockTimeCutoff, nMedianTimePast)) {
             return false;
         }
 
         uint64_t nTxSize =
             ::GetSerializeSize(it->GetTx(), SER_NETWORK, PROTOCOL_VERSION);
         if (nPotentialBlockSize + nTxSize >= nMaxGeneratedBlockSize) {
             return false;
         }
 
         nPotentialBlockSize += nTxSize;
     }
 
     return true;
 }
 
 bool BlockAssembler::TestForBlock(CTxMemPool::txiter it) {
     auto blockSizeWithTx =
         nBlockSize +
         ::GetSerializeSize(it->GetTx(), SER_NETWORK, PROTOCOL_VERSION);
     if (blockSizeWithTx >= nMaxGeneratedBlockSize) {
         if (nBlockSize > nMaxGeneratedBlockSize - 100 || lastFewTxs > 50) {
             blockFinished = true;
             return false;
         }
         if (nBlockSize > nMaxGeneratedBlockSize - 1000) {
             lastFewTxs++;
         }
         return false;
     }
 
     auto maxBlockSigOps = GetMaxBlockSigOpsCount(blockSizeWithTx);
     if (nBlockSigOps + it->GetSigOpCount() >= maxBlockSigOps) {
         // If the block has room for no more sig ops then flag that the block is
         // finished.
         // TODO: We should consider adding another transaction that isn't very
         // dense in sigops instead of bailing out so easily.
         if (nBlockSigOps > maxBlockSigOps - 2) {
             blockFinished = true;
             return false;
         }
         // Otherwise attempt to find another tx with fewer sigops to put in the
         // block.
         return false;
     }
 
     // Must check that lock times are still valid. This can be removed once MTP
     // is always enforced as long as reorgs keep the mempool consistent.
     CValidationState state;
     if (!ContextualCheckTransaction(*config, it->GetTx(), state,
                                     chainparams.GetConsensus(), nHeight,
                                     nLockTimeCutoff, nMedianTimePast)) {
         return false;
     }
 
     return true;
 }
 
 void BlockAssembler::AddToBlock(CTxMemPool::txiter iter) {
     pblock->vtx.emplace_back(iter->GetSharedTx());
     pblocktemplate->vTxFees.push_back(iter->GetFee());
     pblocktemplate->vTxSigOpsCount.push_back(iter->GetSigOpCount());
     nBlockSize += iter->GetTxSize();
     ++nBlockTx;
     nBlockSigOps += iter->GetSigOpCount();
     nFees += iter->GetFee();
     inBlock.insert(iter);
 
     bool fPrintPriority = GetBoolArg("-printpriority", DEFAULT_PRINTPRIORITY);
     if (fPrintPriority) {
         double dPriority = iter->GetPriority(nHeight);
         CAmount dummy;
         mempool.ApplyDeltas(iter->GetTx().GetId(), dPriority, dummy);
         LogPrintf(
             "priority %.1f fee %s txid %s\n", dPriority,
             CFeeRate(iter->GetModifiedFee(), iter->GetTxSize()).ToString(),
             iter->GetTx().GetId().ToString());
     }
 }
 
 int BlockAssembler::UpdatePackagesForAdded(
     const CTxMemPool::setEntries &alreadyAdded,
     indexed_modified_transaction_set &mapModifiedTx) {
     int nDescendantsUpdated = 0;
     for (const CTxMemPool::txiter it : alreadyAdded) {
         CTxMemPool::setEntries descendants;
         mempool.CalculateDescendants(it, descendants);
         // Insert all descendants (not yet in block) into the modified set.
         for (CTxMemPool::txiter desc : descendants) {
             if (alreadyAdded.count(desc)) {
                 continue;
             }
             ++nDescendantsUpdated;
             modtxiter mit = mapModifiedTx.find(desc);
             if (mit == mapModifiedTx.end()) {
                 CTxMemPoolModifiedEntry modEntry(desc);
                 modEntry.nSizeWithAncestors -= it->GetTxSize();
                 modEntry.nModFeesWithAncestors -= it->GetModifiedFee();
                 modEntry.nSigOpCountWithAncestors -= it->GetSigOpCount();
                 mapModifiedTx.insert(modEntry);
             } else {
                 mapModifiedTx.modify(mit, update_for_parent_inclusion(it));
             }
         }
     }
     return nDescendantsUpdated;
 }
 
 // Skip entries in mapTx that are already in a block or are present in
 // mapModifiedTx (which implies that the mapTx ancestor state is stale due to
 // ancestor inclusion in the block). Also skip transactions that we've already
 // failed to add. This can happen if we consider a transaction in mapModifiedTx
 // and it fails: we can then potentially consider it again while walking mapTx.
 // It's currently guaranteed to fail again, but as a belt-and-suspenders check
 // we put it in failedTx and avoid re-evaluation, since the re-evaluation would
 // be using cached size/sigops/fee values that are not actually correct.
 bool BlockAssembler::SkipMapTxEntry(
     CTxMemPool::txiter it, indexed_modified_transaction_set &mapModifiedTx,
     CTxMemPool::setEntries &failedTx) {
     assert(it != mempool.mapTx.end());
     if (mapModifiedTx.count(it) || inBlock.count(it) || failedTx.count(it)) {
         return true;
     }
     return false;
 }
 
 void BlockAssembler::SortForBlock(
     const CTxMemPool::setEntries &package, CTxMemPool::txiter entry,
     std::vector<CTxMemPool::txiter> &sortedEntries) {
     // Sort package by ancestor count. If a transaction A depends on transaction
     // B, then A's ancestor count must be greater than B's. So this is
     // sufficient to validly order the transactions for block inclusion.
     sortedEntries.clear();
     sortedEntries.insert(sortedEntries.begin(), package.begin(), package.end());
     std::sort(sortedEntries.begin(), sortedEntries.end(),
               CompareTxIterByAncestorCount());
 }
 
 // This transaction selection algorithm orders the mempool based on feerate of a
 // transaction including all unconfirmed ancestors. Since we don't remove
 // transactions from the mempool as we select them for block inclusion, we need
 // an alternate method of updating the feerate of a transaction with its
 // not-yet-selected ancestors as we go. This is accomplished by walking the
 // in-mempool descendants of selected transactions and storing a temporary
 // modified state in mapModifiedTxs. Each time through the loop, we compare the
 // best transaction in mapModifiedTxs with the next transaction in the mempool
 // to decide what transaction package to work on next.
 void BlockAssembler::addPackageTxs(int &nPackagesSelected,
                                    int &nDescendantsUpdated) {
     // mapModifiedTx will store sorted packages after they are modified because
     // some of their txs are already in the block.
     indexed_modified_transaction_set mapModifiedTx;
     // Keep track of entries that failed inclusion, to avoid duplicate work.
     CTxMemPool::setEntries failedTx;
 
     // Start by adding all descendants of previously added txs to mapModifiedTx
     // and modifying them for their already included ancestors.
     UpdatePackagesForAdded(inBlock, mapModifiedTx);
 
     CTxMemPool::indexed_transaction_set::index<ancestor_score>::type::iterator
         mi = mempool.mapTx.get<ancestor_score>().begin();
     CTxMemPool::txiter iter;
 
     // Limit the number of attempts to add transactions to the block when it is
     // close to full; this is just a simple heuristic to finish quickly if the
     // mempool has a lot of entries.
     const int64_t MAX_CONSECUTIVE_FAILURES = 1000;
     int64_t nConsecutiveFailed = 0;
 
     while (mi != mempool.mapTx.get<ancestor_score>().end() ||
            !mapModifiedTx.empty()) {
         // First try to find a new transaction in mapTx to evaluate.
         if (mi != mempool.mapTx.get<ancestor_score>().end() &&
             SkipMapTxEntry(mempool.mapTx.project<0>(mi), mapModifiedTx,
                            failedTx)) {
             ++mi;
             continue;
         }
 
         // Now that mi is not stale, determine which transaction to evaluate:
         // the next entry from mapTx, or the best from mapModifiedTx?
         bool fUsingModified = false;
 
         modtxscoreiter modit = mapModifiedTx.get<ancestor_score>().begin();
         if (mi == mempool.mapTx.get<ancestor_score>().end()) {
             // We're out of entries in mapTx; use the entry from mapModifiedTx
             iter = modit->iter;
             fUsingModified = true;
         } else {
             // Try to compare the mapTx entry to the mapModifiedTx entry.
             iter = mempool.mapTx.project<0>(mi);
             if (modit != mapModifiedTx.get<ancestor_score>().end() &&
                 CompareModifiedEntry()(*modit, CTxMemPoolModifiedEntry(iter))) {
                 // The best entry in mapModifiedTx has higher score than the one
                 // from mapTx. Switch which transaction (package) to consider
                 iter = modit->iter;
                 fUsingModified = true;
             } else {
                 // Either no entry in mapModifiedTx, or it's worse than mapTx.
                 // Increment mi for the next loop iteration.
                 ++mi;
             }
         }
 
         // We skip mapTx entries that are inBlock, and mapModifiedTx shouldn't
         // contain anything that is inBlock.
         assert(!inBlock.count(iter));
 
         uint64_t packageSize = iter->GetSizeWithAncestors();
         CAmount packageFees = iter->GetModFeesWithAncestors();
         int64_t packageSigOps = iter->GetSigOpCountWithAncestors();
         if (fUsingModified) {
             packageSize = modit->nSizeWithAncestors;
             packageFees = modit->nModFeesWithAncestors;
             packageSigOps = modit->nSigOpCountWithAncestors;
         }
 
         if (packageFees < blockMinFeeRate.GetFee(packageSize)) {
             // Everything else we might consider has a lower fee rate
             return;
         }
 
         if (!TestPackage(packageSize, packageSigOps)) {
             if (fUsingModified) {
                 // Since we always look at the best entry in mapModifiedTx, we
                 // must erase failed entries so that we can consider the next
                 // best entry on the next loop iteration
                 mapModifiedTx.get<ancestor_score>().erase(modit);
                 failedTx.insert(iter);
             }
 
             ++nConsecutiveFailed;
 
             if (nConsecutiveFailed > MAX_CONSECUTIVE_FAILURES &&
                 nBlockSize > nMaxGeneratedBlockSize - 1000) {
                 // Give up if we're close to full and haven't succeeded in a
                 // while.
                 break;
             }
             continue;
         }
 
         CTxMemPool::setEntries ancestors;
         uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
         std::string dummy;
         mempool.CalculateMemPoolAncestors(*iter, ancestors, nNoLimit, nNoLimit,
                                           nNoLimit, nNoLimit, dummy, false);
 
         onlyUnconfirmed(ancestors);
         ancestors.insert(iter);
 
         // Test if all tx's are Final.
         if (!TestPackageTransactions(ancestors)) {
             if (fUsingModified) {
                 mapModifiedTx.get<ancestor_score>().erase(modit);
                 failedTx.insert(iter);
             }
             continue;
         }
 
         // This transaction will make it in; reset the failed counter.
         nConsecutiveFailed = 0;
 
         // Package can be added. Sort the entries in a valid order.
         std::vector<CTxMemPool::txiter> sortedEntries;
         SortForBlock(ancestors, iter, sortedEntries);
 
         for (size_t i = 0; i < sortedEntries.size(); ++i) {
             AddToBlock(sortedEntries[i]);
             // Erase from the modified set, if present
             mapModifiedTx.erase(sortedEntries[i]);
         }
 
         ++nPackagesSelected;
 
         // Update transactions that depend on each of these
         nDescendantsUpdated += UpdatePackagesForAdded(ancestors, mapModifiedTx);
     }
 }
 
 void BlockAssembler::addPriorityTxs() {
     // How much of the block should be dedicated to high-priority transactions,
     // included regardless of the fees they pay.
     uint64_t nBlockPrioritySize =
         GetArg("-blockprioritysize", DEFAULT_BLOCK_PRIORITY_SIZE);
     nBlockPrioritySize = std::min(nMaxGeneratedBlockSize, nBlockPrioritySize);
     if (nBlockPrioritySize == 0) {
         return;
     }
 
     // This vector will be sorted into a priority queue:
     std::vector<TxCoinAgePriority> vecPriority;
     TxCoinAgePriorityCompare pricomparer;
     std::map<CTxMemPool::txiter, double, CTxMemPool::CompareIteratorByHash>
         waitPriMap;
     typedef std::map<CTxMemPool::txiter, double,
                      CTxMemPool::CompareIteratorByHash>::iterator waitPriIter;
     double actualPriority = -1;
 
     vecPriority.reserve(mempool.mapTx.size());
     for (CTxMemPool::indexed_transaction_set::iterator mi =
              mempool.mapTx.begin();
          mi != mempool.mapTx.end(); ++mi) {
         double dPriority = mi->GetPriority(nHeight);
         CAmount dummy;
         mempool.ApplyDeltas(mi->GetTx().GetId(), dPriority, dummy);
         vecPriority.push_back(TxCoinAgePriority(dPriority, mi));
     }
     std::make_heap(vecPriority.begin(), vecPriority.end(), pricomparer);
 
     CTxMemPool::txiter iter;
 
     // Add a tx from priority queue to fill the blockprioritysize.
     while (!vecPriority.empty() && !blockFinished) {
         iter = vecPriority.front().second;
         actualPriority = vecPriority.front().first;
         std::pop_heap(vecPriority.begin(), vecPriority.end(), pricomparer);
         vecPriority.pop_back();
 
         // If tx already in block, skip.
         if (inBlock.count(iter)) {
             // Shouldn't happen for priority txs.
             assert(false);
             continue;
         }
 
         // If tx is dependent on other mempool txs which haven't yet been
         // included then put it in the waitSet.
         if (isStillDependent(iter)) {
             waitPriMap.insert(std::make_pair(iter, actualPriority));
             continue;
         }
 
         // If this tx fits in the block add it, otherwise keep looping.
         if (TestForBlock(iter)) {
             AddToBlock(iter);
 
             // If now that this txs is added we've surpassed our desired
             // priority size or have dropped below the AllowFreeThreshold, then
             // we're done adding priority txs.
             if (nBlockSize >= nBlockPrioritySize ||
                 !AllowFree(actualPriority)) {
                 break;
             }
 
             // This tx was successfully added, so add transactions that depend
             // on this one to the priority queue to try again.
             for (CTxMemPool::txiter child : mempool.GetMemPoolChildren(iter)) {
                 waitPriIter wpiter = waitPriMap.find(child);
                 if (wpiter != waitPriMap.end()) {
                     vecPriority.push_back(
                         TxCoinAgePriority(wpiter->second, child));
                     std::push_heap(vecPriority.begin(), vecPriority.end(),
                                    pricomparer);
                     waitPriMap.erase(wpiter);
                 }
             }
         }
     }
 }
 
 void IncrementExtraNonce(const Config &config, CBlock *pblock,
                          const CBlockIndex *pindexPrev,
                          unsigned int &nExtraNonce) {
     // Update nExtraNonce
     static uint256 hashPrevBlock;
     if (hashPrevBlock != pblock->hashPrevBlock) {
         nExtraNonce = 0;
         hashPrevBlock = pblock->hashPrevBlock;
     }
     ++nExtraNonce;
     // Height first in coinbase required for block.version=2
     unsigned int nHeight = pindexPrev->nHeight + 1;
     CMutableTransaction txCoinbase(*pblock->vtx[0]);
     txCoinbase.vin[0].scriptSig =
         (CScript() << nHeight << CScriptNum(nExtraNonce)
                    << getExcessiveBlockSizeSig(config)) +
         COINBASE_FLAGS;
     assert(txCoinbase.vin[0].scriptSig.size() <= MAX_COINBASE_SCRIPTSIG_SIZE);
 
     pblock->vtx[0] = MakeTransactionRef(std::move(txCoinbase));
     pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
 }
diff --git a/src/net.cpp b/src/net.cpp
index 9ad81c03c..90a520d0b 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -1,3059 +1,3059 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #if defined(HAVE_CONFIG_H)
 #include "config/bitcoin-config.h"
 #endif
 
 #include "net.h"
 
 #include "addrman.h"
 #include "chainparams.h"
 #include "clientversion.h"
 #include "config.h"
 #include "consensus/consensus.h"
 #include "crypto/common.h"
 #include "crypto/sha256.h"
 #include "hash.h"
 #include "netbase.h"
 #include "primitives/transaction.h"
 #include "scheduler.h"
 #include "ui_interface.h"
 #include "utilstrencodings.h"
 
 #ifdef WIN32
 #include <string.h>
 #else
 #include <fcntl.h>
 #endif
 
 #ifdef USE_UPNP
 #include <miniupnpc/miniupnpc.h>
 #include <miniupnpc/miniwget.h>
 #include <miniupnpc/upnpcommands.h>
 #include <miniupnpc/upnperrors.h>
 #endif
 
 #include <cmath>
 
 // Dump addresses to peers.dat and banlist.dat every 15 minutes (900s)
 #define DUMP_ADDRESSES_INTERVAL 900
 
 // We add a random period time (0 to 1 seconds) to feeler connections to prevent
 // synchronization.
 #define FEELER_SLEEP_WINDOW 1
 
 #if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
 #define MSG_NOSIGNAL 0
 #endif
 
 // Fix for ancient MinGW versions, that don't have defined these in ws2tcpip.h.
 // Todo: Can be removed when our pull-tester is upgraded to a modern MinGW
 // version.
 #ifdef WIN32
 #ifndef PROTECTION_LEVEL_UNRESTRICTED
 #define PROTECTION_LEVEL_UNRESTRICTED 10
 #endif
 #ifndef IPV6_PROTECTION_LEVEL
 #define IPV6_PROTECTION_LEVEL 23
 #endif
 #endif
 
 static const std::string NET_MESSAGE_COMMAND_OTHER = "*other*";
 
 // SHA256("netgroup")[0:8]
 static const uint64_t RANDOMIZER_ID_NETGROUP = 0x6c0edd8036ef4036ULL;
 // SHA256("localhostnonce")[0:8]
 static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE = 0xd93e69e2bbfa5735ULL;
 //
 // Global state variables
 //
 bool fDiscover = true;
 bool fListen = true;
 bool fRelayTxes = true;
 CCriticalSection cs_mapLocalHost;
 std::map<CNetAddr, LocalServiceInfo> mapLocalHost;
 static bool vfLimited[NET_MAX] = {};
 
 limitedmap<uint256, int64_t> mapAlreadyAskedFor(MAX_INV_SZ);
 
 // Signals for message handling
 static CNodeSignals g_signals;
 CNodeSignals &GetNodeSignals() {
     return g_signals;
 }
 
 void CConnman::AddOneShot(const std::string &strDest) {
     LOCK(cs_vOneShots);
     vOneShots.push_back(strDest);
 }
 
 unsigned short GetListenPort() {
     return (unsigned short)(GetArg("-port", Params().GetDefaultPort()));
 }
 
 // find 'best' local address for a particular peer
 bool GetLocal(CService &addr, const CNetAddr *paddrPeer) {
     if (!fListen) return false;
 
     int nBestScore = -1;
     int nBestReachability = -1;
     {
         LOCK(cs_mapLocalHost);
         for (std::map<CNetAddr, LocalServiceInfo>::iterator it =
                  mapLocalHost.begin();
              it != mapLocalHost.end(); it++) {
             int nScore = (*it).second.nScore;
             int nReachability = (*it).first.GetReachabilityFrom(paddrPeer);
             if (nReachability > nBestReachability ||
                 (nReachability == nBestReachability && nScore > nBestScore)) {
                 addr = CService((*it).first, (*it).second.nPort);
                 nBestReachability = nReachability;
                 nBestScore = nScore;
             }
         }
     }
     return nBestScore >= 0;
 }
 
 //! Convert the pnSeeds6 array into usable address objects.
 static std::vector<CAddress>
 convertSeed6(const std::vector<SeedSpec6> &vSeedsIn) {
     // It'll only connect to one or two seed nodes because once it connects,
     // it'll get a pile of addresses with newer timestamps. Seed nodes are given
     // a random 'last seen time' of between one and two weeks ago.
     const int64_t nOneWeek = 7 * 24 * 60 * 60;
     std::vector<CAddress> vSeedsOut;
     vSeedsOut.reserve(vSeedsIn.size());
     for (std::vector<SeedSpec6>::const_iterator i(vSeedsIn.begin());
          i != vSeedsIn.end(); ++i) {
         struct in6_addr ip;
         memcpy(&ip, i->addr, sizeof(ip));
         CAddress addr(CService(ip, i->port), NODE_NETWORK);
         addr.nTime = GetTime() - GetRand(nOneWeek) - nOneWeek;
         vSeedsOut.push_back(addr);
     }
     return vSeedsOut;
 }
 
 // Get best local address for a particular peer as a CAddress. Otherwise, return
 // the unroutable 0.0.0.0 but filled in with the normal parameters, since the IP
 // may be changed to a useful one by discovery.
 CAddress GetLocalAddress(const CNetAddr *paddrPeer,
                          ServiceFlags nLocalServices) {
     CAddress ret(CService(CNetAddr(), GetListenPort()), NODE_NONE);
     CService addr;
     if (GetLocal(addr, paddrPeer)) {
         ret = CAddress(addr, nLocalServices);
     }
     ret.nTime = GetAdjustedTime();
     return ret;
 }
 
 int GetnScore(const CService &addr) {
     LOCK(cs_mapLocalHost);
     if (mapLocalHost.count(addr) == LOCAL_NONE) {
         return 0;
     }
     return mapLocalHost[addr].nScore;
 }
 
 // Is our peer's addrLocal potentially useful as an external IP source?
 bool IsPeerAddrLocalGood(CNode *pnode) {
     CService addrLocal = pnode->GetAddrLocal();
     return fDiscover && pnode->addr.IsRoutable() && addrLocal.IsRoutable() &&
            !IsLimited(addrLocal.GetNetwork());
 }
 
 // Pushes our own address to a peer.
 void AdvertiseLocal(CNode *pnode) {
     if (fListen && pnode->fSuccessfullyConnected) {
         CAddress addrLocal =
             GetLocalAddress(&pnode->addr, pnode->GetLocalServices());
         // If discovery is enabled, sometimes give our peer the address it tells
         // us that it sees us as in case it has a better idea of our address
         // than we do.
         if (IsPeerAddrLocalGood(pnode) &&
             (!addrLocal.IsRoutable() ||
              GetRand((GetnScore(addrLocal) > LOCAL_MANUAL) ? 8 : 2) == 0)) {
             addrLocal.SetIP(pnode->GetAddrLocal());
         }
         if (addrLocal.IsRoutable()) {
             LogPrint("net", "AdvertiseLocal: advertising address %s\n",
                      addrLocal.ToString());
             FastRandomContext insecure_rand;
             pnode->PushAddress(addrLocal, insecure_rand);
         }
     }
 }
 
 // Learn a new local address.
 bool AddLocal(const CService &addr, int nScore) {
     if (!addr.IsRoutable()) {
         return false;
     }
 
     if (!fDiscover && nScore < LOCAL_MANUAL) {
         return false;
     }
 
     if (IsLimited(addr)) {
         return false;
     }
 
     LogPrintf("AddLocal(%s,%i)\n", addr.ToString(), nScore);
 
     {
         LOCK(cs_mapLocalHost);
         bool fAlready = mapLocalHost.count(addr) > 0;
         LocalServiceInfo &info = mapLocalHost[addr];
         if (!fAlready || nScore >= info.nScore) {
             info.nScore = nScore + (fAlready ? 1 : 0);
             info.nPort = addr.GetPort();
         }
     }
 
     return true;
 }
 
 bool AddLocal(const CNetAddr &addr, int nScore) {
     return AddLocal(CService(addr, GetListenPort()), nScore);
 }
 
 bool RemoveLocal(const CService &addr) {
     LOCK(cs_mapLocalHost);
     LogPrintf("RemoveLocal(%s)\n", addr.ToString());
     mapLocalHost.erase(addr);
     return true;
 }
 
 /** Make a particular network entirely off-limits (no automatic connects to it)
  */
 void SetLimited(enum Network net, bool fLimited) {
     if (net == NET_UNROUTABLE) {
         return;
     }
     LOCK(cs_mapLocalHost);
     vfLimited[net] = fLimited;
 }
 
 bool IsLimited(enum Network net) {
     LOCK(cs_mapLocalHost);
     return vfLimited[net];
 }
 
 bool IsLimited(const CNetAddr &addr) {
     return IsLimited(addr.GetNetwork());
 }
 
 /** vote for a local address */
 bool SeenLocal(const CService &addr) {
     LOCK(cs_mapLocalHost);
     if (mapLocalHost.count(addr) == 0) {
         return false;
     }
     mapLocalHost[addr].nScore++;
     return true;
 }
 
 /** check whether a given address is potentially local */
 bool IsLocal(const CService &addr) {
     LOCK(cs_mapLocalHost);
     return mapLocalHost.count(addr) > 0;
 }
 
 /** check whether a given network is one we can probably connect to */
 bool IsReachable(enum Network net) {
     LOCK(cs_mapLocalHost);
     return !vfLimited[net];
 }
 
 /** check whether a given address is in a network we can probably connect to */
 bool IsReachable(const CNetAddr &addr) {
     enum Network net = addr.GetNetwork();
     return IsReachable(net);
 }
 
 CNode *CConnman::FindNode(const CNetAddr &ip) {
     LOCK(cs_vNodes);
     for (CNode *pnode : vNodes) {
         if ((CNetAddr)pnode->addr == ip) {
             return pnode;
         }
     }
     return nullptr;
 }
 
 CNode *CConnman::FindNode(const CSubNet &subNet) {
     LOCK(cs_vNodes);
     for (CNode *pnode : vNodes) {
         if (subNet.Match((CNetAddr)pnode->addr)) {
             return pnode;
         }
     }
     return nullptr;
 }
 
 CNode *CConnman::FindNode(const std::string &addrName) {
     LOCK(cs_vNodes);
     for (CNode *pnode : vNodes) {
         if (pnode->GetAddrName() == addrName) {
             return pnode;
         }
     }
     return nullptr;
 }
 
 CNode *CConnman::FindNode(const CService &addr) {
     LOCK(cs_vNodes);
     for (CNode *pnode : vNodes) {
         if ((CService)pnode->addr == addr) {
             return pnode;
         }
     }
     return nullptr;
 }
 
 bool CConnman::CheckIncomingNonce(uint64_t nonce) {
     LOCK(cs_vNodes);
     for (CNode *pnode : vNodes) {
         if (!pnode->fSuccessfullyConnected && !pnode->fInbound &&
             pnode->GetLocalNonce() == nonce)
             return false;
     }
     return true;
 }
 
 CNode *CConnman::ConnectNode(CAddress addrConnect, const char *pszDest,
                              bool fCountFailure) {
     if (pszDest == nullptr) {
         if (IsLocal(addrConnect)) {
             return nullptr;
         }
 
         // Look for an existing connection
         CNode *pnode = FindNode((CService)addrConnect);
         if (pnode) {
             LogPrintf("Failed to open new connection, already connected\n");
             return nullptr;
         }
     }
 
     /// debug print
     LogPrint("net", "trying connection %s lastseen=%.1fhrs\n",
              pszDest ? pszDest : addrConnect.ToString(),
              pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime) /
                                  3600.0);
 
     // Connect
     SOCKET hSocket;
     bool proxyConnectionFailed = false;
     if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest,
                                       Params().GetDefaultPort(),
                                       nConnectTimeout, &proxyConnectionFailed)
                 : ConnectSocket(addrConnect, hSocket, nConnectTimeout,
                                 &proxyConnectionFailed)) {
         if (!IsSelectableSocket(hSocket)) {
             LogPrintf("Cannot create connection: non-selectable socket created "
                       "(fd >= FD_SETSIZE ?)\n");
             CloseSocket(hSocket);
             return nullptr;
         }
 
         if (pszDest && addrConnect.IsValid()) {
             // It is possible that we already have a connection to the IP/port
             // pszDest resolved to. In that case, drop the connection that was
             // just created, and return the existing CNode instead. Also store
             // the name we used to connect in that CNode, so that future
             // FindNode() calls to that name catch this early.
             LOCK(cs_vNodes);
             CNode *pnode = FindNode((CService)addrConnect);
             if (pnode) {
                 pnode->MaybeSetAddrName(std::string(pszDest));
                 CloseSocket(hSocket);
                 LogPrintf("Failed to open new connection, already connected\n");
                 return nullptr;
             }
         }
 
         addrman.Attempt(addrConnect, fCountFailure);
 
         // Add node
         NodeId id = GetNewNodeId();
         uint64_t nonce =
             GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE)
                 .Write(id)
                 .Finalize();
         CNode *pnode =
             new CNode(id, nLocalServices, GetBestHeight(), hSocket, addrConnect,
                       CalculateKeyedNetGroup(addrConnect), nonce,
                       pszDest ? pszDest : "", false);
         pnode->nServicesExpected =
             ServiceFlags(addrConnect.nServices & nRelevantServices);
         pnode->AddRef();
 
         return pnode;
     } else if (!proxyConnectionFailed) {
         // If connecting to the node failed, and failure is not caused by a
         // problem connecting to the proxy, mark this as an attempt.
         addrman.Attempt(addrConnect, fCountFailure);
     }
 
     return nullptr;
 }
 
 void CConnman::DumpBanlist() {
     // Clean unused entries (if bantime has expired)
     SweepBanned();
 
     if (!BannedSetIsDirty()) {
         return;
     }
 
     int64_t nStart = GetTimeMillis();
 
     CBanDB bandb;
     banmap_t banmap;
     SetBannedSetDirty(false);
     GetBanned(banmap);
     if (!bandb.Write(banmap)) {
         SetBannedSetDirty(true);
     }
 
     LogPrint("net", "Flushed %d banned node ips/subnets to banlist.dat  %dms\n",
              banmap.size(), GetTimeMillis() - nStart);
 }
 
 void CNode::CloseSocketDisconnect() {
     fDisconnect = true;
     LOCK(cs_hSocket);
     if (hSocket != INVALID_SOCKET) {
         LogPrint("net", "disconnecting peer=%d\n", id);
         CloseSocket(hSocket);
     }
 }
 
 void CConnman::ClearBanned() {
     {
         LOCK(cs_setBanned);
         setBanned.clear();
         setBannedIsDirty = true;
     }
 
     // Store banlist to disk.
     DumpBanlist();
     if (clientInterface) {
         clientInterface->BannedListChanged();
     }
 }
 
 bool CConnman::IsBanned(CNetAddr ip) {
     LOCK(cs_setBanned);
 
     bool fResult = false;
     for (banmap_t::iterator it = setBanned.begin(); it != setBanned.end();
          it++) {
         CSubNet subNet = (*it).first;
         CBanEntry banEntry = (*it).second;
 
         if (subNet.Match(ip) && GetTime() < banEntry.nBanUntil) {
             fResult = true;
         }
     }
 
     return fResult;
 }
 
 bool CConnman::IsBanned(CSubNet subnet) {
     LOCK(cs_setBanned);
 
     bool fResult = false;
     banmap_t::iterator i = setBanned.find(subnet);
     if (i != setBanned.end()) {
         CBanEntry banEntry = (*i).second;
         if (GetTime() < banEntry.nBanUntil) {
             fResult = true;
         }
     }
 
     return fResult;
 }
 
 void CConnman::Ban(const CNetAddr &addr, const BanReason &banReason,
                    int64_t bantimeoffset, bool sinceUnixEpoch) {
     CSubNet subNet(addr);
     Ban(subNet, banReason, bantimeoffset, sinceUnixEpoch);
 }
 
 void CConnman::Ban(const CSubNet &subNet, const BanReason &banReason,
                    int64_t bantimeoffset, bool sinceUnixEpoch) {
     CBanEntry banEntry(GetTime());
     banEntry.banReason = banReason;
     if (bantimeoffset <= 0) {
         bantimeoffset = GetArg("-bantime", DEFAULT_MISBEHAVING_BANTIME);
         sinceUnixEpoch = false;
     }
     banEntry.nBanUntil = (sinceUnixEpoch ? 0 : GetTime()) + bantimeoffset;
 
     {
         LOCK(cs_setBanned);
         if (setBanned[subNet].nBanUntil < banEntry.nBanUntil) {
             setBanned[subNet] = banEntry;
             setBannedIsDirty = true;
         } else {
             return;
         }
     }
 
     if (clientInterface) {
         clientInterface->BannedListChanged();
     }
 
     {
         LOCK(cs_vNodes);
         for (CNode *pnode : vNodes) {
             if (subNet.Match((CNetAddr)pnode->addr)) {
                 pnode->fDisconnect = true;
             }
         }
     }
 
     if (banReason == BanReasonManuallyAdded) {
         // Store banlist to disk immediately if user requested ban.
         DumpBanlist();
     }
 }
 
 bool CConnman::Unban(const CNetAddr &addr) {
     CSubNet subNet(addr);
     return Unban(subNet);
 }
 
 bool CConnman::Unban(const CSubNet &subNet) {
     {
         LOCK(cs_setBanned);
         if (!setBanned.erase(subNet)) {
             return false;
         }
         setBannedIsDirty = true;
     }
 
     if (clientInterface) {
         clientInterface->BannedListChanged();
     }
 
     // Store banlist to disk immediately.
     DumpBanlist();
     return true;
 }
 
 void CConnman::GetBanned(banmap_t &banMap) {
     LOCK(cs_setBanned);
     // Create a thread safe copy.
     banMap = setBanned;
 }
 
 void CConnman::SetBanned(const banmap_t &banMap) {
     LOCK(cs_setBanned);
     setBanned = banMap;
     setBannedIsDirty = true;
 }
 
 void CConnman::SweepBanned() {
     int64_t now = GetTime();
 
     LOCK(cs_setBanned);
     banmap_t::iterator it = setBanned.begin();
     while (it != setBanned.end()) {
         CSubNet subNet = (*it).first;
         CBanEntry banEntry = (*it).second;
         if (now > banEntry.nBanUntil) {
             setBanned.erase(it++);
             setBannedIsDirty = true;
             LogPrint("net",
                      "%s: Removed banned node ip/subnet from banlist.dat: %s\n",
                      __func__, subNet.ToString());
         } else {
             ++it;
         }
     }
 }
 
 bool CConnman::BannedSetIsDirty() {
     LOCK(cs_setBanned);
     return setBannedIsDirty;
 }
 
 void CConnman::SetBannedSetDirty(bool dirty) {
     // Reuse setBanned lock for the isDirty flag.
     LOCK(cs_setBanned);
     setBannedIsDirty = dirty;
 }
 
 bool CConnman::IsWhitelistedRange(const CNetAddr &addr) {
     LOCK(cs_vWhitelistedRange);
     for (const CSubNet &subnet : vWhitelistedRange) {
         if (subnet.Match(addr)) {
             return true;
         }
     }
     return false;
 }
 
 void CConnman::AddWhitelistedRange(const CSubNet &subnet) {
     LOCK(cs_vWhitelistedRange);
     vWhitelistedRange.push_back(subnet);
 }
 
 std::string CNode::GetAddrName() const {
     LOCK(cs_addrName);
     return addrName;
 }
 
 void CNode::MaybeSetAddrName(const std::string &addrNameIn) {
     LOCK(cs_addrName);
     if (addrName.empty()) {
         addrName = addrNameIn;
     }
 }
 
 CService CNode::GetAddrLocal() const {
     LOCK(cs_addrLocal);
     return addrLocal;
 }
 
 void CNode::SetAddrLocal(const CService &addrLocalIn) {
     LOCK(cs_addrLocal);
     if (addrLocal.IsValid()) {
         error("Addr local already set for node: %i. Refusing to change from %s "
               "to %s",
               id, addrLocal.ToString(), addrLocalIn.ToString());
     } else {
         addrLocal = addrLocalIn;
     }
 }
 
 #undef X
 #define X(name) stats.name = name
 void CNode::copyStats(CNodeStats &stats) {
     stats.nodeid = this->GetId();
     X(nServices);
     X(addr);
     {
         LOCK(cs_filter);
         X(fRelayTxes);
     }
     X(nLastSend);
     X(nLastRecv);
     X(nTimeConnected);
     X(nTimeOffset);
     stats.addrName = GetAddrName();
     X(nVersion);
     {
         LOCK(cs_SubVer);
         X(cleanSubVer);
     }
     X(fInbound);
     X(fAddnode);
     X(nStartingHeight);
     {
         LOCK(cs_vSend);
         X(mapSendBytesPerMsgCmd);
         X(nSendBytes);
     }
     {
         LOCK(cs_vRecv);
         X(mapRecvBytesPerMsgCmd);
         X(nRecvBytes);
     }
     X(fWhitelisted);
 
     // It is common for nodes with good ping times to suddenly become lagged,
     // due to a new block arriving or other large transfer. Merely reporting
     // pingtime might fool the caller into thinking the node was still
     // responsive, since pingtime does not update until the ping is complete,
     // which might take a while. So, if a ping is taking an unusually long time
     // in flight, the caller can immediately detect that this is happening.
     int64_t nPingUsecWait = 0;
     if ((0 != nPingNonceSent) && (0 != nPingUsecStart)) {
         nPingUsecWait = GetTimeMicros() - nPingUsecStart;
     }
 
     // Raw ping time is in microseconds, but show it to user as whole seconds
     // (Bitcoin users should be well used to small numbers with many decimal
     // places by now :)
     stats.dPingTime = ((double(nPingUsecTime)) / 1e6);
     stats.dMinPing = ((double(nMinPingUsecTime)) / 1e6);
     stats.dPingWait = ((double(nPingUsecWait)) / 1e6);
 
     // Leave string empty if addrLocal invalid (not filled in yet)
     CService addrLocalUnlocked = GetAddrLocal();
     stats.addrLocal =
         addrLocalUnlocked.IsValid() ? addrLocalUnlocked.ToString() : "";
 }
 #undef X
 
 bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes,
                             bool &complete) {
     complete = false;
     int64_t nTimeMicros = GetTimeMicros();
     LOCK(cs_vRecv);
     nLastRecv = nTimeMicros / 1000000;
     nRecvBytes += nBytes;
     while (nBytes > 0) {
         // Get current incomplete message, or create a new one.
         if (vRecvMsg.empty() || vRecvMsg.back().complete()) {
             vRecvMsg.push_back(CNetMessage(GetMagic(Params()), SER_NETWORK,
                                            INIT_PROTO_VERSION));
         }
 
         CNetMessage &msg = vRecvMsg.back();
 
         // Absorb network data.
         int handled;
         if (!msg.in_data) {
             handled = msg.readHeader(pch, nBytes);
         } else {
             handled = msg.readData(pch, nBytes);
         }
 
         if (handled < 0) {
             return false;
         }
 
         if (msg.in_data && msg.hdr.nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) {
             LogPrint("net", "Oversized message from peer=%i, disconnecting\n",
                      GetId());
             return false;
         }
 
         pch += handled;
         nBytes -= handled;
 
         if (msg.complete()) {
             // Store received bytes per message command to prevent a memory DOS,
             // only allow valid commands.
             mapMsgCmdSize::iterator i =
                 mapRecvBytesPerMsgCmd.find(msg.hdr.pchCommand);
             if (i == mapRecvBytesPerMsgCmd.end()) {
                 i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER);
             }
 
             assert(i != mapRecvBytesPerMsgCmd.end());
             i->second += msg.hdr.nMessageSize + CMessageHeader::HEADER_SIZE;
 
             msg.nTime = nTimeMicros;
             complete = true;
         }
     }
 
     return true;
 }
 
 void CNode::SetSendVersion(int nVersionIn) {
     // Send version may only be changed in the version message, and only one
     // version message is allowed per session. We can therefore treat this value
     // as const and even atomic as long as it's only used once a version message
     // has been successfully processed. Any attempt to set this twice is an
     // error.
     if (nSendVersion != 0) {
         error("Send version already set for node: %i. Refusing to change from "
               "%i to %i",
               id, nSendVersion, nVersionIn);
     } else {
         nSendVersion = nVersionIn;
     }
 }
 
 int CNode::GetSendVersion() const {
     // The send version should always be explicitly set to INIT_PROTO_VERSION
     // rather than using this value until SetSendVersion has been called.
     if (nSendVersion == 0) {
         error("Requesting unset send version for node: %i. Using %i", id,
               INIT_PROTO_VERSION);
         return INIT_PROTO_VERSION;
     }
     return nSendVersion;
 }
 
 int CNetMessage::readHeader(const char *pch, unsigned int nBytes) {
     // copy data to temporary parsing buffer
     unsigned int nRemaining = 24 - nHdrPos;
     unsigned int nCopy = std::min(nRemaining, nBytes);
 
     memcpy(&hdrbuf[nHdrPos], pch, nCopy);
     nHdrPos += nCopy;
 
     // if header incomplete, exit
     if (nHdrPos < 24) {
         return nCopy;
     }
 
     // deserialize to CMessageHeader
     try {
         hdrbuf >> hdr;
     } catch (const std::exception &) {
         return -1;
     }
 
     // reject messages larger than MAX_SIZE
     if (hdr.nMessageSize > MAX_SIZE) {
         return -1;
     }
 
     // switch state to reading message data
     in_data = true;
 
     return nCopy;
 }
 
 int CNetMessage::readData(const char *pch, unsigned int nBytes) {
     unsigned int nRemaining = hdr.nMessageSize - nDataPos;
     unsigned int nCopy = std::min(nRemaining, nBytes);
 
     if (vRecv.size() < nDataPos + nCopy) {
         // Allocate up to 256 KiB ahead, but never more than the total message
         // size.
         vRecv.resize(std::min(hdr.nMessageSize, nDataPos + nCopy + 256 * 1024));
     }
 
-    hasher.Write((const unsigned char *)pch, nCopy);
+    hasher.Write((const uint8_t *)pch, nCopy);
     memcpy(&vRecv[nDataPos], pch, nCopy);
     nDataPos += nCopy;
 
     return nCopy;
 }
 
 const uint256 &CNetMessage::GetMessageHash() const {
     assert(complete());
     if (data_hash.IsNull()) {
         hasher.Finalize(data_hash.begin());
     }
     return data_hash;
 }
 
 // requires LOCK(cs_vSend)
 size_t CConnman::SocketSendData(CNode *pnode) const {
     AssertLockHeld(pnode->cs_vSend);
     size_t nSentSize = 0;
     size_t nMsgCount = 0;
 
     for (const auto &data : pnode->vSendMsg) {
         assert(data.size() > pnode->nSendOffset);
         int nBytes = 0;
 
         {
             LOCK(pnode->cs_hSocket);
             if (pnode->hSocket == INVALID_SOCKET) {
                 break;
             }
 
             nBytes = send(
                 pnode->hSocket, reinterpret_cast<const char *>(data.data()) +
                                     pnode->nSendOffset,
                 data.size() - pnode->nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT);
         }
 
         if (nBytes == 0) {
             // couldn't send anything at all
             break;
         }
 
         if (nBytes < 0) {
             // error
             int nErr = WSAGetLastError();
             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE &&
                 nErr != WSAEINTR && nErr != WSAEINPROGRESS) {
                 LogPrintf("socket send error %s\n", NetworkErrorString(nErr));
                 pnode->CloseSocketDisconnect();
             }
 
             break;
         }
 
         assert(nBytes > 0);
         pnode->nLastSend = GetSystemTimeInSeconds();
         pnode->nSendBytes += nBytes;
         pnode->nSendOffset += nBytes;
         nSentSize += nBytes;
         if (pnode->nSendOffset != data.size()) {
             // could not send full message; stop sending more
             break;
         }
 
         pnode->nSendOffset = 0;
         pnode->nSendSize -= data.size();
         pnode->fPauseSend = pnode->nSendSize > nSendBufferMaxSize;
         nMsgCount++;
     }
 
     pnode->vSendMsg.erase(pnode->vSendMsg.begin(),
                           pnode->vSendMsg.begin() + nMsgCount);
 
     if (pnode->vSendMsg.empty()) {
         assert(pnode->nSendOffset == 0);
         assert(pnode->nSendSize == 0);
     }
 
     return nSentSize;
 }
 
 struct NodeEvictionCandidate {
     NodeId id;
     int64_t nTimeConnected;
     int64_t nMinPingUsecTime;
     int64_t nLastBlockTime;
     int64_t nLastTXTime;
     bool fRelevantServices;
     bool fRelayTxes;
     bool fBloomFilter;
     CAddress addr;
     uint64_t nKeyedNetGroup;
 };
 
 static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a,
                                           const NodeEvictionCandidate &b) {
     return a.nMinPingUsecTime > b.nMinPingUsecTime;
 }
 
 static bool ReverseCompareNodeTimeConnected(const NodeEvictionCandidate &a,
                                             const NodeEvictionCandidate &b) {
     return a.nTimeConnected > b.nTimeConnected;
 }
 
 static bool CompareNetGroupKeyed(const NodeEvictionCandidate &a,
                                  const NodeEvictionCandidate &b) {
     return a.nKeyedNetGroup < b.nKeyedNetGroup;
 }
 
 static bool CompareNodeBlockTime(const NodeEvictionCandidate &a,
                                  const NodeEvictionCandidate &b) {
     // There is a fall-through here because it is common for a node to have many
     // peers which have not yet relayed a block.
     if (a.nLastBlockTime != b.nLastBlockTime) {
         return a.nLastBlockTime < b.nLastBlockTime;
     }
 
     if (a.fRelevantServices != b.fRelevantServices) {
         return b.fRelevantServices;
     }
 
     return a.nTimeConnected > b.nTimeConnected;
 }
 
 static bool CompareNodeTXTime(const NodeEvictionCandidate &a,
                               const NodeEvictionCandidate &b) {
     // There is a fall-through here because it is common for a node to have more
     // than a few peers that have not yet relayed txn.
     if (a.nLastTXTime != b.nLastTXTime) {
         return a.nLastTXTime < b.nLastTXTime;
     }
 
     if (a.fRelayTxes != b.fRelayTxes) {
         return b.fRelayTxes;
     }
 
     if (a.fBloomFilter != b.fBloomFilter) {
         return a.fBloomFilter;
     }
 
     return a.nTimeConnected > b.nTimeConnected;
 }
 
 /**
  * Try to find a connection to evict when the node is full. Extreme care must be
  * taken to avoid opening the node to attacker triggered network partitioning.
  * The strategy used here is to protect a small number of peers for each of
  * several distinct characteristics which are difficult to forge. In order to
  * partition a node the attacker must be simultaneously better at all of them
  * than honest peers.
  */
 bool CConnman::AttemptToEvictConnection() {
     std::vector<NodeEvictionCandidate> vEvictionCandidates;
     {
         LOCK(cs_vNodes);
 
         for (CNode *node : vNodes) {
             if (node->fWhitelisted || !node->fInbound || node->fDisconnect) {
                 continue;
             }
             NodeEvictionCandidate candidate = {
                 node->id,
                 node->nTimeConnected,
                 node->nMinPingUsecTime,
                 node->nLastBlockTime,
                 node->nLastTXTime,
                 (node->nServices & nRelevantServices) == nRelevantServices,
                 node->fRelayTxes,
                 node->pfilter != nullptr,
                 node->addr,
                 node->nKeyedNetGroup};
             vEvictionCandidates.push_back(candidate);
         }
     }
 
     if (vEvictionCandidates.empty()) {
         return false;
     }
 
     // Protect connections with certain characteristics
 
     // Deterministically select 4 peers to protect by netgroup. An attacker
     // cannot predict which netgroups will be protected.
     std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(),
               CompareNetGroupKeyed);
     vEvictionCandidates.erase(
         vEvictionCandidates.end() -
             std::min(4, static_cast<int>(vEvictionCandidates.size())),
         vEvictionCandidates.end());
 
     if (vEvictionCandidates.empty()) {
         return false;
     }
 
     // Protect the 8 nodes with the lowest minimum ping time. An attacker cannot
     // manipulate this metric without physically moving nodes closer to the
     // target.
     std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(),
               ReverseCompareNodeMinPingTime);
     vEvictionCandidates.erase(
         vEvictionCandidates.end() -
             std::min(8, static_cast<int>(vEvictionCandidates.size())),
         vEvictionCandidates.end());
 
     if (vEvictionCandidates.empty()) {
         return false;
     }
 
     // Protect 4 nodes that most recently sent us transactions. An attacker
     // cannot manipulate this metric without performing useful work.
     std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(),
               CompareNodeTXTime);
     vEvictionCandidates.erase(
         vEvictionCandidates.end() -
             std::min(4, static_cast<int>(vEvictionCandidates.size())),
         vEvictionCandidates.end());
 
     if (vEvictionCandidates.empty()) {
         return false;
     }
 
     // Protect 4 nodes that most recently sent us blocks. An attacker cannot
     // manipulate this metric without performing useful work.
     std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(),
               CompareNodeBlockTime);
     vEvictionCandidates.erase(
         vEvictionCandidates.end() -
             std::min(4, static_cast<int>(vEvictionCandidates.size())),
         vEvictionCandidates.end());
 
     if (vEvictionCandidates.empty()) {
         return false;
     }
 
     // Protect the half of the remaining nodes which have been connected the
     // longest. This replicates the non-eviction implicit behavior, and
     // precludes attacks that start later.
     std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(),
               ReverseCompareNodeTimeConnected);
     vEvictionCandidates.erase(
         vEvictionCandidates.end() -
             static_cast<int>(vEvictionCandidates.size() / 2),
         vEvictionCandidates.end());
 
     if (vEvictionCandidates.empty()) {
         return false;
     }
 
     // Identify the network group with the most connections and youngest member.
     // (vEvictionCandidates is already sorted by reverse connect time)
     uint64_t naMostConnections;
     unsigned int nMostConnections = 0;
     int64_t nMostConnectionsTime = 0;
     std::map<uint64_t, std::vector<NodeEvictionCandidate>> mapNetGroupNodes;
     for (const NodeEvictionCandidate &node : vEvictionCandidates) {
         mapNetGroupNodes[node.nKeyedNetGroup].push_back(node);
         int64_t grouptime =
             mapNetGroupNodes[node.nKeyedNetGroup][0].nTimeConnected;
         size_t groupsize = mapNetGroupNodes[node.nKeyedNetGroup].size();
 
         if (groupsize > nMostConnections ||
             (groupsize == nMostConnections &&
              grouptime > nMostConnectionsTime)) {
             nMostConnections = groupsize;
             nMostConnectionsTime = grouptime;
             naMostConnections = node.nKeyedNetGroup;
         }
     }
 
     // Reduce to the network group with the most connections
     vEvictionCandidates = std::move(mapNetGroupNodes[naMostConnections]);
 
     // Disconnect from the network group with the most connections
     NodeId evicted = vEvictionCandidates.front().id;
     LOCK(cs_vNodes);
     for (std::vector<CNode *>::const_iterator it(vNodes.begin());
          it != vNodes.end(); ++it) {
         if ((*it)->GetId() == evicted) {
             (*it)->fDisconnect = true;
             return true;
         }
     }
     return false;
 }
 
 void CConnman::AcceptConnection(const ListenSocket &hListenSocket) {
     struct sockaddr_storage sockaddr;
     socklen_t len = sizeof(sockaddr);
     SOCKET hSocket =
         accept(hListenSocket.socket, (struct sockaddr *)&sockaddr, &len);
     CAddress addr;
     int nInbound = 0;
     int nMaxInbound = nMaxConnections - (nMaxOutbound + nMaxFeeler);
 
     if (hSocket != INVALID_SOCKET) {
         if (!addr.SetSockAddr((const struct sockaddr *)&sockaddr)) {
             LogPrintf("Warning: Unknown socket family\n");
         }
     }
 
     bool whitelisted = hListenSocket.whitelisted || IsWhitelistedRange(addr);
     {
         LOCK(cs_vNodes);
         for (CNode *pnode : vNodes) {
             if (pnode->fInbound) {
                 nInbound++;
             }
         }
     }
 
     if (hSocket == INVALID_SOCKET) {
         int nErr = WSAGetLastError();
         if (nErr != WSAEWOULDBLOCK) {
             LogPrintf("socket error accept failed: %s\n",
                       NetworkErrorString(nErr));
         }
         return;
     }
 
     if (!fNetworkActive) {
         LogPrintf("connection from %s dropped: not accepting new connections\n",
                   addr.ToString());
         CloseSocket(hSocket);
         return;
     }
 
     if (!IsSelectableSocket(hSocket)) {
         LogPrintf("connection from %s dropped: non-selectable socket\n",
                   addr.ToString());
         CloseSocket(hSocket);
         return;
     }
 
     // According to the internet TCP_NODELAY is not carried into accepted
     // sockets on all platforms.  Set it again here just to be sure.
     int set = 1;
 #ifdef WIN32
     setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (const char *)&set,
                sizeof(int));
 #else
     setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (void *)&set, sizeof(int));
 #endif
 
     if (IsBanned(addr) && !whitelisted) {
         LogPrintf("connection from %s dropped (banned)\n", addr.ToString());
         CloseSocket(hSocket);
         return;
     }
 
     if (nInbound >= nMaxInbound) {
         if (!AttemptToEvictConnection()) {
             // No connection to evict, disconnect the new connection
             LogPrint("net", "failed to find an eviction candidate - connection "
                             "dropped (full)\n");
             CloseSocket(hSocket);
             return;
         }
     }
 
     NodeId id = GetNewNodeId();
     uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE)
                          .Write(id)
                          .Finalize();
 
     CNode *pnode = new CNode(id, nLocalServices, GetBestHeight(), hSocket, addr,
                              CalculateKeyedNetGroup(addr), nonce, "", true);
     pnode->AddRef();
     pnode->fWhitelisted = whitelisted;
 
     // FIXME: Pass config down rather than use GetConfig
     GetNodeSignals().InitializeNode(GetConfig(), pnode, *this);
 
     LogPrint("net", "connection from %s accepted\n", addr.ToString());
 
     {
         LOCK(cs_vNodes);
         vNodes.push_back(pnode);
     }
 }
 
 void CConnman::ThreadSocketHandler() {
     unsigned int nPrevNodeCount = 0;
     while (!interruptNet) {
         //
         // Disconnect nodes
         //
         {
             LOCK(cs_vNodes);
             // Disconnect unused nodes
             std::vector<CNode *> vNodesCopy = vNodes;
             for (CNode *pnode : vNodesCopy) {
                 if (pnode->fDisconnect) {
                     // remove from vNodes
                     vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode),
                                  vNodes.end());
 
                     // release outbound grant (if any)
                     pnode->grantOutbound.Release();
 
                     // close socket and cleanup
                     pnode->CloseSocketDisconnect();
 
                     // hold in disconnected pool until all refs are released
                     pnode->Release();
                     vNodesDisconnected.push_back(pnode);
                 }
             }
         }
         {
             // Delete disconnected nodes
             std::list<CNode *> vNodesDisconnectedCopy = vNodesDisconnected;
             for (CNode *pnode : vNodesDisconnectedCopy) {
                 // wait until threads are done using it
                 if (pnode->GetRefCount() <= 0) {
                     bool fDelete = false;
                     {
                         TRY_LOCK(pnode->cs_inventory, lockInv);
                         if (lockInv) {
                             TRY_LOCK(pnode->cs_vSend, lockSend);
                             if (lockSend) {
                                 fDelete = true;
                             }
                         }
                     }
                     if (fDelete) {
                         vNodesDisconnected.remove(pnode);
                         DeleteNode(pnode);
                     }
                 }
             }
         }
         size_t vNodesSize;
         {
             LOCK(cs_vNodes);
             vNodesSize = vNodes.size();
         }
         if (vNodesSize != nPrevNodeCount) {
             nPrevNodeCount = vNodesSize;
             if (clientInterface) {
                 clientInterface->NotifyNumConnectionsChanged(nPrevNodeCount);
             }
         }
 
         //
         // Find which sockets have data to receive
         //
         struct timeval timeout;
         timeout.tv_sec = 0;
         // Frequency to poll pnode->vSend
         timeout.tv_usec = 50000;
 
         fd_set fdsetRecv;
         fd_set fdsetSend;
         fd_set fdsetError;
         FD_ZERO(&fdsetRecv);
         FD_ZERO(&fdsetSend);
         FD_ZERO(&fdsetError);
         SOCKET hSocketMax = 0;
         bool have_fds = false;
 
         for (const ListenSocket &hListenSocket : vhListenSocket) {
             FD_SET(hListenSocket.socket, &fdsetRecv);
             hSocketMax = std::max(hSocketMax, hListenSocket.socket);
             have_fds = true;
         }
 
         {
             LOCK(cs_vNodes);
             for (CNode *pnode : vNodes) {
                 // Implement the following logic:
                 // * If there is data to send, select() for sending data. As
                 // this only happens when optimistic write failed, we choose to
                 // first drain the write buffer in this case before receiving
                 // more. This avoids needlessly queueing received data, if the
                 // remote peer is not themselves receiving data. This means
                 // properly utilizing TCP flow control signalling.
                 // * Otherwise, if there is space left in the receive buffer,
                 // select() for receiving data.
                 // * Hand off all complete messages to the processor, to be
                 // handled without blocking here.
 
                 bool select_recv = !pnode->fPauseRecv;
                 bool select_send;
                 {
                     LOCK(pnode->cs_vSend);
                     select_send = !pnode->vSendMsg.empty();
                 }
 
                 LOCK(pnode->cs_hSocket);
                 if (pnode->hSocket == INVALID_SOCKET) {
                     continue;
                 }
 
                 FD_SET(pnode->hSocket, &fdsetError);
                 hSocketMax = std::max(hSocketMax, pnode->hSocket);
                 have_fds = true;
 
                 if (select_send) {
                     FD_SET(pnode->hSocket, &fdsetSend);
                     continue;
                 }
                 if (select_recv) {
                     FD_SET(pnode->hSocket, &fdsetRecv);
                 }
             }
         }
 
         int nSelect = select(have_fds ? hSocketMax + 1 : 0, &fdsetRecv,
                              &fdsetSend, &fdsetError, &timeout);
         if (interruptNet) {
             return;
         }
 
         if (nSelect == SOCKET_ERROR) {
             if (have_fds) {
                 int nErr = WSAGetLastError();
                 LogPrintf("socket select error %s\n", NetworkErrorString(nErr));
                 for (unsigned int i = 0; i <= hSocketMax; i++) {
                     FD_SET(i, &fdsetRecv);
                 }
             }
             FD_ZERO(&fdsetSend);
             FD_ZERO(&fdsetError);
             if (!interruptNet.sleep_for(
                     std::chrono::milliseconds(timeout.tv_usec / 1000))) {
                 return;
             }
         }
 
         //
         // Accept new connections
         //
         for (const ListenSocket &hListenSocket : vhListenSocket) {
             if (hListenSocket.socket != INVALID_SOCKET &&
                 FD_ISSET(hListenSocket.socket, &fdsetRecv)) {
                 AcceptConnection(hListenSocket);
             }
         }
 
         //
         // Service each socket
         //
         std::vector<CNode *> vNodesCopy;
         {
             LOCK(cs_vNodes);
             vNodesCopy = vNodes;
             for (CNode *pnode : vNodesCopy) {
                 pnode->AddRef();
             }
         }
         for (CNode *pnode : vNodesCopy) {
             if (interruptNet) {
                 return;
             }
 
             //
             // Receive
             //
             bool recvSet = false;
             bool sendSet = false;
             bool errorSet = false;
             {
                 LOCK(pnode->cs_hSocket);
                 if (pnode->hSocket == INVALID_SOCKET) {
                     continue;
                 }
                 recvSet = FD_ISSET(pnode->hSocket, &fdsetRecv);
                 sendSet = FD_ISSET(pnode->hSocket, &fdsetSend);
                 errorSet = FD_ISSET(pnode->hSocket, &fdsetError);
             }
             if (recvSet || errorSet) {
                 // typical socket buffer is 8K-64K
                 char pchBuf[0x10000];
                 int nBytes = 0;
                 {
                     LOCK(pnode->cs_hSocket);
                     if (pnode->hSocket == INVALID_SOCKET) {
                         continue;
                     }
                     nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf),
                                   MSG_DONTWAIT);
                 }
                 if (nBytes > 0) {
                     bool notify = false;
                     if (!pnode->ReceiveMsgBytes(pchBuf, nBytes, notify)) {
                         pnode->CloseSocketDisconnect();
                     }
                     RecordBytesRecv(nBytes);
                     if (notify) {
                         size_t nSizeAdded = 0;
                         auto it(pnode->vRecvMsg.begin());
                         for (; it != pnode->vRecvMsg.end(); ++it) {
                             if (!it->complete()) {
                                 break;
                             }
                             nSizeAdded +=
                                 it->vRecv.size() + CMessageHeader::HEADER_SIZE;
                         }
                         {
                             LOCK(pnode->cs_vProcessMsg);
                             pnode->vProcessMsg.splice(
                                 pnode->vProcessMsg.end(), pnode->vRecvMsg,
                                 pnode->vRecvMsg.begin(), it);
                             pnode->nProcessQueueSize += nSizeAdded;
                             pnode->fPauseRecv =
                                 pnode->nProcessQueueSize > nReceiveFloodSize;
                         }
                         WakeMessageHandler();
                     }
                 } else if (nBytes == 0) {
                     // socket closed gracefully
                     if (!pnode->fDisconnect) {
                         LogPrint("net", "socket closed\n");
                     }
                     pnode->CloseSocketDisconnect();
                 } else if (nBytes < 0) {
                     // error
                     int nErr = WSAGetLastError();
                     if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE &&
                         nErr != WSAEINTR && nErr != WSAEINPROGRESS) {
                         if (!pnode->fDisconnect) {
                             LogPrintf("socket recv error %s\n",
                                       NetworkErrorString(nErr));
                         }
                         pnode->CloseSocketDisconnect();
                     }
                 }
             }
 
             //
             // Send
             //
             if (sendSet) {
                 LOCK(pnode->cs_vSend);
                 size_t nBytes = SocketSendData(pnode);
                 if (nBytes) {
                     RecordBytesSent(nBytes);
                 }
             }
 
             //
             // Inactivity checking
             //
             int64_t nTime = GetSystemTimeInSeconds();
             if (nTime - pnode->nTimeConnected > 60) {
                 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0) {
                     LogPrint("net", "socket no message in first 60 seconds, %d "
                                     "%d from %d\n",
                              pnode->nLastRecv != 0, pnode->nLastSend != 0,
                              pnode->id);
                     pnode->fDisconnect = true;
                 } else if (nTime - pnode->nLastSend > TIMEOUT_INTERVAL) {
                     LogPrintf("socket sending timeout: %is\n",
                               nTime - pnode->nLastSend);
                     pnode->fDisconnect = true;
                 } else if (nTime - pnode->nLastRecv >
                            (pnode->nVersion > BIP0031_VERSION ? TIMEOUT_INTERVAL
                                                               : 90 * 60)) {
                     LogPrintf("socket receive timeout: %is\n",
                               nTime - pnode->nLastRecv);
                     pnode->fDisconnect = true;
                 } else if (pnode->nPingNonceSent &&
                            pnode->nPingUsecStart + TIMEOUT_INTERVAL * 1000000 <
                                GetTimeMicros()) {
                     LogPrintf("ping timeout: %fs\n",
                               0.000001 *
                                   (GetTimeMicros() - pnode->nPingUsecStart));
                     pnode->fDisconnect = true;
                 } else if (!pnode->fSuccessfullyConnected) {
                     LogPrintf("version handshake timeout from %d\n", pnode->id);
                     pnode->fDisconnect = true;
                 }
             }
         }
         {
             LOCK(cs_vNodes);
             for (CNode *pnode : vNodesCopy) {
                 pnode->Release();
             }
         }
     }
 }
 
 void CConnman::WakeMessageHandler() {
     {
         std::lock_guard<std::mutex> lock(mutexMsgProc);
         fMsgProcWake = true;
     }
     condMsgProc.notify_one();
 }
 
 #ifdef USE_UPNP
 void ThreadMapPort() {
     std::string port = strprintf("%u", GetListenPort());
     const char *multicastif = 0;
     const char *minissdpdpath = 0;
     struct UPNPDev *devlist = 0;
     char lanaddr[64];
 
 #ifndef UPNPDISCOVER_SUCCESS
     /* miniupnpc 1.5 */
     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
 #elif MINIUPNPC_API_VERSION < 14
     /* miniupnpc 1.6 */
     int error = 0;
     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
 #else
     /* miniupnpc 1.9.20150730 */
     int error = 0;
     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error);
 #endif
 
     struct UPNPUrls urls;
     struct IGDdatas data;
     int r;
 
     r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
     if (r == 1) {
         if (fDiscover) {
             char externalIPAddress[40];
             r = UPNP_GetExternalIPAddress(
                 urls.controlURL, data.first.servicetype, externalIPAddress);
             if (r != UPNPCOMMAND_SUCCESS) {
                 LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r);
             } else {
                 if (externalIPAddress[0]) {
                     CNetAddr resolved;
                     if (LookupHost(externalIPAddress, resolved, false)) {
                         LogPrintf("UPnP: ExternalIPAddress = %s\n",
                                   resolved.ToString().c_str());
                         AddLocal(resolved, LOCAL_UPNP);
                     }
                 } else {
                     LogPrintf("UPnP: GetExternalIPAddress failed.\n");
                 }
             }
         }
 
         std::string strDesc = "Bitcoin " + FormatFullVersion();
 
         try {
             while (true) {
 #ifndef UPNPDISCOVER_SUCCESS
                 /* miniupnpc 1.5 */
                 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
                                         port.c_str(), port.c_str(), lanaddr,
                                         strDesc.c_str(), "TCP", 0);
 #else
                 /* miniupnpc 1.6 */
                 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
                                         port.c_str(), port.c_str(), lanaddr,
                                         strDesc.c_str(), "TCP", 0, "0");
 #endif
 
                 if (r != UPNPCOMMAND_SUCCESS) {
                     LogPrintf(
                         "AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
                         port, port, lanaddr, r, strupnperror(r));
                 } else {
                     LogPrintf("UPnP Port Mapping successful.\n");
                 }
 
                 // Refresh every 20 minutes
                 MilliSleep(20 * 60 * 1000);
             }
         } catch (const boost::thread_interrupted &) {
             r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype,
                                        port.c_str(), "TCP", 0);
             LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r);
             freeUPNPDevlist(devlist);
             devlist = 0;
             FreeUPNPUrls(&urls);
             throw;
         }
     } else {
         LogPrintf("No valid UPnP IGDs found\n");
         freeUPNPDevlist(devlist);
         devlist = 0;
         if (r != 0) {
             FreeUPNPUrls(&urls);
         }
     }
 }
 
 void MapPort(bool fUseUPnP) {
     static boost::thread *upnp_thread = nullptr;
 
     if (fUseUPnP) {
         if (upnp_thread) {
             upnp_thread->interrupt();
             upnp_thread->join();
             delete upnp_thread;
         }
         upnp_thread = new boost::thread(
             boost::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort));
     } else if (upnp_thread) {
         upnp_thread->interrupt();
         upnp_thread->join();
         delete upnp_thread;
         upnp_thread = nullptr;
     }
 }
 
 #else
 void MapPort(bool) {
     // Intentionally left blank.
 }
 #endif
 
 static std::string GetDNSHost(const CDNSSeedData &data,
                               ServiceFlags *requiredServiceBits) {
     // use default host for non-filter-capable seeds or if we use the default
     // service bits (NODE_NETWORK)
     if (!data.supportsServiceBitsFiltering ||
         *requiredServiceBits == NODE_NETWORK) {
         *requiredServiceBits = NODE_NETWORK;
         return data.host;
     }
 
     // See chainparams.cpp, most dnsseeds only support one or two possible
     // servicebits hostnames
     return strprintf("x%x.%s", *requiredServiceBits, data.host);
 }
 
 void CConnman::ThreadDNSAddressSeed() {
     // goal: only query DNS seeds if address need is acute.
     // Avoiding DNS seeds when we don't need them improves user privacy by
     // creating fewer identifying DNS requests, reduces trust by giving seeds
     // less influence on the network topology, and reduces traffic to the seeds.
     if ((addrman.size() > 0) &&
         (!GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED))) {
         if (!interruptNet.sleep_for(std::chrono::seconds(11))) {
             return;
         }
 
         LOCK(cs_vNodes);
         int nRelevant = 0;
         for (auto pnode : vNodes) {
             nRelevant +=
                 pnode->fSuccessfullyConnected &&
                 ((pnode->nServices & nRelevantServices) == nRelevantServices);
         }
         if (nRelevant >= 2) {
             LogPrintf("P2P peers available. Skipped DNS seeding.\n");
             return;
         }
     }
 
     const std::vector<CDNSSeedData> &vSeeds = Params().DNSSeeds();
     int found = 0;
 
     LogPrintf("Loading addresses from DNS seeds (could take a while)\n");
 
     for (const CDNSSeedData &seed : vSeeds) {
         if (HaveNameProxy()) {
             AddOneShot(seed.host);
         } else {
             std::vector<CNetAddr> vIPs;
             std::vector<CAddress> vAdd;
             ServiceFlags requiredServiceBits = nRelevantServices;
             if (LookupHost(GetDNSHost(seed, &requiredServiceBits).c_str(), vIPs,
                            0, true)) {
                 for (const CNetAddr &ip : vIPs) {
                     int nOneDay = 24 * 3600;
                     CAddress addr =
                         CAddress(CService(ip, Params().GetDefaultPort()),
                                  requiredServiceBits);
                     // Use a random age between 3 and 7 days old.
                     addr.nTime = GetTime() - 3 * nOneDay - GetRand(4 * nOneDay);
                     vAdd.push_back(addr);
                     found++;
                 }
             }
             // TODO: The seed name resolve may fail, yielding an IP of [::],
             // which results in addrman assigning the same source to results
             // from different seeds. This should switch to a hard-coded stable
             // dummy IP for each seed name, so that the resolve is not required
             // at all.
             if (!vIPs.empty()) {
                 CService seedSource;
                 Lookup(seed.name.c_str(), seedSource, 0, true);
                 addrman.Add(vAdd, seedSource);
             }
         }
     }
 
     LogPrintf("%d addresses found from DNS seeds\n", found);
 }
 
 void CConnman::DumpAddresses() {
     int64_t nStart = GetTimeMillis();
 
     CAddrDB adb;
     adb.Write(addrman);
 
     LogPrint("net", "Flushed %d addresses to peers.dat  %dms\n", addrman.size(),
              GetTimeMillis() - nStart);
 }
 
 void CConnman::DumpData() {
     DumpAddresses();
     DumpBanlist();
 }
 
 void CConnman::ProcessOneShot() {
     std::string strDest;
     {
         LOCK(cs_vOneShots);
         if (vOneShots.empty()) {
             return;
         }
         strDest = vOneShots.front();
         vOneShots.pop_front();
     }
     CAddress addr;
     CSemaphoreGrant grant(*semOutbound, true);
     if (grant) {
         if (!OpenNetworkConnection(addr, false, &grant, strDest.c_str(),
                                    true)) {
             AddOneShot(strDest);
         }
     }
 }
 
 void CConnman::ThreadOpenConnections() {
     // Connect to specific addresses
     if (mapMultiArgs.count("-connect") &&
         mapMultiArgs.at("-connect").size() > 0) {
         for (int64_t nLoop = 0;; nLoop++) {
             ProcessOneShot();
             for (const std::string &strAddr : mapMultiArgs.at("-connect")) {
                 CAddress addr(CService(), NODE_NONE);
                 OpenNetworkConnection(addr, false, nullptr, strAddr.c_str());
                 for (int i = 0; i < 10 && i < nLoop; i++) {
                     if (!interruptNet.sleep_for(
                             std::chrono::milliseconds(500))) {
                         return;
                     }
                 }
             }
             if (!interruptNet.sleep_for(std::chrono::milliseconds(500))) {
                 return;
             }
         }
     }
 
     // Initiate network connections
     int64_t nStart = GetTime();
 
     // Minimum time before next feeler connection (in microseconds).
     int64_t nNextFeeler =
         PoissonNextSend(nStart * 1000 * 1000, FEELER_INTERVAL);
     while (!interruptNet) {
         ProcessOneShot();
 
         if (!interruptNet.sleep_for(std::chrono::milliseconds(500))) {
             return;
         }
 
         CSemaphoreGrant grant(*semOutbound);
         if (interruptNet) {
             return;
         }
 
         // Add seed nodes if DNS seeds are all down (an infrastructure attack?).
         if (addrman.size() == 0 && (GetTime() - nStart > 60)) {
             static bool done = false;
             if (!done) {
                 LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be "
                           "available.\n");
                 CNetAddr local;
                 LookupHost("127.0.0.1", local, false);
                 addrman.Add(convertSeed6(Params().FixedSeeds()), local);
                 done = true;
             }
         }
 
         //
         // Choose an address to connect to based on most recently seen
         //
         CAddress addrConnect;
 
         // Only connect out to one peer per network group (/16 for IPv4). Do
         // this here so we don't have to critsect vNodes inside mapAddresses
         // critsect.
         int nOutbound = 0;
-        std::set<std::vector<unsigned char>> setConnected;
+        std::set<std::vector<uint8_t>> setConnected;
         {
             LOCK(cs_vNodes);
             for (CNode *pnode : vNodes) {
                 if (!pnode->fInbound && !pnode->fAddnode) {
                     // Netgroups for inbound and addnode peers are not excluded
                     // because our goal here is to not use multiple of our
                     // limited outbound slots on a single netgroup but inbound
                     // and addnode peers do not use our outbound slots. Inbound
                     // peers also have the added issue that they're attacker
                     // controlled and could be used to prevent us from
                     // connecting to particular hosts if we used them here.
                     setConnected.insert(pnode->addr.GetGroup());
                     nOutbound++;
                 }
             }
         }
 
         // Feeler Connections
         //
         // Design goals:
         //  * Increase the number of connectable addresses in the tried table.
         //
         // Method:
         //  * Choose a random address from new and attempt to connect to it if
         //  we can connect successfully it is added to tried.
         //  * Start attempting feeler connections only after node finishes
         //  making outbound connections.
         //  * Only make a feeler connection once every few minutes.
         //
         bool fFeeler = false;
         if (nOutbound >= nMaxOutbound) {
             // The current time right now (in microseconds).
             int64_t nTime = GetTimeMicros();
             if (nTime > nNextFeeler) {
                 nNextFeeler = PoissonNextSend(nTime, FEELER_INTERVAL);
                 fFeeler = true;
             } else {
                 continue;
             }
         }
 
         int64_t nANow = GetAdjustedTime();
         int nTries = 0;
         while (!interruptNet) {
             CAddrInfo addr = addrman.Select(fFeeler);
 
             // if we selected an invalid address, restart
             if (!addr.IsValid() || setConnected.count(addr.GetGroup()) ||
                 IsLocal(addr)) {
                 break;
             }
 
             // If we didn't find an appropriate destination after trying 100
             // addresses fetched from addrman, stop this loop, and let the outer
             // loop run again (which sleeps, adds seed nodes, recalculates
             // already-connected network ranges, ...) before trying new addrman
             // addresses.
             nTries++;
             if (nTries > 100) {
                 break;
             }
 
             if (IsLimited(addr)) {
                 continue;
             }
 
             // only connect to full nodes
             if ((addr.nServices & REQUIRED_SERVICES) != REQUIRED_SERVICES) {
                 continue;
             }
 
             // only consider very recently tried nodes after 30 failed attempts
             if (nANow - addr.nLastTry < 600 && nTries < 30) {
                 continue;
             }
 
             // only consider nodes missing relevant services after 40 failed
             // attempts and only if less than half the outbound are up.
             if ((addr.nServices & nRelevantServices) != nRelevantServices &&
                 (nTries < 40 || nOutbound >= (nMaxOutbound >> 1))) {
                 continue;
             }
 
             // do not allow non-default ports, unless after 50 invalid addresses
             // selected already.
             if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50) {
                 continue;
             }
 
             addrConnect = addr;
             break;
         }
 
         if (addrConnect.IsValid()) {
 
             if (fFeeler) {
                 // Add small amount of random noise before connection to avoid
                 // synchronization.
                 int randsleep = GetRandInt(FEELER_SLEEP_WINDOW * 1000);
                 if (!interruptNet.sleep_for(
                         std::chrono::milliseconds(randsleep))) {
                     return;
                 }
                 LogPrint("net", "Making feeler connection to %s\n",
                          addrConnect.ToString());
             }
 
             OpenNetworkConnection(addrConnect,
                                   (int)setConnected.size() >=
                                       std::min(nMaxConnections - 1, 2),
                                   &grant, nullptr, false, fFeeler);
         }
     }
 }
 
 std::vector<AddedNodeInfo> CConnman::GetAddedNodeInfo() {
     std::vector<AddedNodeInfo> ret;
 
     std::list<std::string> lAddresses(0);
     {
         LOCK(cs_vAddedNodes);
         ret.reserve(vAddedNodes.size());
         for (const std::string &strAddNode : vAddedNodes) {
             lAddresses.push_back(strAddNode);
         }
     }
 
     // Build a map of all already connected addresses (by IP:port and by name)
     // to inbound/outbound and resolved CService
     std::map<CService, bool> mapConnected;
     std::map<std::string, std::pair<bool, CService>> mapConnectedByName;
     {
         LOCK(cs_vNodes);
         for (const CNode *pnode : vNodes) {
             if (pnode->addr.IsValid()) {
                 mapConnected[pnode->addr] = pnode->fInbound;
             }
             std::string addrName = pnode->GetAddrName();
             if (!addrName.empty()) {
                 mapConnectedByName[std::move(addrName)] =
                     std::make_pair(pnode->fInbound,
                                    static_cast<const CService &>(pnode->addr));
             }
         }
     }
 
     for (const std::string &strAddNode : lAddresses) {
         CService service(
             LookupNumeric(strAddNode.c_str(), Params().GetDefaultPort()));
         if (service.IsValid()) {
             // strAddNode is an IP:port
             auto it = mapConnected.find(service);
             if (it != mapConnected.end()) {
                 ret.push_back(
                     AddedNodeInfo{strAddNode, service, true, it->second});
             } else {
                 ret.push_back(
                     AddedNodeInfo{strAddNode, CService(), false, false});
             }
         } else {
             // strAddNode is a name
             auto it = mapConnectedByName.find(strAddNode);
             if (it != mapConnectedByName.end()) {
                 ret.push_back(AddedNodeInfo{strAddNode, it->second.second, true,
                                             it->second.first});
             } else {
                 ret.push_back(
                     AddedNodeInfo{strAddNode, CService(), false, false});
             }
         }
     }
 
     return ret;
 }
 
 void CConnman::ThreadOpenAddedConnections() {
     {
         LOCK(cs_vAddedNodes);
         if (mapMultiArgs.count("-addnode")) {
             vAddedNodes = mapMultiArgs.at("-addnode");
         }
     }
 
     while (true) {
         CSemaphoreGrant grant(*semAddnode);
         std::vector<AddedNodeInfo> vInfo = GetAddedNodeInfo();
         bool tried = false;
         for (const AddedNodeInfo &info : vInfo) {
             if (!info.fConnected) {
                 if (!grant.TryAcquire()) {
                     // If we've used up our semaphore and need a new one, lets
                     // not wait here since while we are waiting the
                     // addednodeinfo state might change.
                     break;
                 }
                 // If strAddedNode is an IP/port, decode it immediately, so
                 // OpenNetworkConnection can detect existing connections to that
                 // IP/port.
                 tried = true;
                 CService service(LookupNumeric(info.strAddedNode.c_str(),
                                                Params().GetDefaultPort()));
                 OpenNetworkConnection(CAddress(service, NODE_NONE), false,
                                       &grant, info.strAddedNode.c_str(), false,
                                       false, true);
                 if (!interruptNet.sleep_for(std::chrono::milliseconds(500))) {
                     return;
                 }
             }
         }
         // Retry every 60 seconds if a connection was attempted, otherwise two
         // seconds.
         if (!interruptNet.sleep_for(std::chrono::seconds(tried ? 60 : 2))) {
             return;
         }
     }
 }
 
 // If successful, this moves the passed grant to the constructed node.
 bool CConnman::OpenNetworkConnection(const CAddress &addrConnect,
                                      bool fCountFailure,
                                      CSemaphoreGrant *grantOutbound,
                                      const char *pszDest, bool fOneShot,
                                      bool fFeeler, bool fAddnode) {
     //
     // Initiate outbound network connection
     //
     if (interruptNet) {
         return false;
     }
     if (!fNetworkActive) {
         return false;
     }
     if (!pszDest) {
         if (IsLocal(addrConnect) || FindNode((CNetAddr)addrConnect) ||
             IsBanned(addrConnect) || FindNode(addrConnect.ToStringIPPort())) {
             return false;
         }
     } else if (FindNode(std::string(pszDest))) {
         return false;
     }
 
     CNode *pnode = ConnectNode(addrConnect, pszDest, fCountFailure);
 
     if (!pnode) {
         return false;
     }
     if (grantOutbound) {
         grantOutbound->MoveTo(pnode->grantOutbound);
     }
     if (fOneShot) {
         pnode->fOneShot = true;
     }
     if (fFeeler) {
         pnode->fFeeler = true;
     }
     if (fAddnode) {
         pnode->fAddnode = true;
     }
 
     // FIXME: Pass the config down rather than use GetConfig()
     GetNodeSignals().InitializeNode(GetConfig(), pnode, *this);
     {
         LOCK(cs_vNodes);
         vNodes.push_back(pnode);
     }
 
     return true;
 }
 
 void CConnman::ThreadMessageHandler() {
     while (!flagInterruptMsgProc) {
         std::vector<CNode *> vNodesCopy;
         {
             LOCK(cs_vNodes);
             vNodesCopy = vNodes;
             for (CNode *pnode : vNodesCopy) {
                 pnode->AddRef();
             }
         }
 
         bool fMoreWork = false;
 
         for (CNode *pnode : vNodesCopy) {
             if (pnode->fDisconnect) {
                 continue;
             }
 
             // Receive messages
             // FIXME: Pass the config down here.
             bool fMoreNodeWork = GetNodeSignals().ProcessMessages(
                 GetConfig(), pnode, *this, flagInterruptMsgProc);
             fMoreWork |= (fMoreNodeWork && !pnode->fPauseSend);
             if (flagInterruptMsgProc) {
                 return;
             }
 
             // Send messages
             {
                 LOCK(pnode->cs_sendProcessing);
                 GetNodeSignals().SendMessages(GetConfig(), pnode, *this,
                                               flagInterruptMsgProc);
             }
             if (flagInterruptMsgProc) {
                 return;
             }
         }
 
         {
             LOCK(cs_vNodes);
             for (CNode *pnode : vNodesCopy) {
                 pnode->Release();
             }
         }
 
         std::unique_lock<std::mutex> lock(mutexMsgProc);
         if (!fMoreWork) {
             condMsgProc.wait_until(lock, std::chrono::steady_clock::now() +
                                              std::chrono::milliseconds(100),
                                    [this] { return fMsgProcWake; });
         }
         fMsgProcWake = false;
     }
 }
 
 bool CConnman::BindListenPort(const CService &addrBind, std::string &strError,
                               bool fWhitelisted) {
     strError = "";
     int nOne = 1;
 
     // Create socket for listening for incoming connections
     struct sockaddr_storage sockaddr;
     socklen_t len = sizeof(sockaddr);
     if (!addrBind.GetSockAddr((struct sockaddr *)&sockaddr, &len)) {
         strError = strprintf("Error: Bind address family for %s not supported",
                              addrBind.ToString());
         LogPrintf("%s\n", strError);
         return false;
     }
 
     SOCKET hListenSocket = socket(((struct sockaddr *)&sockaddr)->sa_family,
                                   SOCK_STREAM, IPPROTO_TCP);
     if (hListenSocket == INVALID_SOCKET) {
         strError = strprintf("Error: Couldn't open socket for incoming "
                              "connections (socket returned error %s)",
                              NetworkErrorString(WSAGetLastError()));
         LogPrintf("%s\n", strError);
         return false;
     }
     if (!IsSelectableSocket(hListenSocket)) {
         strError = "Error: Couldn't create a listenable socket for incoming "
                    "connections";
         LogPrintf("%s\n", strError);
         return false;
     }
 
 #ifndef WIN32
 #ifdef SO_NOSIGPIPE
     // Different way of disabling SIGPIPE on BSD
     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void *)&nOne,
                sizeof(int));
 #endif
     // Allow binding if the port is still in TIME_WAIT state after
     // the program was closed and restarted.
     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void *)&nOne,
                sizeof(int));
     // Disable Nagle's algorithm
     setsockopt(hListenSocket, IPPROTO_TCP, TCP_NODELAY, (void *)&nOne,
                sizeof(int));
 #else
     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (const char *)&nOne,
                sizeof(int));
     setsockopt(hListenSocket, IPPROTO_TCP, TCP_NODELAY, (const char *)&nOne,
                sizeof(int));
 #endif
 
     // Set to non-blocking, incoming connections will also inherit this
     if (!SetSocketNonBlocking(hListenSocket, true)) {
         strError = strprintf("BindListenPort: Setting listening socket to "
                              "non-blocking failed, error %s\n",
                              NetworkErrorString(WSAGetLastError()));
         LogPrintf("%s\n", strError);
         return false;
     }
 
     // Some systems don't have IPV6_V6ONLY but are always v6only; others do have
     // the option and enable it by default or not. Try to enable it, if
     // possible.
     if (addrBind.IsIPv6()) {
 #ifdef IPV6_V6ONLY
 #ifdef WIN32
         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY,
                    (const char *)&nOne, sizeof(int));
 #else
         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&nOne,
                    sizeof(int));
 #endif
 #endif
 #ifdef WIN32
         int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL,
                    (const char *)&nProtLevel, sizeof(int));
 #endif
     }
 
     if (::bind(hListenSocket, (struct sockaddr *)&sockaddr, len) ==
         SOCKET_ERROR) {
         int nErr = WSAGetLastError();
         if (nErr == WSAEADDRINUSE) {
             strError = strprintf(_("Unable to bind to %s on this computer. %s "
                                    "is probably already running."),
                                  addrBind.ToString(), _(PACKAGE_NAME));
         } else {
             strError = strprintf(_("Unable to bind to %s on this computer "
                                    "(bind returned error %s)"),
                                  addrBind.ToString(), NetworkErrorString(nErr));
         }
         LogPrintf("%s\n", strError);
         CloseSocket(hListenSocket);
         return false;
     }
     LogPrintf("Bound to %s\n", addrBind.ToString());
 
     // Listen for incoming connections
     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR) {
         strError = strprintf(_("Error: Listening for incoming connections "
                                "failed (listen returned error %s)"),
                              NetworkErrorString(WSAGetLastError()));
         LogPrintf("%s\n", strError);
         CloseSocket(hListenSocket);
         return false;
     }
 
     vhListenSocket.push_back(ListenSocket(hListenSocket, fWhitelisted));
 
     if (addrBind.IsRoutable() && fDiscover && !fWhitelisted) {
         AddLocal(addrBind, LOCAL_BIND);
     }
 
     return true;
 }
 
 void Discover(boost::thread_group &threadGroup) {
     if (!fDiscover) {
         return;
     }
 
 #ifdef WIN32
     // Get local host IP
     char pszHostName[256] = "";
     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR) {
         std::vector<CNetAddr> vaddr;
         if (LookupHost(pszHostName, vaddr, 0, true)) {
             for (const CNetAddr &addr : vaddr) {
                 if (AddLocal(addr, LOCAL_IF)) {
                     LogPrintf("%s: %s - %s\n", __func__, pszHostName,
                               addr.ToString());
                 }
             }
         }
     }
 #else
     // Get local host ip
     struct ifaddrs *myaddrs;
     if (getifaddrs(&myaddrs) == 0) {
         for (struct ifaddrs *ifa = myaddrs; ifa != nullptr;
              ifa = ifa->ifa_next) {
             if (ifa->ifa_addr == nullptr || (ifa->ifa_flags & IFF_UP) == 0 ||
                 strcmp(ifa->ifa_name, "lo") == 0 ||
                 strcmp(ifa->ifa_name, "lo0") == 0) {
                 continue;
             }
             if (ifa->ifa_addr->sa_family == AF_INET) {
                 struct sockaddr_in *s4 = (struct sockaddr_in *)(ifa->ifa_addr);
                 CNetAddr addr(s4->sin_addr);
                 if (AddLocal(addr, LOCAL_IF)) {
                     LogPrintf("%s: IPv4 %s: %s\n", __func__, ifa->ifa_name,
                               addr.ToString());
                 }
             } else if (ifa->ifa_addr->sa_family == AF_INET6) {
                 struct sockaddr_in6 *s6 =
                     (struct sockaddr_in6 *)(ifa->ifa_addr);
                 CNetAddr addr(s6->sin6_addr);
                 if (AddLocal(addr, LOCAL_IF)) {
                     LogPrintf("%s: IPv6 %s: %s\n", __func__, ifa->ifa_name,
                               addr.ToString());
                 }
             }
         }
         freeifaddrs(myaddrs);
     }
 #endif
 }
 
 void CConnman::SetNetworkActive(bool active) {
     if (fDebug) {
         LogPrint("net", "SetNetworkActive: %s\n", active);
     }
 
     if (!active) {
         fNetworkActive = false;
 
         LOCK(cs_vNodes);
         // Close sockets to all nodes
         for (CNode *pnode : vNodes) {
             pnode->CloseSocketDisconnect();
         }
     } else {
         fNetworkActive = true;
     }
 
     uiInterface.NotifyNetworkActiveChanged(fNetworkActive);
 }
 
 CConnman::CConnman(uint64_t nSeed0In, uint64_t nSeed1In)
     : nSeed0(nSeed0In), nSeed1(nSeed1In) {
     fNetworkActive = true;
     setBannedIsDirty = false;
     fAddressesInitialized = false;
     nLastNodeId = 0;
     nSendBufferMaxSize = 0;
     nReceiveFloodSize = 0;
     semOutbound = nullptr;
     semAddnode = nullptr;
     nMaxConnections = 0;
     nMaxOutbound = 0;
     nMaxAddnode = 0;
     nBestHeight = 0;
     clientInterface = nullptr;
     flagInterruptMsgProc = false;
 }
 
 NodeId CConnman::GetNewNodeId() {
     return nLastNodeId.fetch_add(1, std::memory_order_relaxed);
 }
 
 bool CConnman::Start(CScheduler &scheduler, std::string &strNodeError,
                      Options connOptions) {
     nTotalBytesRecv = 0;
     nTotalBytesSent = 0;
     nMaxOutboundTotalBytesSentInCycle = 0;
     nMaxOutboundCycleStartTime = 0;
 
     nRelevantServices = connOptions.nRelevantServices;
     nLocalServices = connOptions.nLocalServices;
     nMaxConnections = connOptions.nMaxConnections;
     nMaxOutbound = std::min((connOptions.nMaxOutbound), nMaxConnections);
     nMaxAddnode = connOptions.nMaxAddnode;
     nMaxFeeler = connOptions.nMaxFeeler;
 
     nSendBufferMaxSize = connOptions.nSendBufferMaxSize;
     nReceiveFloodSize = connOptions.nReceiveFloodSize;
 
     nMaxOutboundLimit = connOptions.nMaxOutboundLimit;
     nMaxOutboundTimeframe = connOptions.nMaxOutboundTimeframe;
 
     SetBestHeight(connOptions.nBestHeight);
 
     clientInterface = connOptions.uiInterface;
     if (clientInterface) {
         clientInterface->InitMessage(_("Loading addresses..."));
     }
     // Load addresses from peers.dat
     int64_t nStart = GetTimeMillis();
     {
         CAddrDB adb;
         if (adb.Read(addrman)) {
             LogPrintf("Loaded %i addresses from peers.dat  %dms\n",
                       addrman.size(), GetTimeMillis() - nStart);
         } else {
             // Addrman can be in an inconsistent state after failure, reset it
             addrman.Clear();
             LogPrintf("Invalid or missing peers.dat; recreating\n");
             DumpAddresses();
         }
     }
     if (clientInterface) {
         clientInterface->InitMessage(_("Loading banlist..."));
     }
     // Load addresses from banlist.dat
     nStart = GetTimeMillis();
     CBanDB bandb;
     banmap_t banmap;
     if (bandb.Read(banmap)) {
         // thread save setter
         SetBanned(banmap);
         // no need to write down, just read data
         SetBannedSetDirty(false);
         // sweep out unused entries
         SweepBanned();
 
         LogPrint("net",
                  "Loaded %d banned node ips/subnets from banlist.dat  %dms\n",
                  banmap.size(), GetTimeMillis() - nStart);
     } else {
         LogPrintf("Invalid or missing banlist.dat; recreating\n");
         // force write
         SetBannedSetDirty(true);
         DumpBanlist();
     }
 
     uiInterface.InitMessage(_("Starting network threads..."));
 
     fAddressesInitialized = true;
 
     if (semOutbound == nullptr) {
         // initialize semaphore
         semOutbound = new CSemaphore(
             std::min((nMaxOutbound + nMaxFeeler), nMaxConnections));
     }
     if (semAddnode == nullptr) {
         // initialize semaphore
         semAddnode = new CSemaphore(nMaxAddnode);
     }
 
     //
     // Start threads
     //
     InterruptSocks5(false);
     interruptNet.reset();
     flagInterruptMsgProc = false;
 
     {
         std::unique_lock<std::mutex> lock(mutexMsgProc);
         fMsgProcWake = false;
     }
 
     // Send and receive from sockets, accept connections
     threadSocketHandler = std::thread(
         &TraceThread<std::function<void()>>, "net",
         std::function<void()>(std::bind(&CConnman::ThreadSocketHandler, this)));
 
     if (!GetBoolArg("-dnsseed", true)) {
         LogPrintf("DNS seeding disabled\n");
     } else {
         threadDNSAddressSeed =
             std::thread(&TraceThread<std::function<void()>>, "dnsseed",
                         std::function<void()>(
                             std::bind(&CConnman::ThreadDNSAddressSeed, this)));
     }
 
     // Initiate outbound connections from -addnode
     threadOpenAddedConnections =
         std::thread(&TraceThread<std::function<void()>>, "addcon",
                     std::function<void()>(std::bind(
                         &CConnman::ThreadOpenAddedConnections, this)));
 
     // Initiate outbound connections unless connect=0
     if (!mapMultiArgs.count("-connect") ||
         mapMultiArgs.at("-connect").size() != 1 ||
         mapMultiArgs.at("-connect")[0] != "0") {
         threadOpenConnections =
             std::thread(&TraceThread<std::function<void()>>, "opencon",
                         std::function<void()>(
                             std::bind(&CConnman::ThreadOpenConnections, this)));
     }
 
     // Process messages
     threadMessageHandler =
         std::thread(&TraceThread<std::function<void()>>, "msghand",
                     std::function<void()>(
                         std::bind(&CConnman::ThreadMessageHandler, this)));
 
     // Dump network addresses
     scheduler.scheduleEvery(boost::bind(&CConnman::DumpData, this),
                             DUMP_ADDRESSES_INTERVAL);
 
     return true;
 }
 
 class CNetCleanup {
 public:
     CNetCleanup() {}
 
     ~CNetCleanup() {
 #ifdef WIN32
         // Shutdown Windows Sockets
         WSACleanup();
 #endif
     }
 } instance_of_cnetcleanup;
 
 void CConnman::Interrupt() {
     {
         std::lock_guard<std::mutex> lock(mutexMsgProc);
         flagInterruptMsgProc = true;
     }
     condMsgProc.notify_all();
 
     interruptNet();
     InterruptSocks5(true);
 
     if (semOutbound) {
         for (int i = 0; i < (nMaxOutbound + nMaxFeeler); i++) {
             semOutbound->post();
         }
     }
 
     if (semAddnode) {
         for (int i = 0; i < nMaxAddnode; i++) {
             semAddnode->post();
         }
     }
 }
 
 void CConnman::Stop() {
     if (threadMessageHandler.joinable()) {
         threadMessageHandler.join();
     }
     if (threadOpenConnections.joinable()) {
         threadOpenConnections.join();
     }
     if (threadOpenAddedConnections.joinable()) {
         threadOpenAddedConnections.join();
     }
     if (threadDNSAddressSeed.joinable()) {
         threadDNSAddressSeed.join();
     }
     if (threadSocketHandler.joinable()) {
         threadSocketHandler.join();
     }
 
     if (fAddressesInitialized) {
         DumpData();
         fAddressesInitialized = false;
     }
 
     // Close sockets
     for (CNode *pnode : vNodes) {
         pnode->CloseSocketDisconnect();
     }
     for (ListenSocket &hListenSocket : vhListenSocket) {
         if (hListenSocket.socket != INVALID_SOCKET) {
             if (!CloseSocket(hListenSocket.socket)) {
                 LogPrintf("CloseSocket(hListenSocket) failed with error %s\n",
                           NetworkErrorString(WSAGetLastError()));
             }
         }
     }
 
     // clean up some globals (to help leak detection)
     for (CNode *pnode : vNodes) {
         DeleteNode(pnode);
     }
     for (CNode *pnode : vNodesDisconnected) {
         DeleteNode(pnode);
     }
     vNodes.clear();
     vNodesDisconnected.clear();
     vhListenSocket.clear();
     delete semOutbound;
     semOutbound = nullptr;
     delete semAddnode;
     semAddnode = nullptr;
 }
 
 void CConnman::DeleteNode(CNode *pnode) {
     assert(pnode);
     bool fUpdateConnectionTime = false;
     GetNodeSignals().FinalizeNode(pnode->GetId(), fUpdateConnectionTime);
     if (fUpdateConnectionTime) {
         addrman.Connected(pnode->addr);
     }
     delete pnode;
 }
 
 CConnman::~CConnman() {
     Interrupt();
     Stop();
 }
 
 size_t CConnman::GetAddressCount() const {
     return addrman.size();
 }
 
 void CConnman::SetServices(const CService &addr, ServiceFlags nServices) {
     addrman.SetServices(addr, nServices);
 }
 
 void CConnman::MarkAddressGood(const CAddress &addr) {
     addrman.Good(addr);
 }
 
 void CConnman::AddNewAddress(const CAddress &addr, const CAddress &addrFrom,
                              int64_t nTimePenalty) {
     addrman.Add(addr, addrFrom, nTimePenalty);
 }
 
 void CConnman::AddNewAddresses(const std::vector<CAddress> &vAddr,
                                const CAddress &addrFrom, int64_t nTimePenalty) {
     addrman.Add(vAddr, addrFrom, nTimePenalty);
 }
 
 std::vector<CAddress> CConnman::GetAddresses() {
     return addrman.GetAddr();
 }
 
 bool CConnman::AddNode(const std::string &strNode) {
     LOCK(cs_vAddedNodes);
     for (std::vector<std::string>::const_iterator it = vAddedNodes.begin();
          it != vAddedNodes.end(); ++it) {
         if (strNode == *it) {
             return false;
         }
     }
 
     vAddedNodes.push_back(strNode);
     return true;
 }
 
 bool CConnman::RemoveAddedNode(const std::string &strNode) {
     LOCK(cs_vAddedNodes);
     for (std::vector<std::string>::iterator it = vAddedNodes.begin();
          it != vAddedNodes.end(); ++it) {
         if (strNode == *it) {
             vAddedNodes.erase(it);
             return true;
         }
     }
     return false;
 }
 
 size_t CConnman::GetNodeCount(NumConnections flags) {
     LOCK(cs_vNodes);
     // Shortcut if we want total
     if (flags == CConnman::CONNECTIONS_ALL) {
         return vNodes.size();
     }
 
     int nNum = 0;
     for (std::vector<CNode *>::const_iterator it = vNodes.begin();
          it != vNodes.end(); ++it) {
         if (flags & ((*it)->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT)) {
             nNum++;
         }
     }
 
     return nNum;
 }
 
 void CConnman::GetNodeStats(std::vector<CNodeStats> &vstats) {
     vstats.clear();
     LOCK(cs_vNodes);
     vstats.reserve(vNodes.size());
     for (std::vector<CNode *>::iterator it = vNodes.begin(); it != vNodes.end();
          ++it) {
         CNode *pnode = *it;
         vstats.emplace_back();
         pnode->copyStats(vstats.back());
     }
 }
 
 bool CConnman::DisconnectNode(const std::string &strNode) {
     LOCK(cs_vNodes);
     if (CNode *pnode = FindNode(strNode)) {
         pnode->fDisconnect = true;
         return true;
     }
     return false;
 }
 bool CConnman::DisconnectNode(NodeId id) {
     LOCK(cs_vNodes);
     for (CNode *pnode : vNodes) {
         if (id == pnode->id) {
             pnode->fDisconnect = true;
             return true;
         }
     }
     return false;
 }
 
 void CConnman::RecordBytesRecv(uint64_t bytes) {
     LOCK(cs_totalBytesRecv);
     nTotalBytesRecv += bytes;
 }
 
 void CConnman::RecordBytesSent(uint64_t bytes) {
     LOCK(cs_totalBytesSent);
     nTotalBytesSent += bytes;
 
     uint64_t now = GetTime();
     if (nMaxOutboundCycleStartTime + nMaxOutboundTimeframe < now) {
         // timeframe expired, reset cycle
         nMaxOutboundCycleStartTime = now;
         nMaxOutboundTotalBytesSentInCycle = 0;
     }
 
     // TODO, exclude whitebind peers
     nMaxOutboundTotalBytesSentInCycle += bytes;
 }
 
 void CConnman::SetMaxOutboundTarget(uint64_t limit) {
     LOCK(cs_totalBytesSent);
     nMaxOutboundLimit = limit;
 }
 
 uint64_t CConnman::GetMaxOutboundTarget() {
     LOCK(cs_totalBytesSent);
     return nMaxOutboundLimit;
 }
 
 uint64_t CConnman::GetMaxOutboundTimeframe() {
     LOCK(cs_totalBytesSent);
     return nMaxOutboundTimeframe;
 }
 
 uint64_t CConnman::GetMaxOutboundTimeLeftInCycle() {
     LOCK(cs_totalBytesSent);
     if (nMaxOutboundLimit == 0) {
         return 0;
     }
 
     if (nMaxOutboundCycleStartTime == 0) {
         return nMaxOutboundTimeframe;
     }
 
     uint64_t cycleEndTime = nMaxOutboundCycleStartTime + nMaxOutboundTimeframe;
     uint64_t now = GetTime();
     return (cycleEndTime < now) ? 0 : cycleEndTime - GetTime();
 }
 
 void CConnman::SetMaxOutboundTimeframe(uint64_t timeframe) {
     LOCK(cs_totalBytesSent);
     if (nMaxOutboundTimeframe != timeframe) {
         // reset measure-cycle in case of changing the timeframe.
         nMaxOutboundCycleStartTime = GetTime();
     }
     nMaxOutboundTimeframe = timeframe;
 }
 
 bool CConnman::OutboundTargetReached(bool historicalBlockServingLimit) {
     LOCK(cs_totalBytesSent);
     if (nMaxOutboundLimit == 0) {
         return false;
     }
 
     if (historicalBlockServingLimit) {
         // keep a large enough buffer to at least relay each block once.
         uint64_t timeLeftInCycle = GetMaxOutboundTimeLeftInCycle();
         uint64_t buffer = timeLeftInCycle / 600 * ONE_MEGABYTE;
         if (buffer >= nMaxOutboundLimit ||
             nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit - buffer) {
             return true;
         }
     } else if (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit) {
         return true;
     }
 
     return false;
 }
 
 uint64_t CConnman::GetOutboundTargetBytesLeft() {
     LOCK(cs_totalBytesSent);
     if (nMaxOutboundLimit == 0) {
         return 0;
     }
 
     return (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit)
                ? 0
                : nMaxOutboundLimit - nMaxOutboundTotalBytesSentInCycle;
 }
 
 uint64_t CConnman::GetTotalBytesRecv() {
     LOCK(cs_totalBytesRecv);
     return nTotalBytesRecv;
 }
 
 uint64_t CConnman::GetTotalBytesSent() {
     LOCK(cs_totalBytesSent);
     return nTotalBytesSent;
 }
 
 ServiceFlags CConnman::GetLocalServices() const {
     return nLocalServices;
 }
 
 void CConnman::SetBestHeight(int height) {
     nBestHeight.store(height, std::memory_order_release);
 }
 
 int CConnman::GetBestHeight() const {
     return nBestHeight.load(std::memory_order_acquire);
 }
 
 unsigned int CConnman::GetReceiveFloodSize() const {
     return nReceiveFloodSize;
 }
 unsigned int CConnman::GetSendBufferSize() const {
     return nSendBufferMaxSize;
 }
 
 CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn,
              int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn,
              uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn,
              const std::string &addrNameIn, bool fInboundIn)
     : nTimeConnected(GetSystemTimeInSeconds()), addr(addrIn),
       fInbound(fInboundIn), id(idIn), nKeyedNetGroup(nKeyedNetGroupIn),
       addrKnown(5000, 0.001), filterInventoryKnown(50000, 0.000001),
       nLocalHostNonce(nLocalHostNonceIn), nLocalServices(nLocalServicesIn),
       nMyStartingHeight(nMyStartingHeightIn), nSendVersion(0) {
     nServices = NODE_NONE;
     nServicesExpected = NODE_NONE;
     hSocket = hSocketIn;
     nRecvVersion = INIT_PROTO_VERSION;
     nLastSend = 0;
     nLastRecv = 0;
     nSendBytes = 0;
     nRecvBytes = 0;
     nTimeOffset = 0;
     addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
     nVersion = 0;
     strSubVer = "";
     fWhitelisted = false;
     fOneShot = false;
     fAddnode = false;
     // set by version message
     fClient = false;
     fFeeler = false;
     fSuccessfullyConnected = false;
     fDisconnect = false;
     nRefCount = 0;
     nSendSize = 0;
     nSendOffset = 0;
     hashContinue = uint256();
     nStartingHeight = -1;
     filterInventoryKnown.reset();
     fSendMempool = false;
     fGetAddr = false;
     nNextLocalAddrSend = 0;
     nNextAddrSend = 0;
     nNextInvSend = 0;
     fRelayTxes = false;
     fSentAddr = false;
     pfilter = new CBloomFilter();
     timeLastMempoolReq = 0;
     nLastBlockTime = 0;
     nLastTXTime = 0;
     nPingNonceSent = 0;
     nPingUsecStart = 0;
     nPingUsecTime = 0;
     fPingQueued = false;
     // set when etablishing connection
     fUsesCashMagic = false;
     nMinPingUsecTime = std::numeric_limits<int64_t>::max();
     minFeeFilter = 0;
     lastSentFeeFilter = 0;
     nextSendTimeFeeFilter = 0;
     fPauseRecv = false;
     fPauseSend = false;
     nProcessQueueSize = 0;
 
     for (const std::string &msg : getAllNetMessageTypes()) {
         mapRecvBytesPerMsgCmd[msg] = 0;
     }
     mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0;
 
     if (fLogIPs) {
         LogPrint("net", "Added connection to %s peer=%d\n", addrName, id);
     } else {
         LogPrint("net", "Added connection peer=%d\n", id);
     }
 }
 
 CNode::~CNode() {
     CloseSocket(hSocket);
 
     if (pfilter) {
         delete pfilter;
     }
 }
 
 void CNode::AskFor(const CInv &inv) {
     if (mapAskFor.size() > MAPASKFOR_MAX_SZ ||
         setAskFor.size() > SETASKFOR_MAX_SZ) {
         return;
     }
 
     // a peer may not have multiple non-responded queue positions for a single
     // inv item.
     if (!setAskFor.insert(inv.hash).second) {
         return;
     }
 
     // We're using mapAskFor as a priority queue, the key is the earliest time
     // the request can be sent.
     int64_t nRequestTime;
     limitedmap<uint256, int64_t>::const_iterator it =
         mapAlreadyAskedFor.find(inv.hash);
     if (it != mapAlreadyAskedFor.end()) {
         nRequestTime = it->second;
     } else {
         nRequestTime = 0;
     }
     LogPrint("net", "askfor %s  %d (%s) peer=%d\n", inv.ToString(),
              nRequestTime,
              DateTimeStrFormat("%H:%M:%S", nRequestTime / 1000000), id);
 
     // Make sure not to reuse time indexes to keep things in the same order
     int64_t nNow = GetTimeMicros() - 1000000;
     static int64_t nLastTime;
     ++nLastTime;
     nNow = std::max(nNow, nLastTime);
     nLastTime = nNow;
 
     // Each retry is 2 minutes after the last
     nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
     if (it != mapAlreadyAskedFor.end()) {
         mapAlreadyAskedFor.update(it, nRequestTime);
     } else {
         mapAlreadyAskedFor.insert(std::make_pair(inv.hash, nRequestTime));
     }
     mapAskFor.insert(std::make_pair(nRequestTime, inv));
 }
 
 bool CConnman::NodeFullyConnected(const CNode *pnode) {
     return pnode && pnode->fSuccessfullyConnected && !pnode->fDisconnect;
 }
 
 void CConnman::PushMessage(CNode *pnode, CSerializedNetMsg &&msg) {
     size_t nMessageSize = msg.data.size();
     size_t nTotalSize = nMessageSize + CMessageHeader::HEADER_SIZE;
     LogPrint("net", "sending %s (%d bytes) peer=%d\n",
              SanitizeString(msg.command.c_str()), nMessageSize, pnode->id);
 
-    std::vector<unsigned char> serializedHeader;
+    std::vector<uint8_t> serializedHeader;
     serializedHeader.reserve(CMessageHeader::HEADER_SIZE);
     uint256 hash = Hash(msg.data.data(), msg.data.data() + nMessageSize);
     CMessageHeader hdr(pnode->GetMagic(Params()), msg.command.c_str(),
                        nMessageSize);
     memcpy(hdr.pchChecksum, hash.begin(), CMessageHeader::CHECKSUM_SIZE);
 
     CVectorWriter{SER_NETWORK, INIT_PROTO_VERSION, serializedHeader, 0, hdr};
 
     size_t nBytesSent = 0;
     {
         LOCK(pnode->cs_vSend);
         bool optimisticSend(pnode->vSendMsg.empty());
 
         // log total amount of bytes per command
         pnode->mapSendBytesPerMsgCmd[msg.command] += nTotalSize;
         pnode->nSendSize += nTotalSize;
 
         if (pnode->nSendSize > nSendBufferMaxSize) {
             pnode->fPauseSend = true;
         }
         pnode->vSendMsg.push_back(std::move(serializedHeader));
         if (nMessageSize) {
             pnode->vSendMsg.push_back(std::move(msg.data));
         }
 
         // If write queue empty, attempt "optimistic write"
         if (optimisticSend == true) {
             nBytesSent = SocketSendData(pnode);
         }
     }
     if (nBytesSent) {
         RecordBytesSent(nBytesSent);
     }
 }
 
 bool CConnman::ForNode(NodeId id, std::function<bool(CNode *pnode)> func) {
     CNode *found = nullptr;
     LOCK(cs_vNodes);
     for (auto &&pnode : vNodes) {
         if (pnode->id == id) {
             found = pnode;
             break;
         }
     }
     return found != nullptr && NodeFullyConnected(found) && func(found);
 }
 
 int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) {
     return nNow + int64_t(log1p(GetRand(1ULL << 48) *
                                 -0.0000000000000035527136788 /* -1/2^48 */) *
                               average_interval_seconds * -1000000.0 +
                           0.5);
 }
 
 CSipHasher CConnman::GetDeterministicRandomizer(uint64_t id) const {
     return CSipHasher(nSeed0, nSeed1).Write(id);
 }
 
 uint64_t CConnman::CalculateKeyedNetGroup(const CAddress &ad) const {
-    std::vector<unsigned char> vchNetGroup(ad.GetGroup());
+    std::vector<uint8_t> vchNetGroup(ad.GetGroup());
 
     return GetDeterministicRandomizer(RANDOMIZER_ID_NETGROUP)
         .Write(&vchNetGroup[0], vchNetGroup.size())
         .Finalize();
 }
 
 /**
  * This function convert MaxBlockSize from byte to
  * MB with a decimal precision one digit rounded down
  * E.g.
  * 1660000 -> 1.6
  * 2010000 -> 2.0
  * 1000000 -> 1.0
  * 230000  -> 0.2
  * 50000   -> 0.0
  *
  *  NB behavior for EB<1MB not standardized yet still
  *  the function applies the same algo used for
  *  EB greater or equal to 1MB
  */
 std::string getSubVersionEB(uint64_t MaxBlockSize) {
     // Prepare EB string we are going to add to SubVer:
     // 1) translate from byte to MB and convert to string
     // 2) limit the EB string to the first decimal digit (floored)
     std::stringstream ebMBs;
     ebMBs << (MaxBlockSize / (ONE_MEGABYTE / 10));
     std::string eb = ebMBs.str();
     eb.insert(eb.size() - 1, ".", 1);
     if (eb.substr(0, 1) == ".") {
         eb = "0" + eb;
     }
     return eb;
 }
 
 std::string userAgent(const Config &config) {
     // format excessive blocksize value
     std::string eb = getSubVersionEB(config.GetMaxBlockSize());
     std::vector<std::string> uacomments;
     uacomments.push_back("EB" + eb);
 
     // sanitize comments per BIP-0014, format user agent and check total size
     if (mapMultiArgs.count("-uacomment")) {
         for (const std::string &cmt : mapMultiArgs.at("-uacomment")) {
             if (cmt != SanitizeString(cmt, SAFE_CHARS_UA_COMMENT)) {
                 LogPrintf(
                     "User Agent comment (%s) contains unsafe characters. "
                     "We are going to use a sanitize version of the comment.\n",
                     cmt);
             }
             uacomments.push_back(cmt);
         }
     }
 
     std::string subversion =
         FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, uacomments);
     if (subversion.size() > MAX_SUBVERSION_LENGTH) {
         LogPrintf("Total length of network version string (%i) exceeds maximum "
                   "length (%i). Reduce the number or size of uacomments. "
                   "String has been resized to the max length allowed.\n",
                   subversion.size(), MAX_SUBVERSION_LENGTH);
         subversion.resize(MAX_SUBVERSION_LENGTH - 2);
         subversion.append(")/");
         LogPrintf("Current network string has been set to: %s\n", subversion);
     }
 
     return subversion;
 }
diff --git a/src/net.h b/src/net.h
index c1f364ff2..1bd051d38 100644
--- a/src/net.h
+++ b/src/net.h
@@ -1,828 +1,828 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_NET_H
 #define BITCOIN_NET_H
 
 #include "addrdb.h"
 #include "addrman.h"
 #include "amount.h"
 #include "bloom.h"
 #include "chainparams.h"
 #include "compat.h"
 #include "hash.h"
 #include "limitedmap.h"
 #include "netaddress.h"
 #include "protocol.h"
 #include "random.h"
 #include "streams.h"
 #include "sync.h"
 #include "threadinterrupt.h"
 #include "uint256.h"
 
 #include <atomic>
 #include <condition_variable>
 #include <cstdint>
 #include <deque>
 #include <memory>
 #include <thread>
 
 #ifndef WIN32
 #include <arpa/inet.h>
 #endif
 
 #include <boost/filesystem/path.hpp>
 #include <boost/signals2/signal.hpp>
 
 class CAddrMan;
 class Config;
 class CNode;
 class CScheduler;
 
 namespace boost {
 class thread_group;
 } // namespace boost
 
 /** Time between pings automatically sent out for latency probing and keepalive
  * (in seconds). */
 static const int PING_INTERVAL = 2 * 60;
 /** Time after which to disconnect, after waiting for a ping response (or
  * inactivity). */
 static const int TIMEOUT_INTERVAL = 20 * 60;
 /** Run the feeler connection loop once every 2 minutes or 120 seconds. **/
 static const int FEELER_INTERVAL = 120;
 /** The maximum number of entries in an 'inv' protocol message */
 static const unsigned int MAX_INV_SZ = 50000;
 /** The maximum number of new addresses to accumulate before announcing. */
 static const unsigned int MAX_ADDR_TO_SEND = 1000;
 /** Maximum length of incoming protocol messages (no message over 4 MB is
  * currently acceptable). */
 static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 32 * 1000 * 1000;
 /** Maximum length of strSubVer in `version` message */
 static const unsigned int MAX_SUBVERSION_LENGTH = 256;
 /** Maximum number of automatic outgoing nodes */
 static const int MAX_OUTBOUND_CONNECTIONS = 8;
 /** Maximum number of addnode outgoing nodes */
 static const int MAX_ADDNODE_CONNECTIONS = 8;
 /** -listen default */
 static const bool DEFAULT_LISTEN = true;
 /** -upnp default */
 #ifdef USE_UPNP
 static const bool DEFAULT_UPNP = USE_UPNP;
 #else
 static const bool DEFAULT_UPNP = false;
 #endif
 /** The maximum number of entries in mapAskFor */
 static const size_t MAPASKFOR_MAX_SZ = MAX_INV_SZ;
 /** The maximum number of entries in setAskFor (larger due to getdata latency)*/
 static const size_t SETASKFOR_MAX_SZ = 2 * MAX_INV_SZ;
 /** The maximum number of peer connections to maintain. */
 static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 125;
 /** The default for -maxuploadtarget. 0 = Unlimited */
 static const uint64_t DEFAULT_MAX_UPLOAD_TARGET = 0;
 /** The default timeframe for -maxuploadtarget. 1 day. */
 static const uint64_t MAX_UPLOAD_TIMEFRAME = 60 * 60 * 24;
 /** Default for blocks only*/
 static const bool DEFAULT_BLOCKSONLY = false;
 
 // Force DNS seed use ahead of UAHF fork, to ensure peers are found
 // as long as seeders are working.
 // TODO: Change this back to false after the forked network is stable.
 static const bool DEFAULT_FORCEDNSSEED = true;
 static const size_t DEFAULT_MAXRECEIVEBUFFER = 5 * 1000;
 static const size_t DEFAULT_MAXSENDBUFFER = 1 * 1000;
 
 static const ServiceFlags REQUIRED_SERVICES =
     ServiceFlags(NODE_NETWORK | NODE_BITCOIN_CASH);
 
 // Default 24-hour ban.
 // NOTE: When adjusting this, update rpcnet:setban's help ("24h")
 static const unsigned int DEFAULT_MISBEHAVING_BANTIME = 60 * 60 * 24;
 
 typedef int64_t NodeId;
 
 struct AddedNodeInfo {
     std::string strAddedNode;
     CService resolvedAddress;
     bool fConnected;
     bool fInbound;
 };
 
 class CTransaction;
 class CNodeStats;
 class CClientUIInterface;
 
 struct CSerializedNetMsg {
     CSerializedNetMsg() = default;
     CSerializedNetMsg(CSerializedNetMsg &&) = default;
     CSerializedNetMsg &operator=(CSerializedNetMsg &&) = default;
     // No copying, only moves.
     CSerializedNetMsg(const CSerializedNetMsg &msg) = delete;
     CSerializedNetMsg &operator=(const CSerializedNetMsg &) = delete;
 
-    std::vector<unsigned char> data;
+    std::vector<uint8_t> data;
     std::string command;
 };
 
 class CConnman {
 public:
     enum NumConnections {
         CONNECTIONS_NONE = 0,
         CONNECTIONS_IN = (1U << 0),
         CONNECTIONS_OUT = (1U << 1),
         CONNECTIONS_ALL = (CONNECTIONS_IN | CONNECTIONS_OUT),
     };
 
     struct Options {
         ServiceFlags nLocalServices = NODE_NONE;
         ServiceFlags nRelevantServices = NODE_NONE;
         int nMaxConnections = 0;
         int nMaxOutbound = 0;
         int nMaxAddnode = 0;
         int nMaxFeeler = 0;
         int nBestHeight = 0;
         CClientUIInterface *uiInterface = nullptr;
         unsigned int nSendBufferMaxSize = 0;
         unsigned int nReceiveFloodSize = 0;
         uint64_t nMaxOutboundTimeframe = 0;
         uint64_t nMaxOutboundLimit = 0;
     };
     CConnman(uint64_t seed0, uint64_t seed1);
     ~CConnman();
     bool Start(CScheduler &scheduler, std::string &strNodeError,
                Options options);
     void Stop();
     void Interrupt();
     bool BindListenPort(const CService &bindAddr, std::string &strError,
                         bool fWhitelisted = false);
     bool GetNetworkActive() const { return fNetworkActive; };
     void SetNetworkActive(bool active);
     bool OpenNetworkConnection(const CAddress &addrConnect, bool fCountFailure,
                                CSemaphoreGrant *grantOutbound = nullptr,
                                const char *strDest = nullptr,
                                bool fOneShot = false, bool fFeeler = false,
                                bool fAddnode = false);
     bool CheckIncomingNonce(uint64_t nonce);
 
     bool ForNode(NodeId id, std::function<bool(CNode *pnode)> func);
 
     void PushMessage(CNode *pnode, CSerializedNetMsg &&msg);
 
     template <typename Callable> void ForEachNode(Callable &&func) {
         LOCK(cs_vNodes);
         for (auto &&node : vNodes) {
             if (NodeFullyConnected(node)) func(node);
         }
     };
 
     template <typename Callable> void ForEachNode(Callable &&func) const {
         LOCK(cs_vNodes);
         for (auto &&node : vNodes) {
             if (NodeFullyConnected(node)) func(node);
         }
     };
 
     template <typename Callable, typename CallableAfter>
     void ForEachNodeThen(Callable &&pre, CallableAfter &&post) {
         LOCK(cs_vNodes);
         for (auto &&node : vNodes) {
             if (NodeFullyConnected(node)) pre(node);
         }
         post();
     };
 
     template <typename Callable, typename CallableAfter>
     void ForEachNodeThen(Callable &&pre, CallableAfter &&post) const {
         LOCK(cs_vNodes);
         for (auto &&node : vNodes) {
             if (NodeFullyConnected(node)) pre(node);
         }
         post();
     };
 
     // Addrman functions
     size_t GetAddressCount() const;
     void SetServices(const CService &addr, ServiceFlags nServices);
     void MarkAddressGood(const CAddress &addr);
     void AddNewAddress(const CAddress &addr, const CAddress &addrFrom,
                        int64_t nTimePenalty = 0);
     void AddNewAddresses(const std::vector<CAddress> &vAddr,
                          const CAddress &addrFrom, int64_t nTimePenalty = 0);
     std::vector<CAddress> GetAddresses();
     void AddressCurrentlyConnected(const CService &addr);
 
     // Denial-of-service detection/prevention. The idea is to detect peers that
     // are behaving badly and disconnect/ban them, but do it in a
     // one-coding-mistake-won't-shatter-the-entire-network way.
     // IMPORTANT: There should be nothing I can give a node that it will forward
     // on that will make that node's peers drop it. If there is, an attacker can
     // isolate a node and/or try to split the network. Dropping a node for
     // sending stuff that is invalid now but might be valid in a later version
     // is also dangerous, because it can cause a network split between nodes
     // running old code and nodes running new code.
     void Ban(const CNetAddr &netAddr, const BanReason &reason,
              int64_t bantimeoffset = 0, bool sinceUnixEpoch = false);
     void Ban(const CSubNet &subNet, const BanReason &reason,
              int64_t bantimeoffset = 0, bool sinceUnixEpoch = false);
     // Needed for unit testing.
     void ClearBanned();
     bool IsBanned(CNetAddr ip);
     bool IsBanned(CSubNet subnet);
     bool Unban(const CNetAddr &ip);
     bool Unban(const CSubNet &ip);
     void GetBanned(banmap_t &banmap);
     void SetBanned(const banmap_t &banmap);
 
     void AddOneShot(const std::string &strDest);
 
     bool AddNode(const std::string &node);
     bool RemoveAddedNode(const std::string &node);
     std::vector<AddedNodeInfo> GetAddedNodeInfo();
 
     size_t GetNodeCount(NumConnections num);
     void GetNodeStats(std::vector<CNodeStats> &vstats);
     bool DisconnectNode(const std::string &node);
     bool DisconnectNode(NodeId id);
 
     unsigned int GetSendBufferSize() const;
 
     void AddWhitelistedRange(const CSubNet &subnet);
 
     ServiceFlags GetLocalServices() const;
 
     //! set the max outbound target in bytes.
     void SetMaxOutboundTarget(uint64_t limit);
     uint64_t GetMaxOutboundTarget();
 
     //! set the timeframe for the max outbound target.
     void SetMaxOutboundTimeframe(uint64_t timeframe);
     uint64_t GetMaxOutboundTimeframe();
 
     //! check if the outbound target is reached.
     // If param historicalBlockServingLimit is set true, the function will
     // response true if the limit for serving historical blocks has been
     // reached.
     bool OutboundTargetReached(bool historicalBlockServingLimit);
 
     //! response the bytes left in the current max outbound cycle
     // in case of no limit, it will always response 0
     uint64_t GetOutboundTargetBytesLeft();
 
     //! response the time in second left in the current max outbound cycle
     // in case of no limit, it will always response 0
     uint64_t GetMaxOutboundTimeLeftInCycle();
 
     uint64_t GetTotalBytesRecv();
     uint64_t GetTotalBytesSent();
 
     void SetBestHeight(int height);
     int GetBestHeight() const;
 
     /** Get a unique deterministic randomizer. */
     CSipHasher GetDeterministicRandomizer(uint64_t id) const;
 
     unsigned int GetReceiveFloodSize() const;
 
     void WakeMessageHandler();
 
 private:
     struct ListenSocket {
         SOCKET socket;
         bool whitelisted;
 
         ListenSocket(SOCKET socket_, bool whitelisted_)
             : socket(socket_), whitelisted(whitelisted_) {}
     };
 
     void ThreadOpenAddedConnections();
     void ProcessOneShot();
     void ThreadOpenConnections();
     void ThreadMessageHandler();
     void AcceptConnection(const ListenSocket &hListenSocket);
     void ThreadSocketHandler();
     void ThreadDNSAddressSeed();
 
     uint64_t CalculateKeyedNetGroup(const CAddress &ad) const;
 
     CNode *FindNode(const CNetAddr &ip);
     CNode *FindNode(const CSubNet &subNet);
     CNode *FindNode(const std::string &addrName);
     CNode *FindNode(const CService &addr);
 
     bool AttemptToEvictConnection();
     CNode *ConnectNode(CAddress addrConnect, const char *pszDest,
                        bool fCountFailure);
     bool IsWhitelistedRange(const CNetAddr &addr);
 
     void DeleteNode(CNode *pnode);
 
     NodeId GetNewNodeId();
 
     size_t SocketSendData(CNode *pnode) const;
     //! check is the banlist has unwritten changes
     bool BannedSetIsDirty();
     //! set the "dirty" flag for the banlist
     void SetBannedSetDirty(bool dirty = true);
     //! clean unused entries (if bantime has expired)
     void SweepBanned();
     void DumpAddresses();
     void DumpData();
     void DumpBanlist();
 
     // Network stats
     void RecordBytesRecv(uint64_t bytes);
     void RecordBytesSent(uint64_t bytes);
 
     // Whether the node should be passed out in ForEach* callbacks
     static bool NodeFullyConnected(const CNode *pnode);
 
     // Network usage totals
     CCriticalSection cs_totalBytesRecv;
     CCriticalSection cs_totalBytesSent;
     uint64_t nTotalBytesRecv;
     uint64_t nTotalBytesSent;
 
     // outbound limit & stats
     uint64_t nMaxOutboundTotalBytesSentInCycle;
     uint64_t nMaxOutboundCycleStartTime;
     uint64_t nMaxOutboundLimit;
     uint64_t nMaxOutboundTimeframe;
 
     // Whitelisted ranges. Any node connecting from these is automatically
     // whitelisted (as well as those connecting to whitelisted binds).
     std::vector<CSubNet> vWhitelistedRange;
     CCriticalSection cs_vWhitelistedRange;
 
     unsigned int nSendBufferMaxSize;
     unsigned int nReceiveFloodSize;
 
     std::vector<ListenSocket> vhListenSocket;
     std::atomic<bool> fNetworkActive;
     banmap_t setBanned;
     CCriticalSection cs_setBanned;
     bool setBannedIsDirty;
     bool fAddressesInitialized;
     CAddrMan addrman;
     std::deque<std::string> vOneShots;
     CCriticalSection cs_vOneShots;
     std::vector<std::string> vAddedNodes;
     CCriticalSection cs_vAddedNodes;
     std::vector<CNode *> vNodes;
     std::list<CNode *> vNodesDisconnected;
     mutable CCriticalSection cs_vNodes;
     std::atomic<NodeId> nLastNodeId;
 
     /** Services this instance offers */
     ServiceFlags nLocalServices;
 
     /** Services this instance cares about */
     ServiceFlags nRelevantServices;
 
     CSemaphore *semOutbound;
     CSemaphore *semAddnode;
     int nMaxConnections;
     int nMaxOutbound;
     int nMaxAddnode;
     int nMaxFeeler;
     std::atomic<int> nBestHeight;
     CClientUIInterface *clientInterface;
 
     /** SipHasher seeds for deterministic randomness */
     const uint64_t nSeed0, nSeed1;
 
     /** flag for waking the message processor. */
     bool fMsgProcWake;
 
     std::condition_variable condMsgProc;
     std::mutex mutexMsgProc;
     std::atomic<bool> flagInterruptMsgProc;
 
     CThreadInterrupt interruptNet;
 
     std::thread threadDNSAddressSeed;
     std::thread threadSocketHandler;
     std::thread threadOpenAddedConnections;
     std::thread threadOpenConnections;
     std::thread threadMessageHandler;
 };
 extern std::unique_ptr<CConnman> g_connman;
 void Discover(boost::thread_group &threadGroup);
 void MapPort(bool fUseUPnP);
 unsigned short GetListenPort();
 bool BindListenPort(const CService &bindAddr, std::string &strError,
                     bool fWhitelisted = false);
 
 struct CombinerAll {
     typedef bool result_type;
 
     template <typename I> bool operator()(I first, I last) const {
         while (first != last) {
             if (!(*first)) {
                 return false;
             }
             ++first;
         }
         return true;
     }
 };
 
 // Signals for message handling
 struct CNodeSignals {
     boost::signals2::signal<bool(const Config &, CNode *, CConnman &,
                                  std::atomic<bool> &),
                             CombinerAll>
         ProcessMessages;
     boost::signals2::signal<bool(const Config &, CNode *, CConnman &,
                                  std::atomic<bool> &),
                             CombinerAll>
         SendMessages;
     boost::signals2::signal<void(const Config &, CNode *, CConnman &)>
         InitializeNode;
     boost::signals2::signal<void(NodeId, bool &)> FinalizeNode;
 };
 
 CNodeSignals &GetNodeSignals();
 
 enum {
     // unknown
     LOCAL_NONE,
     // address a local interface listens on
     LOCAL_IF,
     // address explicit bound to
     LOCAL_BIND,
     // address reported by UPnP
     LOCAL_UPNP,
     // address explicitly specified (-externalip=)
     LOCAL_MANUAL,
 
     LOCAL_MAX
 };
 
 bool IsPeerAddrLocalGood(CNode *pnode);
 void AdvertiseLocal(CNode *pnode);
 void SetLimited(enum Network net, bool fLimited = true);
 bool IsLimited(enum Network net);
 bool IsLimited(const CNetAddr &addr);
 bool AddLocal(const CService &addr, int nScore = LOCAL_NONE);
 bool AddLocal(const CNetAddr &addr, int nScore = LOCAL_NONE);
 bool RemoveLocal(const CService &addr);
 bool SeenLocal(const CService &addr);
 bool IsLocal(const CService &addr);
 bool GetLocal(CService &addr, const CNetAddr *paddrPeer = nullptr);
 bool IsReachable(enum Network net);
 bool IsReachable(const CNetAddr &addr);
 CAddress GetLocalAddress(const CNetAddr *paddrPeer,
                          ServiceFlags nLocalServices);
 
 extern bool fDiscover;
 extern bool fListen;
 extern bool fRelayTxes;
 
 extern limitedmap<uint256, int64_t> mapAlreadyAskedFor;
 
 struct LocalServiceInfo {
     int nScore;
     int nPort;
 };
 
 extern CCriticalSection cs_mapLocalHost;
 extern std::map<CNetAddr, LocalServiceInfo> mapLocalHost;
 
 // Command, total bytes
 typedef std::map<std::string, uint64_t> mapMsgCmdSize;
 
 class CNodeStats {
 public:
     NodeId nodeid;
     ServiceFlags nServices;
     bool fRelayTxes;
     int64_t nLastSend;
     int64_t nLastRecv;
     int64_t nTimeConnected;
     int64_t nTimeOffset;
     std::string addrName;
     int nVersion;
     std::string cleanSubVer;
     bool fInbound;
     bool fAddnode;
     int nStartingHeight;
     uint64_t nSendBytes;
     mapMsgCmdSize mapSendBytesPerMsgCmd;
     uint64_t nRecvBytes;
     mapMsgCmdSize mapRecvBytesPerMsgCmd;
     bool fWhitelisted;
     double dPingTime;
     double dPingWait;
     double dMinPing;
     std::string addrLocal;
     CAddress addr;
 };
 
 class CNetMessage {
 private:
     mutable CHash256 hasher;
     mutable uint256 data_hash;
 
 public:
     // Parsing header (false) or data (true)
     bool in_data;
 
     // Partially received header.
     CDataStream hdrbuf;
     // Complete header.
     CMessageHeader hdr;
     unsigned int nHdrPos;
 
     // Received message data.
     CDataStream vRecv;
     unsigned int nDataPos;
 
     // Time (in microseconds) of message receipt.
     int64_t nTime;
 
     CNetMessage(const CMessageHeader::MessageStartChars &pchMessageStartIn,
                 int nTypeIn, int nVersionIn)
         : hdrbuf(nTypeIn, nVersionIn), hdr(pchMessageStartIn),
           vRecv(nTypeIn, nVersionIn) {
         hdrbuf.resize(24);
         in_data = false;
         nHdrPos = 0;
         nDataPos = 0;
         nTime = 0;
     }
 
     bool complete() const {
         if (!in_data) {
             return false;
         }
 
         return (hdr.nMessageSize == nDataPos);
     }
 
     const uint256 &GetMessageHash() const;
 
     void SetVersion(int nVersionIn) {
         hdrbuf.SetVersion(nVersionIn);
         vRecv.SetVersion(nVersionIn);
     }
 
     int readHeader(const char *pch, unsigned int nBytes);
     int readData(const char *pch, unsigned int nBytes);
 };
 
 /** Information about a peer */
 class CNode {
     friend class CConnman;
 
 public:
     // socket
     std::atomic<ServiceFlags> nServices;
     ServiceFlags nServicesExpected;
     SOCKET hSocket;
     // Total size of all vSendMsg entries.
     size_t nSendSize;
     // Offset inside the first vSendMsg already sent.
     size_t nSendOffset;
     uint64_t nSendBytes;
-    std::deque<std::vector<unsigned char>> vSendMsg;
+    std::deque<std::vector<uint8_t>> vSendMsg;
     CCriticalSection cs_vSend;
     CCriticalSection cs_hSocket;
     CCriticalSection cs_vRecv;
 
     CCriticalSection cs_vProcessMsg;
     std::list<CNetMessage> vProcessMsg;
     size_t nProcessQueueSize;
 
     CCriticalSection cs_sendProcessing;
 
     std::deque<CInv> vRecvGetData;
     uint64_t nRecvBytes;
     std::atomic<int> nRecvVersion;
 
     std::atomic<int64_t> nLastSend;
     std::atomic<int64_t> nLastRecv;
     const int64_t nTimeConnected;
     std::atomic<int64_t> nTimeOffset;
     const CAddress addr;
     std::atomic<int> nVersion;
     // strSubVer is whatever byte array we read from the wire. However, this
     // field is intended to be printed out, displayed to humans in various forms
     // and so on. So we sanitize it and store the sanitized version in
     // cleanSubVer. The original should be used when dealing with the network or
     // wire types and the cleaned string used when displayed or logged.
     std::string strSubVer, cleanSubVer;
     // Used for both cleanSubVer and strSubVer.
     CCriticalSection cs_SubVer;
     // This peer can bypass DoS banning.
     bool fWhitelisted;
     // If true this node is being used as a short lived feeler.
     bool fFeeler;
     bool fOneShot;
     bool fAddnode;
     bool fClient;
     const bool fInbound;
     std::atomic_bool fSuccessfullyConnected;
     std::atomic_bool fDisconnect;
     // We use fRelayTxes for two purposes -
     // a) it allows us to not relay tx invs before receiving the peer's version
     // message.
     // b) the peer may tell us in its version message that we should not relay
     // tx invs unless it loads a bloom filter.
 
     // protected by cs_filter
     bool fRelayTxes;
     bool fSentAddr;
     CSemaphoreGrant grantOutbound;
     CCriticalSection cs_filter;
     CBloomFilter *pfilter;
     std::atomic<int> nRefCount;
     const NodeId id;
 
     const uint64_t nKeyedNetGroup;
     std::atomic_bool fPauseRecv;
     std::atomic_bool fPauseSend;
 
 protected:
     mapMsgCmdSize mapSendBytesPerMsgCmd;
     mapMsgCmdSize mapRecvBytesPerMsgCmd;
 
 public:
     uint256 hashContinue;
     std::atomic<int> nStartingHeight;
 
     // flood relay
     std::vector<CAddress> vAddrToSend;
     CRollingBloomFilter addrKnown;
     bool fGetAddr;
     std::set<uint256> setKnown;
     int64_t nNextAddrSend;
     int64_t nNextLocalAddrSend;
 
     // Inventory based relay.
     CRollingBloomFilter filterInventoryKnown;
     // Set of transaction ids we still have to announce. They are sorted by the
     // mempool before relay, so the order is not important.
     std::set<uint256> setInventoryTxToSend;
     // List of block ids we still have announce. There is no final sorting
     // before sending, as they are always sent immediately and in the order
     // requested.
     std::vector<uint256> vInventoryBlockToSend;
     CCriticalSection cs_inventory;
     std::set<uint256> setAskFor;
     std::multimap<int64_t, CInv> mapAskFor;
     int64_t nNextInvSend;
     // Used for headers announcements - unfiltered blocks to relay. Also
     // protected by cs_inventory.
     std::vector<uint256> vBlockHashesToAnnounce;
     // Used for BIP35 mempool sending, also protected by cs_inventory.
     bool fSendMempool;
 
     // Last time a "MEMPOOL" request was serviced.
     std::atomic<int64_t> timeLastMempoolReq;
 
     // Block and TXN accept times
     std::atomic<int64_t> nLastBlockTime;
     std::atomic<int64_t> nLastTXTime;
 
     // Ping time measurement:
     // The pong reply we're expecting, or 0 if no pong expected.
     std::atomic<uint64_t> nPingNonceSent;
     // Time (in usec) the last ping was sent, or 0 if no ping was ever sent.
     std::atomic<int64_t> nPingUsecStart;
     // Last measured round-trip time.
     std::atomic<int64_t> nPingUsecTime;
     // Best measured round-trip time.
     std::atomic<int64_t> nMinPingUsecTime;
     // Whether a ping is requested.
     std::atomic<bool> fPingQueued;
     // Whether the node uses the bitcoin cash magic to communicate.
     std::atomic<bool> fUsesCashMagic;
     // Minimum fee rate with which to filter inv's to this node
     CAmount minFeeFilter;
     CCriticalSection cs_feeFilter;
     CAmount lastSentFeeFilter;
     int64_t nextSendTimeFeeFilter;
 
     CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn,
           SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn,
           uint64_t nLocalHostNonceIn, const std::string &addrNameIn = "",
           bool fInboundIn = false);
     ~CNode();
 
 private:
     CNode(const CNode &);
     void operator=(const CNode &);
 
     const uint64_t nLocalHostNonce;
     // Services offered to this peer
     const ServiceFlags nLocalServices;
     const int nMyStartingHeight;
     int nSendVersion;
     // Used only by SocketHandler thread.
     std::list<CNetMessage> vRecvMsg;
 
     mutable CCriticalSection cs_addrName;
     std::string addrName;
 
     CService addrLocal;
     mutable CCriticalSection cs_addrLocal;
 
 public:
     NodeId GetId() const { return id; }
 
     uint64_t GetLocalNonce() const { return nLocalHostNonce; }
 
     int GetMyStartingHeight() const { return nMyStartingHeight; }
 
     int GetRefCount() {
         assert(nRefCount >= 0);
         return nRefCount;
     }
 
     bool ReceiveMsgBytes(const char *pch, unsigned int nBytes, bool &complete);
 
     void SetRecvVersion(int nVersionIn) { nRecvVersion = nVersionIn; }
     int GetRecvVersion() { return nRecvVersion; }
     void SetSendVersion(int nVersionIn);
     int GetSendVersion() const;
 
     const CMessageHeader::MessageStartChars &
     GetMagic(const CChainParams &params) const {
         return fUsesCashMagic ? params.CashMessageStart()
                               : params.MessageStart();
     }
 
     CService GetAddrLocal() const;
     //! May not be called more than once
     void SetAddrLocal(const CService &addrLocalIn);
 
     CNode *AddRef() {
         nRefCount++;
         return this;
     }
 
     void Release() { nRefCount--; }
 
     void AddAddressKnown(const CAddress &_addr) {
         addrKnown.insert(_addr.GetKey());
     }
 
     void PushAddress(const CAddress &_addr, FastRandomContext &insecure_rand) {
         // Known checking here is only to save space from duplicates.
         // SendMessages will filter it again for knowns that were added
         // after addresses were pushed.
         if (_addr.IsValid() && !addrKnown.contains(_addr.GetKey())) {
             if (vAddrToSend.size() >= MAX_ADDR_TO_SEND) {
                 vAddrToSend[insecure_rand.rand32() % vAddrToSend.size()] =
                     _addr;
             } else {
                 vAddrToSend.push_back(_addr);
             }
         }
     }
 
     void AddInventoryKnown(const CInv &inv) {
         LOCK(cs_inventory);
         filterInventoryKnown.insert(inv.hash);
     }
 
     void PushInventory(const CInv &inv) {
         LOCK(cs_inventory);
         if (inv.type == MSG_TX) {
             if (!filterInventoryKnown.contains(inv.hash)) {
                 setInventoryTxToSend.insert(inv.hash);
             }
         } else if (inv.type == MSG_BLOCK) {
             vInventoryBlockToSend.push_back(inv.hash);
         }
     }
 
     void PushBlockHash(const uint256 &hash) {
         LOCK(cs_inventory);
         vBlockHashesToAnnounce.push_back(hash);
     }
 
     void AskFor(const CInv &inv);
 
     void CloseSocketDisconnect();
 
     void copyStats(CNodeStats &stats);
 
     ServiceFlags GetLocalServices() const { return nLocalServices; }
 
     std::string GetAddrName() const;
     //! Sets the addrName only if it was not previously set
     void MaybeSetAddrName(const std::string &addrNameIn);
 };
 
 /**
  * Return a timestamp in the future (in microseconds) for exponentially
  * distributed events.
  */
 int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds);
 
 std::string getSubVersionEB(uint64_t MaxBlockSize);
 std::string userAgent(const Config &config);
 #endif // BITCOIN_NET_H
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index 48606c48b..c3fbc5014 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -1,3847 +1,3847 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #include "net_processing.h"
 
 #include "addrman.h"
 #include "arith_uint256.h"
 #include "blockencodings.h"
 #include "chainparams.h"
 #include "config.h"
 #include "consensus/validation.h"
 #include "hash.h"
 #include "init.h"
 #include "merkleblock.h"
 #include "net.h"
 #include "netbase.h"
 #include "netmessagemaker.h"
 #include "policy/fees.h"
 #include "policy/policy.h"
 #include "primitives/block.h"
 #include "primitives/transaction.h"
 #include "random.h"
 #include "tinyformat.h"
 #include "txmempool.h"
 #include "ui_interface.h"
 #include "util.h"
 #include "utilmoneystr.h"
 #include "utilstrencodings.h"
 #include "validation.h"
 #include "validationinterface.h"
 
 #include <boost/range/adaptor/reversed.hpp>
 #include <boost/thread.hpp>
 
 #if defined(NDEBUG)
 #error "Bitcoin cannot be compiled without assertions."
 #endif
 
 // Used only to inform the wallet of when we last received a block.
 std::atomic<int64_t> nTimeBestReceived(0);
 
 struct IteratorComparator {
     template <typename I> bool operator()(const I &a, const I &b) {
         return &(*a) < &(*b);
     }
 };
 
 struct COrphanTx {
     // When modifying, adapt the copy of this definition in tests/DoS_tests.
     CTransactionRef tx;
     NodeId fromPeer;
     int64_t nTimeExpire;
 };
 std::map<uint256, COrphanTx> mapOrphanTransactions GUARDED_BY(cs_main);
 std::map<COutPoint,
          std::set<std::map<uint256, COrphanTx>::iterator, IteratorComparator>>
     mapOrphanTransactionsByPrev GUARDED_BY(cs_main);
 void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
 
 static size_t vExtraTxnForCompactIt = 0;
 static std::vector<std::pair<uint256, CTransactionRef>>
     vExtraTxnForCompact GUARDED_BY(cs_main);
 
 // SHA256("main address relay")[0:8]
 static const uint64_t RANDOMIZER_ID_ADDRESS_RELAY = 0x3cac0035b5866b90ULL;
 
 // Internal stuff
 namespace {
 /** Number of nodes with fSyncStarted. */
 int nSyncStarted = 0;
 
 /**
  * Sources of received blocks, saved to be able to send them reject messages or
  * ban them when processing happens afterwards. Protected by cs_main.
  * Set mapBlockSource[hash].second to false if the node should not be punished
  * if the block is invalid.
  */
 std::map<uint256, std::pair<NodeId, bool>> mapBlockSource;
 
 /**
  * Filter for transactions that were recently rejected by AcceptToMemoryPool.
  * These are not rerequested until the chain tip changes, at which point the
  * entire filter is reset. Protected by cs_main.
  *
  * Without this filter we'd be re-requesting txs from each of our peers,
  * increasing bandwidth consumption considerably. For instance, with 100 peers,
  * half of which relay a tx we don't accept, that might be a 50x bandwidth
  * increase. A flooding attacker attempting to roll-over the filter using
  * minimum-sized, 60byte, transactions might manage to send 1000/sec if we have
  * fast peers, so we pick 120,000 to give our peers a two minute window to send
  * invs to us.
  *
  * Decreasing the false positive rate is fairly cheap, so we pick one in a
  * million to make it highly unlikely for users to have issues with this filter.
  *
  * Memory used: 1.3 MB
  */
 std::unique_ptr<CRollingBloomFilter> recentRejects;
 uint256 hashRecentRejectsChainTip;
 
 /** Blocks that are in flight, and that are in the queue to be downloaded.
  * Protected by cs_main. */
 struct QueuedBlock {
     uint256 hash;
     //!< Optional.
     const CBlockIndex *pindex;
     //!< Whether this block has validated headers at the time of request.
     bool fValidatedHeaders;
     //!< Optional, used for CMPCTBLOCK downloads
     std::unique_ptr<PartiallyDownloadedBlock> partialBlock;
 };
 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator>>
     mapBlocksInFlight;
 
 /** Stack of nodes which we have set to announce using compact blocks */
 std::list<NodeId> lNodesAnnouncingHeaderAndIDs;
 
 /** Number of preferable block download peers. */
 int nPreferredDownload = 0;
 
 /** Number of peers from which we're downloading blocks. */
 int nPeersWithValidatedDownloads = 0;
 
 /** Relay map, protected by cs_main. */
 typedef std::map<uint256, CTransactionRef> MapRelay;
 MapRelay mapRelay;
 /** Expiration-time ordered list of (expire time, relay map entry) pairs,
  * protected by cs_main). */
 std::deque<std::pair<int64_t, MapRelay::iterator>> vRelayExpiration;
 } // anon namespace
 
 //////////////////////////////////////////////////////////////////////////////
 //
 // Registration of network node signals.
 //
 
 namespace {
 
 struct CBlockReject {
-    unsigned char chRejectCode;
+    uint8_t chRejectCode;
     std::string strRejectReason;
     uint256 hashBlock;
 };
 
 /**
  * Maintain validation-specific state about nodes, protected by cs_main, instead
  * by CNode's own locks. This simplifies asynchronous operation, where
  * processing of incoming data is done after the ProcessMessage call returns,
  * and we're no longer holding the node's locks.
  */
 struct CNodeState {
     //! The peer's address
     const CService address;
     //! Whether we have a fully established connection.
     bool fCurrentlyConnected;
     //! Accumulated misbehaviour score for this peer.
     int nMisbehavior;
     //! Whether this peer should be disconnected and banned (unless
     //! whitelisted).
     bool fShouldBan;
     //! String name of this peer (debugging/logging purposes).
     const std::string name;
     //! List of asynchronously-determined block rejections to notify this peer
     //! about.
     std::vector<CBlockReject> rejects;
     //! The best known block we know this peer has announced.
     const CBlockIndex *pindexBestKnownBlock;
     //! The hash of the last unknown block this peer has announced.
     uint256 hashLastUnknownBlock;
     //! The last full block we both have.
     const CBlockIndex *pindexLastCommonBlock;
     //! The best header we have sent our peer.
     const CBlockIndex *pindexBestHeaderSent;
     //! Length of current-streak of unconnecting headers announcements
     int nUnconnectingHeaders;
     //! Whether we've started headers synchronization with this peer.
     bool fSyncStarted;
     //! Since when we're stalling block download progress (in microseconds), or
     //! 0.
     int64_t nStallingSince;
     std::list<QueuedBlock> vBlocksInFlight;
     //! When the first entry in vBlocksInFlight started downloading. Don't care
     //! when vBlocksInFlight is empty.
     int64_t nDownloadingSince;
     int nBlocksInFlight;
     int nBlocksInFlightValidHeaders;
     //! Whether we consider this a preferred download peer.
     bool fPreferredDownload;
     //! Whether this peer wants invs or headers (when possible) for block
     //! announcements.
     bool fPreferHeaders;
     //! Whether this peer wants invs or cmpctblocks (when possible) for block
     //! announcements.
     bool fPreferHeaderAndIDs;
     /**
      * Whether this peer will send us cmpctblocks if we request them.
      * This is not used to gate request logic, as we really only care about
      * fSupportsDesiredCmpctVersion, but is used as a flag to "lock in" the
      * version of compact blocks we send.
      */
     bool fProvidesHeaderAndIDs;
     /**
      * If we've announced NODE_WITNESS to this peer: whether the peer sends
      * witnesses in cmpctblocks/blocktxns, otherwise: whether this peer sends
      * non-witnesses in cmpctblocks/blocktxns.
      */
     bool fSupportsDesiredCmpctVersion;
 
     CNodeState(CAddress addrIn, std::string addrNameIn)
         : address(addrIn), name(addrNameIn) {
         fCurrentlyConnected = false;
         nMisbehavior = 0;
         fShouldBan = false;
         pindexBestKnownBlock = nullptr;
         hashLastUnknownBlock.SetNull();
         pindexLastCommonBlock = nullptr;
         pindexBestHeaderSent = nullptr;
         nUnconnectingHeaders = 0;
         fSyncStarted = false;
         nStallingSince = 0;
         nDownloadingSince = 0;
         nBlocksInFlight = 0;
         nBlocksInFlightValidHeaders = 0;
         fPreferredDownload = false;
         fPreferHeaders = false;
         fPreferHeaderAndIDs = false;
         fProvidesHeaderAndIDs = false;
         fSupportsDesiredCmpctVersion = false;
     }
 };
 
 /** Map maintaining per-node state. Requires cs_main. */
 std::map<NodeId, CNodeState> mapNodeState;
 
 // Requires cs_main.
 CNodeState *State(NodeId pnode) {
     std::map<NodeId, CNodeState>::iterator it = mapNodeState.find(pnode);
     if (it == mapNodeState.end()) {
         return nullptr;
     }
 
     return &it->second;
 }
 
 void UpdatePreferredDownload(CNode *node, CNodeState *state) {
     nPreferredDownload -= state->fPreferredDownload;
 
     // Whether this node should be marked as a preferred download node.
     state->fPreferredDownload = (!node->fInbound || node->fWhitelisted) &&
                                 !node->fOneShot && !node->fClient;
 
     nPreferredDownload += state->fPreferredDownload;
 }
 
 void PushNodeVersion(const Config &config, CNode *pnode, CConnman &connman,
                      int64_t nTime) {
     ServiceFlags nLocalNodeServices = pnode->GetLocalServices();
     uint64_t nonce = pnode->GetLocalNonce();
     int nNodeStartingHeight = pnode->GetMyStartingHeight();
     NodeId nodeid = pnode->GetId();
     CAddress addr = pnode->addr;
 
     CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr)
                             ? addr
                             : CAddress(CService(), addr.nServices));
     CAddress addrMe = CAddress(CService(), nLocalNodeServices);
 
     connman.PushMessage(pnode,
                         CNetMsgMaker(INIT_PROTO_VERSION)
                             .Make(NetMsgType::VERSION, PROTOCOL_VERSION,
                                   (uint64_t)nLocalNodeServices, nTime, addrYou,
                                   addrMe, nonce, userAgent(config),
                                   nNodeStartingHeight, ::fRelayTxes));
 
     if (fLogIPs) {
         LogPrint("net", "send version message: version %d, blocks=%d, us=%s, "
                         "them=%s, peer=%d\n",
                  PROTOCOL_VERSION, nNodeStartingHeight, addrMe.ToString(),
                  addrYou.ToString(), nodeid);
     } else {
         LogPrint(
             "net",
             "send version message: version %d, blocks=%d, us=%s, peer=%d\n",
             PROTOCOL_VERSION, nNodeStartingHeight, addrMe.ToString(), nodeid);
     }
 }
 
 void InitializeNode(const Config &config, CNode *pnode, CConnman &connman) {
     CAddress addr = pnode->addr;
     std::string addrName = pnode->GetAddrName();
     NodeId nodeid = pnode->GetId();
     {
         LOCK(cs_main);
         mapNodeState.emplace_hint(
             mapNodeState.end(), std::piecewise_construct,
             std::forward_as_tuple(nodeid),
             std::forward_as_tuple(addr, std::move(addrName)));
     }
 
     if (!pnode->fInbound) {
         PushNodeVersion(config, pnode, connman, GetTime());
     }
 }
 
 void FinalizeNode(NodeId nodeid, bool &fUpdateConnectionTime) {
     fUpdateConnectionTime = false;
     LOCK(cs_main);
     CNodeState *state = State(nodeid);
 
     if (state->fSyncStarted) {
         nSyncStarted--;
     }
 
     if (state->nMisbehavior == 0 && state->fCurrentlyConnected) {
         fUpdateConnectionTime = true;
     }
 
     for (const QueuedBlock &entry : state->vBlocksInFlight) {
         mapBlocksInFlight.erase(entry.hash);
     }
     // Get rid of stale mapBlockSource entries for this peer as they may leak
     // if we don't clean them up (I saw on the order of ~100 stale entries on
     // a full resynch in my testing -- these entries stay forever).
     // Performance note: most of the time mapBlockSource has 0 or 1 entries.
     // During synch of blockchain it may end up with as many as 1000 entries,
     // which still only takes ~1ms to iterate through on even old hardware.
     // So this memleak cleanup is not expensive and worth doing since even
     // small leaks are bad. :)
     for (auto it = mapBlockSource.begin(); it != mapBlockSource.end(); /*NA*/) {
         if (it->second.first == nodeid) {
             mapBlockSource.erase(it++);
         } else {
             ++it;
         }
     }
 
     EraseOrphansFor(nodeid);
     nPreferredDownload -= state->fPreferredDownload;
     nPeersWithValidatedDownloads -= (state->nBlocksInFlightValidHeaders != 0);
     assert(nPeersWithValidatedDownloads >= 0);
 
     mapNodeState.erase(nodeid);
 
     if (mapNodeState.empty()) {
         // Do a consistency check after the last peer is removed.
         assert(mapBlocksInFlight.empty());
         assert(nPreferredDownload == 0);
         assert(nPeersWithValidatedDownloads == 0);
     }
 }
 
 // Requires cs_main.
 // Returns a bool indicating whether we requested this block.
 // Also used if a block was /not/ received and timed out or started with another
 // peer.
 bool MarkBlockAsReceived(const uint256 &hash) {
     std::map<uint256,
              std::pair<NodeId, std::list<QueuedBlock>::iterator>>::iterator
         itInFlight = mapBlocksInFlight.find(hash);
     if (itInFlight != mapBlocksInFlight.end()) {
         CNodeState *state = State(itInFlight->second.first);
         state->nBlocksInFlightValidHeaders -=
             itInFlight->second.second->fValidatedHeaders;
         if (state->nBlocksInFlightValidHeaders == 0 &&
             itInFlight->second.second->fValidatedHeaders) {
             // Last validated block on the queue was received.
             nPeersWithValidatedDownloads--;
         }
         if (state->vBlocksInFlight.begin() == itInFlight->second.second) {
             // First block on the queue was received, update the start download
             // time for the next one
             state->nDownloadingSince =
                 std::max(state->nDownloadingSince, GetTimeMicros());
         }
         state->vBlocksInFlight.erase(itInFlight->second.second);
         state->nBlocksInFlight--;
         state->nStallingSince = 0;
         mapBlocksInFlight.erase(itInFlight);
         return true;
     }
 
     return false;
 }
 
 // Requires cs_main.
 // returns false, still setting pit, if the block was already in flight from the
 // same peer pit will only be valid as long as the same cs_main lock is being
 // held.
 static bool
 MarkBlockAsInFlight(const Config &config, NodeId nodeid, const uint256 &hash,
                     const Consensus::Params &consensusParams,
                     const CBlockIndex *pindex = nullptr,
                     std::list<QueuedBlock>::iterator **pit = nullptr) {
     CNodeState *state = State(nodeid);
     assert(state != nullptr);
 
     // Short-circuit most stuff in case its from the same node.
     std::map<uint256,
              std::pair<NodeId, std::list<QueuedBlock>::iterator>>::iterator
         itInFlight = mapBlocksInFlight.find(hash);
     if (itInFlight != mapBlocksInFlight.end() &&
         itInFlight->second.first == nodeid) {
         *pit = &itInFlight->second.second;
         return false;
     }
 
     // Make sure it's not listed somewhere already.
     MarkBlockAsReceived(hash);
 
     std::list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(
         state->vBlocksInFlight.end(),
         {hash, pindex, pindex != nullptr,
          std::unique_ptr<PartiallyDownloadedBlock>(
              pit ? new PartiallyDownloadedBlock(config, &mempool) : nullptr)});
     state->nBlocksInFlight++;
     state->nBlocksInFlightValidHeaders += it->fValidatedHeaders;
     if (state->nBlocksInFlight == 1) {
         // We're starting a block download (batch) from this peer.
         state->nDownloadingSince = GetTimeMicros();
     }
 
     if (state->nBlocksInFlightValidHeaders == 1 && pindex != nullptr) {
         nPeersWithValidatedDownloads++;
     }
 
     itInFlight = mapBlocksInFlight
                      .insert(std::make_pair(hash, std::make_pair(nodeid, it)))
                      .first;
 
     if (pit) {
         *pit = &itInFlight->second.second;
     }
 
     return true;
 }
 
 /** Check whether the last unknown block a peer advertised is not yet known. */
 void ProcessBlockAvailability(NodeId nodeid) {
     CNodeState *state = State(nodeid);
     assert(state != nullptr);
 
     if (!state->hashLastUnknownBlock.IsNull()) {
         BlockMap::iterator itOld =
             mapBlockIndex.find(state->hashLastUnknownBlock);
         if (itOld != mapBlockIndex.end() && itOld->second->nChainWork > 0) {
             if (state->pindexBestKnownBlock == nullptr ||
                 itOld->second->nChainWork >=
                     state->pindexBestKnownBlock->nChainWork) {
                 state->pindexBestKnownBlock = itOld->second;
             }
             state->hashLastUnknownBlock.SetNull();
         }
     }
 }
 
 /** Update tracking information about which blocks a peer is assumed to have. */
 void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) {
     CNodeState *state = State(nodeid);
     assert(state != nullptr);
 
     ProcessBlockAvailability(nodeid);
 
     BlockMap::iterator it = mapBlockIndex.find(hash);
     if (it != mapBlockIndex.end() && it->second->nChainWork > 0) {
         // An actually better block was announced.
         if (state->pindexBestKnownBlock == nullptr ||
             it->second->nChainWork >= state->pindexBestKnownBlock->nChainWork) {
             state->pindexBestKnownBlock = it->second;
         }
     } else {
         // An unknown block was announced; just assume that the latest one is
         // the best one.
         state->hashLastUnknownBlock = hash;
     }
 }
 
 void MaybeSetPeerAsAnnouncingHeaderAndIDs(NodeId nodeid, CConnman &connman) {
     AssertLockHeld(cs_main);
     CNodeState *nodestate = State(nodeid);
     if (!nodestate) {
         LogPrint("net", "node state unavailable: peer=%d\n", nodeid);
         return;
     }
     if (!nodestate->fProvidesHeaderAndIDs) {
         return;
     }
     for (std::list<NodeId>::iterator it = lNodesAnnouncingHeaderAndIDs.begin();
          it != lNodesAnnouncingHeaderAndIDs.end(); it++) {
         if (*it == nodeid) {
             lNodesAnnouncingHeaderAndIDs.erase(it);
             lNodesAnnouncingHeaderAndIDs.push_back(nodeid);
             return;
         }
     }
     connman.ForNode(nodeid, [&connman](CNode *pfrom) {
         bool fAnnounceUsingCMPCTBLOCK = false;
         uint64_t nCMPCTBLOCKVersion = 1;
         if (lNodesAnnouncingHeaderAndIDs.size() >= 3) {
             // As per BIP152, we only get 3 of our peers to announce
             // blocks using compact encodings.
             connman.ForNode(lNodesAnnouncingHeaderAndIDs.front(),
                             [&connman, fAnnounceUsingCMPCTBLOCK,
                              nCMPCTBLOCKVersion](CNode *pnodeStop) {
                                 connman.PushMessage(
                                     pnodeStop,
                                     CNetMsgMaker(pnodeStop->GetSendVersion())
                                         .Make(NetMsgType::SENDCMPCT,
                                               fAnnounceUsingCMPCTBLOCK,
                                               nCMPCTBLOCKVersion));
                                 return true;
                             });
             lNodesAnnouncingHeaderAndIDs.pop_front();
         }
         fAnnounceUsingCMPCTBLOCK = true;
         connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion())
                                        .Make(NetMsgType::SENDCMPCT,
                                              fAnnounceUsingCMPCTBLOCK,
                                              nCMPCTBLOCKVersion));
         lNodesAnnouncingHeaderAndIDs.push_back(pfrom->GetId());
         return true;
     });
 }
 
 // Requires cs_main
 bool CanDirectFetch(const Consensus::Params &consensusParams) {
     return chainActive.Tip()->GetBlockTime() >
            GetAdjustedTime() - consensusParams.nPowTargetSpacing * 20;
 }
 
 // Requires cs_main
 bool PeerHasHeader(CNodeState *state, const CBlockIndex *pindex) {
     if (state->pindexBestKnownBlock &&
         pindex == state->pindexBestKnownBlock->GetAncestor(pindex->nHeight)) {
         return true;
     }
     if (state->pindexBestHeaderSent &&
         pindex == state->pindexBestHeaderSent->GetAncestor(pindex->nHeight)) {
         return true;
     }
     return false;
 }
 
 /**
  * Find the last common ancestor two blocks have.
  * Both pa and pb must be non null.
  */
 const CBlockIndex *LastCommonAncestor(const CBlockIndex *pa,
                                       const CBlockIndex *pb) {
     if (pa->nHeight > pb->nHeight) {
         pa = pa->GetAncestor(pb->nHeight);
     } else if (pb->nHeight > pa->nHeight) {
         pb = pb->GetAncestor(pa->nHeight);
     }
 
     while (pa != pb && pa && pb) {
         pa = pa->pprev;
         pb = pb->pprev;
     }
 
     // Eventually all chain branches meet at the genesis block.
     assert(pa == pb);
     return pa;
 }
 
 /** Update pindexLastCommonBlock and add not-in-flight missing successors to
  * vBlocks, until it has at most count entries. */
 void FindNextBlocksToDownload(NodeId nodeid, unsigned int count,
                               std::vector<const CBlockIndex *> &vBlocks,
                               NodeId &nodeStaller,
                               const Consensus::Params &consensusParams) {
     if (count == 0) {
         return;
     }
 
     vBlocks.reserve(vBlocks.size() + count);
     CNodeState *state = State(nodeid);
     assert(state != nullptr);
 
     // Make sure pindexBestKnownBlock is up to date, we'll need it.
     ProcessBlockAvailability(nodeid);
 
     if (state->pindexBestKnownBlock == nullptr ||
         state->pindexBestKnownBlock->nChainWork <
             chainActive.Tip()->nChainWork) {
         // This peer has nothing interesting.
         return;
     }
 
     if (state->pindexLastCommonBlock == nullptr) {
         // Bootstrap quickly by guessing a parent of our best tip is the forking
         // point. Guessing wrong in either direction is not a problem.
         state->pindexLastCommonBlock = chainActive[std::min(
             state->pindexBestKnownBlock->nHeight, chainActive.Height())];
     }
 
     // If the peer reorganized, our previous pindexLastCommonBlock may not be an
     // ancestor of its current tip anymore. Go back enough to fix that.
     state->pindexLastCommonBlock = LastCommonAncestor(
         state->pindexLastCommonBlock, state->pindexBestKnownBlock);
     if (state->pindexLastCommonBlock == state->pindexBestKnownBlock) {
         return;
     }
 
     std::vector<const CBlockIndex *> vToFetch;
     const CBlockIndex *pindexWalk = state->pindexLastCommonBlock;
     // Never fetch further than the best block we know the peer has, or more
     // than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last linked block we have in
     // common with this peer. The +1 is so we can detect stalling, namely if we
     // would be able to download that next block if the window were 1 larger.
     int nWindowEnd =
         state->pindexLastCommonBlock->nHeight + BLOCK_DOWNLOAD_WINDOW;
     int nMaxHeight =
         std::min<int>(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1);
     NodeId waitingfor = -1;
     while (pindexWalk->nHeight < nMaxHeight) {
         // Read up to 128 (or more, if more blocks than that are needed)
         // successors of pindexWalk (towards pindexBestKnownBlock) into
         // vToFetch. We fetch 128, because CBlockIndex::GetAncestor may be as
         // expensive as iterating over ~100 CBlockIndex* entries anyway.
         int nToFetch = std::min(nMaxHeight - pindexWalk->nHeight,
                                 std::max<int>(count - vBlocks.size(), 128));
         vToFetch.resize(nToFetch);
         pindexWalk = state->pindexBestKnownBlock->GetAncestor(
             pindexWalk->nHeight + nToFetch);
         vToFetch[nToFetch - 1] = pindexWalk;
         for (unsigned int i = nToFetch - 1; i > 0; i--) {
             vToFetch[i - 1] = vToFetch[i]->pprev;
         }
 
         // Iterate over those blocks in vToFetch (in forward direction), adding
         // the ones that are not yet downloaded and not in flight to vBlocks. In
         // the mean time, update pindexLastCommonBlock as long as all ancestors
         // are already downloaded, or if it's already part of our chain (and
         // therefore don't need it even if pruned).
         for (const CBlockIndex *pindex : vToFetch) {
             if (!pindex->IsValid(BLOCK_VALID_TREE)) {
                 // We consider the chain that this peer is on invalid.
                 return;
             }
             if (pindex->nStatus & BLOCK_HAVE_DATA ||
                 chainActive.Contains(pindex)) {
                 if (pindex->nChainTx) {
                     state->pindexLastCommonBlock = pindex;
                 }
             } else if (mapBlocksInFlight.count(pindex->GetBlockHash()) == 0) {
                 // The block is not already downloaded, and not yet in flight.
                 if (pindex->nHeight > nWindowEnd) {
                     // We reached the end of the window.
                     if (vBlocks.size() == 0 && waitingfor != nodeid) {
                         // We aren't able to fetch anything, but we would be if
                         // the download window was one larger.
                         nodeStaller = waitingfor;
                     }
                     return;
                 }
                 vBlocks.push_back(pindex);
                 if (vBlocks.size() == count) {
                     return;
                 }
             } else if (waitingfor == -1) {
                 // This is the first already-in-flight block.
                 waitingfor = mapBlocksInFlight[pindex->GetBlockHash()].first;
             }
         }
     }
 }
 
 } // anon namespace
 
 bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) {
     LOCK(cs_main);
     CNodeState *state = State(nodeid);
     if (state == nullptr) {
         return false;
     }
     stats.nMisbehavior = state->nMisbehavior;
     stats.nSyncHeight =
         state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1;
     stats.nCommonHeight = state->pindexLastCommonBlock
                               ? state->pindexLastCommonBlock->nHeight
                               : -1;
     for (const QueuedBlock &queue : state->vBlocksInFlight) {
         if (queue.pindex) {
             stats.vHeightInFlight.push_back(queue.pindex->nHeight);
         }
     }
     return true;
 }
 
 void RegisterNodeSignals(CNodeSignals &nodeSignals) {
     nodeSignals.ProcessMessages.connect(&ProcessMessages);
     nodeSignals.SendMessages.connect(&SendMessages);
     nodeSignals.InitializeNode.connect(&InitializeNode);
     nodeSignals.FinalizeNode.connect(&FinalizeNode);
 }
 
 void UnregisterNodeSignals(CNodeSignals &nodeSignals) {
     nodeSignals.ProcessMessages.disconnect(&ProcessMessages);
     nodeSignals.SendMessages.disconnect(&SendMessages);
     nodeSignals.InitializeNode.disconnect(&InitializeNode);
     nodeSignals.FinalizeNode.disconnect(&FinalizeNode);
 }
 
 //////////////////////////////////////////////////////////////////////////////
 //
 // mapOrphanTransactions
 //
 
 void AddToCompactExtraTransactions(const CTransactionRef &tx) {
     size_t max_extra_txn = GetArg("-blockreconstructionextratxn",
                                   DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN);
     if (max_extra_txn <= 0) {
         return;
     }
 
     if (!vExtraTxnForCompact.size()) {
         vExtraTxnForCompact.resize(max_extra_txn);
     }
 
     vExtraTxnForCompact[vExtraTxnForCompactIt] =
         std::make_pair(tx->GetHash(), tx);
     vExtraTxnForCompactIt = (vExtraTxnForCompactIt + 1) % max_extra_txn;
 }
 
 bool AddOrphanTx(const CTransactionRef &tx, NodeId peer)
     EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
     const uint256 &txid = tx->GetId();
     if (mapOrphanTransactions.count(txid)) {
         return false;
     }
 
     // Ignore big transactions, to avoid a send-big-orphans memory exhaustion
     // attack. If a peer has a legitimate large transaction with a missing
     // parent then we assume it will rebroadcast it later, after the parent
     // transaction(s) have been mined or received.
     // 100 orphans, each of which is at most 99,999 bytes big is at most 10
     // megabytes of orphans and somewhat more byprev index (in the worst case):
     unsigned int sz = GetTransactionSize(*tx);
     if (sz >= MAX_STANDARD_TX_SIZE) {
         LogPrint("mempool", "ignoring large orphan tx (size: %u, hash: %s)\n",
                  sz, txid.ToString());
         return false;
     }
 
     auto ret = mapOrphanTransactions.emplace(
         txid, COrphanTx{tx, peer, GetTime() + ORPHAN_TX_EXPIRE_TIME});
     assert(ret.second);
     for (const CTxIn &txin : tx->vin) {
         mapOrphanTransactionsByPrev[txin.prevout].insert(ret.first);
     }
 
     AddToCompactExtraTransactions(tx);
 
     LogPrint("mempool", "stored orphan tx %s (mapsz %u outsz %u)\n",
              txid.ToString(), mapOrphanTransactions.size(),
              mapOrphanTransactionsByPrev.size());
     return true;
 }
 
 static int EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
     std::map<uint256, COrphanTx>::iterator it =
         mapOrphanTransactions.find(hash);
     if (it == mapOrphanTransactions.end()) {
         return 0;
     }
     for (const CTxIn &txin : it->second.tx->vin) {
         auto itPrev = mapOrphanTransactionsByPrev.find(txin.prevout);
         if (itPrev == mapOrphanTransactionsByPrev.end()) {
             continue;
         }
         itPrev->second.erase(it);
         if (itPrev->second.empty()) {
             mapOrphanTransactionsByPrev.erase(itPrev);
         }
     }
     mapOrphanTransactions.erase(it);
     return 1;
 }
 
 void EraseOrphansFor(NodeId peer) {
     int nErased = 0;
     std::map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin();
     while (iter != mapOrphanTransactions.end()) {
         // Increment to avoid iterator becoming invalid.
         std::map<uint256, COrphanTx>::iterator maybeErase = iter++;
         if (maybeErase->second.fromPeer == peer) {
             nErased += EraseOrphanTx(maybeErase->second.tx->GetId());
         }
     }
     if (nErased > 0) {
         LogPrint("mempool", "Erased %d orphan tx from peer=%d\n", nErased,
                  peer);
     }
 }
 
 unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
     EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
     unsigned int nEvicted = 0;
     static int64_t nNextSweep;
     int64_t nNow = GetTime();
     if (nNextSweep <= nNow) {
         // Sweep out expired orphan pool entries:
         int nErased = 0;
         int64_t nMinExpTime =
             nNow + ORPHAN_TX_EXPIRE_TIME - ORPHAN_TX_EXPIRE_INTERVAL;
         std::map<uint256, COrphanTx>::iterator iter =
             mapOrphanTransactions.begin();
         while (iter != mapOrphanTransactions.end()) {
             std::map<uint256, COrphanTx>::iterator maybeErase = iter++;
             if (maybeErase->second.nTimeExpire <= nNow) {
                 nErased += EraseOrphanTx(maybeErase->second.tx->GetId());
             } else {
                 nMinExpTime =
                     std::min(maybeErase->second.nTimeExpire, nMinExpTime);
             }
         }
         // Sweep again 5 minutes after the next entry that expires in order to
         // batch the linear scan.
         nNextSweep = nMinExpTime + ORPHAN_TX_EXPIRE_INTERVAL;
         if (nErased > 0) {
             LogPrint("mempool", "Erased %d orphan tx due to expiration\n",
                      nErased);
         }
     }
     while (mapOrphanTransactions.size() > nMaxOrphans) {
         // Evict a random orphan:
         uint256 randomhash = GetRandHash();
         std::map<uint256, COrphanTx>::iterator it =
             mapOrphanTransactions.lower_bound(randomhash);
         if (it == mapOrphanTransactions.end()) {
             it = mapOrphanTransactions.begin();
         }
         EraseOrphanTx(it->first);
         ++nEvicted;
     }
     return nEvicted;
 }
 
 // Requires cs_main.
 void Misbehaving(NodeId pnode, int howmuch, const std::string &reason) {
     if (howmuch == 0) {
         return;
     }
 
     CNodeState *state = State(pnode);
     if (state == nullptr) {
         return;
     }
 
     state->nMisbehavior += howmuch;
     int banscore = GetArg("-banscore", DEFAULT_BANSCORE_THRESHOLD);
     if (state->nMisbehavior >= banscore &&
         state->nMisbehavior - howmuch < banscore) {
         LogPrintf(
             "%s: %s peer=%d (%d -> %d) reason: %s BAN THRESHOLD EXCEEDED\n",
             __func__, state->name, pnode, state->nMisbehavior - howmuch,
             state->nMisbehavior, reason.c_str());
         state->fShouldBan = true;
     } else {
         LogPrintf("%s: %s peer=%d (%d -> %d) reason: %s\n", __func__,
                   state->name, pnode, state->nMisbehavior - howmuch,
                   state->nMisbehavior, reason.c_str());
     }
 }
 
 // overloaded variant of above to operate on CNode*s
 static void Misbehaving(CNode *node, int howmuch, const std::string &reason) {
     Misbehaving(node->GetId(), howmuch, reason);
 }
 
 //////////////////////////////////////////////////////////////////////////////
 //
 // blockchain -> download logic notification
 //
 
 PeerLogicValidation::PeerLogicValidation(CConnman *connmanIn)
     : connman(connmanIn) {
     // Initialize global variables that cannot be constructed at startup.
     recentRejects.reset(new CRollingBloomFilter(120000, 0.000001));
 }
 
 void PeerLogicValidation::SyncTransaction(const CTransaction &tx,
                                           const CBlockIndex *pindex,
                                           int nPosInBlock) {
     if (nPosInBlock == CMainSignals::SYNC_TRANSACTION_NOT_IN_BLOCK) {
         return;
     }
 
     LOCK(cs_main);
 
     std::vector<uint256> vOrphanErase;
     // Which orphan pool entries must we evict?
     for (size_t j = 0; j < tx.vin.size(); j++) {
         auto itByPrev = mapOrphanTransactionsByPrev.find(tx.vin[j].prevout);
         if (itByPrev == mapOrphanTransactionsByPrev.end()) {
             continue;
         }
         for (auto mi = itByPrev->second.begin(); mi != itByPrev->second.end();
              ++mi) {
             const CTransaction &orphanTx = *(*mi)->second.tx;
             const uint256 &orphanId = orphanTx.GetId();
             vOrphanErase.push_back(orphanId);
         }
     }
 
     // Erase orphan transactions include or precluded by this block
     if (vOrphanErase.size()) {
         int nErased = 0;
         for (uint256 &orphanId : vOrphanErase) {
             nErased += EraseOrphanTx(orphanId);
         }
         LogPrint("mempool",
                  "Erased %d orphan tx included or conflicted by block\n",
                  nErased);
     }
 }
 
 static CCriticalSection cs_most_recent_block;
 static std::shared_ptr<const CBlock> most_recent_block;
 static std::shared_ptr<const CBlockHeaderAndShortTxIDs>
     most_recent_compact_block;
 static uint256 most_recent_block_hash;
 
 void PeerLogicValidation::NewPoWValidBlock(
     const CBlockIndex *pindex, const std::shared_ptr<const CBlock> &pblock) {
     std::shared_ptr<const CBlockHeaderAndShortTxIDs> pcmpctblock =
         std::make_shared<const CBlockHeaderAndShortTxIDs>(*pblock);
     const CNetMsgMaker msgMaker(PROTOCOL_VERSION);
 
     LOCK(cs_main);
 
     static int nHighestFastAnnounce = 0;
     if (pindex->nHeight <= nHighestFastAnnounce) {
         return;
     }
     nHighestFastAnnounce = pindex->nHeight;
 
     uint256 hashBlock(pblock->GetHash());
 
     {
         LOCK(cs_most_recent_block);
         most_recent_block_hash = hashBlock;
         most_recent_block = pblock;
         most_recent_compact_block = pcmpctblock;
     }
 
     connman->ForEachNode([this, &pcmpctblock, pindex, &msgMaker,
                           &hashBlock](CNode *pnode) {
         // TODO: Avoid the repeated-serialization here
         if (pnode->nVersion < INVALID_CB_NO_BAN_VERSION || pnode->fDisconnect) {
             return;
         }
         ProcessBlockAvailability(pnode->GetId());
         CNodeState &state = *State(pnode->GetId());
         // If the peer has, or we announced to them the previous block already,
         // but we don't think they have this one, go ahead and announce it.
         if (state.fPreferHeaderAndIDs && !PeerHasHeader(&state, pindex) &&
             PeerHasHeader(&state, pindex->pprev)) {
 
             LogPrint("net", "%s sending header-and-ids %s to peer=%d\n",
                      "PeerLogicValidation::NewPoWValidBlock",
                      hashBlock.ToString(), pnode->id);
             connman->PushMessage(
                 pnode, msgMaker.Make(NetMsgType::CMPCTBLOCK, *pcmpctblock));
             state.pindexBestHeaderSent = pindex;
         }
     });
 }
 
 void PeerLogicValidation::UpdatedBlockTip(const CBlockIndex *pindexNew,
                                           const CBlockIndex *pindexFork,
                                           bool fInitialDownload) {
     const int nNewHeight = pindexNew->nHeight;
     connman->SetBestHeight(nNewHeight);
 
     if (!fInitialDownload) {
         // Find the hashes of all blocks that weren't previously in the best
         // chain.
         std::vector<uint256> vHashes;
         const CBlockIndex *pindexToAnnounce = pindexNew;
         while (pindexToAnnounce != pindexFork) {
             vHashes.push_back(pindexToAnnounce->GetBlockHash());
             pindexToAnnounce = pindexToAnnounce->pprev;
             if (vHashes.size() == MAX_BLOCKS_TO_ANNOUNCE) {
                 // Limit announcements in case of a huge reorganization. Rely on
                 // the peer's synchronization mechanism in that case.
                 break;
             }
         }
         // Relay inventory, but don't relay old inventory during initial block
         // download.
         connman->ForEachNode([nNewHeight, &vHashes](CNode *pnode) {
             if (nNewHeight > (pnode->nStartingHeight != -1
                                   ? pnode->nStartingHeight - 2000
                                   : 0)) {
                 for (const uint256 &hash : boost::adaptors::reverse(vHashes)) {
                     pnode->PushBlockHash(hash);
                 }
             }
         });
         connman->WakeMessageHandler();
     }
 
     nTimeBestReceived = GetTime();
 }
 
 void PeerLogicValidation::BlockChecked(const CBlock &block,
                                        const CValidationState &state) {
     LOCK(cs_main);
 
     const uint256 hash(block.GetHash());
     std::map<uint256, std::pair<NodeId, bool>>::iterator it =
         mapBlockSource.find(hash);
 
     int nDoS = 0;
     if (state.IsInvalid(nDoS)) {
         if (it != mapBlockSource.end() && State(it->second.first)) {
             // Blocks are never rejected with internal reject codes.
             assert(state.GetRejectCode() < REJECT_INTERNAL);
             CBlockReject reject = {
-                (unsigned char)state.GetRejectCode(),
+                uint8_t(state.GetRejectCode()),
                 state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH),
                 hash};
             State(it->second.first)->rejects.push_back(reject);
             if (nDoS > 0 && it->second.second) {
                 Misbehaving(it->second.first, nDoS, state.GetRejectReason());
             }
         }
     }
     // Check that:
     // 1. The block is valid
     // 2. We're not in initial block download
     // 3. This is currently the best block we're aware of. We haven't updated
     //    the tip yet so we have no way to check this directly here. Instead we
     //    just check that there are currently no other blocks in flight.
     else if (state.IsValid() && !IsInitialBlockDownload() &&
              mapBlocksInFlight.count(hash) == mapBlocksInFlight.size()) {
         if (it != mapBlockSource.end()) {
             MaybeSetPeerAsAnnouncingHeaderAndIDs(it->second.first, *connman);
         }
     }
 
     if (it != mapBlockSource.end()) {
         mapBlockSource.erase(it);
     }
 }
 
 //////////////////////////////////////////////////////////////////////////////
 //
 // Messages
 //
 
 static bool AlreadyHave(const CInv &inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
     switch (inv.type) {
         case MSG_TX: {
             assert(recentRejects);
             if (chainActive.Tip()->GetBlockHash() !=
                 hashRecentRejectsChainTip) {
                 // If the chain tip has changed previously rejected transactions
                 // might be now valid, e.g. due to a nLockTime'd tx becoming
                 // valid, or a double-spend. Reset the rejects filter and give
                 // those txs a second chance.
                 hashRecentRejectsChainTip = chainActive.Tip()->GetBlockHash();
                 recentRejects->reset();
             }
 
             // Use pcoinsTip->HaveCoinInCache as a quick approximation to
             // exclude requesting or processing some txs which have already been
             // included in a block. As this is best effort, we only check for
             // output 0 and 1. This works well enough in practice and we get
             // diminishing returns with 2 onward.
             return recentRejects->contains(inv.hash) ||
                    mempool.exists(inv.hash) ||
                    mapOrphanTransactions.count(inv.hash) ||
                    pcoinsTip->HaveCoinInCache(COutPoint(inv.hash, 0)) ||
                    pcoinsTip->HaveCoinInCache(COutPoint(inv.hash, 1));
         }
         case MSG_BLOCK:
             return mapBlockIndex.count(inv.hash);
     }
     // Don't know what it is, just say we already got one
     return true;
 }
 
 static void RelayTransaction(const CTransaction &tx, CConnman &connman) {
     CInv inv(MSG_TX, tx.GetId());
     connman.ForEachNode([&inv](CNode *pnode) { pnode->PushInventory(inv); });
 }
 
 static void RelayAddress(const CAddress &addr, bool fReachable,
                          CConnman &connman) {
     // Limited relaying of addresses outside our network(s)
     unsigned int nRelayNodes = fReachable ? 2 : 1;
 
     // Relay to a limited number of other nodes.
     // Use deterministic randomness to send to the same nodes for 24 hours at a
     // time so the addrKnowns of the chosen nodes prevent repeats.
     uint64_t hashAddr = addr.GetHash();
     const CSipHasher hasher =
         connman.GetDeterministicRandomizer(RANDOMIZER_ID_ADDRESS_RELAY)
             .Write(hashAddr << 32)
             .Write((GetTime() + hashAddr) / (24 * 60 * 60));
     FastRandomContext insecure_rand;
 
     std::array<std::pair<uint64_t, CNode *>, 2> best{
         {{0, nullptr}, {0, nullptr}}};
     assert(nRelayNodes <= best.size());
 
     auto sortfunc = [&best, &hasher, nRelayNodes](CNode *pnode) {
         if (pnode->nVersion >= CADDR_TIME_VERSION) {
             uint64_t hashKey = CSipHasher(hasher).Write(pnode->id).Finalize();
             for (unsigned int i = 0; i < nRelayNodes; i++) {
                 if (hashKey > best[i].first) {
                     std::copy(best.begin() + i, best.begin() + nRelayNodes - 1,
                               best.begin() + i + 1);
                     best[i] = std::make_pair(hashKey, pnode);
                     break;
                 }
             }
         }
     };
 
     auto pushfunc = [&addr, &best, nRelayNodes, &insecure_rand] {
         for (unsigned int i = 0; i < nRelayNodes && best[i].first != 0; i++) {
             best[i].second->PushAddress(addr, insecure_rand);
         }
     };
 
     connman.ForEachNodeThen(std::move(sortfunc), std::move(pushfunc));
 }
 
 static void ProcessGetData(const Config &config, CNode *pfrom,
                            const Consensus::Params &consensusParams,
                            CConnman &connman,
                            const std::atomic<bool> &interruptMsgProc) {
     std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin();
     std::vector<CInv> vNotFound;
     const CNetMsgMaker msgMaker(pfrom->GetSendVersion());
     LOCK(cs_main);
 
     while (it != pfrom->vRecvGetData.end()) {
         // Don't bother if send buffer is too full to respond anyway.
         if (pfrom->fPauseSend) {
             break;
         }
 
         const CInv &inv = *it;
         {
             if (interruptMsgProc) {
                 return;
             }
 
             it++;
 
             if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK ||
                 inv.type == MSG_CMPCT_BLOCK) {
                 bool send = false;
                 BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
                 if (mi != mapBlockIndex.end()) {
                     if (mi->second->nChainTx &&
                         !mi->second->IsValid(BLOCK_VALID_SCRIPTS) &&
                         mi->second->IsValid(BLOCK_VALID_TREE)) {
                         // If we have the block and all of its parents, but have
                         // not yet validated it, we might be in the middle of
                         // connecting it (ie in the unlock of cs_main before
                         // ActivateBestChain but after AcceptBlock). In this
                         // case, we need to run ActivateBestChain prior to
                         // checking the relay conditions below.
                         std::shared_ptr<const CBlock> a_recent_block;
                         {
                             LOCK(cs_most_recent_block);
                             a_recent_block = most_recent_block;
                         }
                         CValidationState dummy;
                         ActivateBestChain(config, dummy, a_recent_block);
                     }
                     if (chainActive.Contains(mi->second)) {
                         send = true;
                     } else {
                         static const int nOneMonth = 30 * 24 * 60 * 60;
                         // To prevent fingerprinting attacks, only send blocks
                         // outside of the active chain if they are valid, and no
                         // more than a month older (both in time, and in best
                         // equivalent proof of work) than the best header chain
                         // we know about.
                         send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) &&
                                (pindexBestHeader != nullptr) &&
                                (pindexBestHeader->GetBlockTime() -
                                     mi->second->GetBlockTime() <
                                 nOneMonth) &&
                                (GetBlockProofEquivalentTime(
                                     *pindexBestHeader, *mi->second,
                                     *pindexBestHeader,
                                     consensusParams) < nOneMonth);
                         if (!send) {
                             LogPrintf("%s: ignoring request from peer=%i for "
                                       "old block that isn't in the main "
                                       "chain\n",
                                       __func__, pfrom->GetId());
                         }
                     }
                 }
 
                 // Disconnect node in case we have reached the outbound limit
                 // for serving historical blocks never disconnect whitelisted
                 // nodes.
                 // assume > 1 week = historical
                 static const int nOneWeek = 7 * 24 * 60 * 60;
                 if (send && connman.OutboundTargetReached(true) &&
                     (((pindexBestHeader != nullptr) &&
                       (pindexBestHeader->GetBlockTime() -
                            mi->second->GetBlockTime() >
                        nOneWeek)) ||
                      inv.type == MSG_FILTERED_BLOCK) &&
                     !pfrom->fWhitelisted) {
                     LogPrint("net", "historical block serving limit reached, "
                                     "disconnect peer=%d\n",
                              pfrom->GetId());
 
                     // disconnect node
                     pfrom->fDisconnect = true;
                     send = false;
                 }
                 // Pruned nodes may have deleted the block, so check whether
                 // it's available before trying to send.
                 if (send && (mi->second->nStatus & BLOCK_HAVE_DATA)) {
                     // Send block from disk
                     CBlock block;
                     if (!ReadBlockFromDisk(block, (*mi).second,
                                            consensusParams)) {
                         assert(!"cannot load block from disk");
                     }
 
                     if (inv.type == MSG_BLOCK) {
                         connman.PushMessage(
                             pfrom, msgMaker.Make(NetMsgType::BLOCK, block));
                     } else if (inv.type == MSG_FILTERED_BLOCK) {
                         bool sendMerkleBlock = false;
                         CMerkleBlock merkleBlock;
                         {
                             LOCK(pfrom->cs_filter);
                             if (pfrom->pfilter) {
                                 sendMerkleBlock = true;
                                 merkleBlock =
                                     CMerkleBlock(block, *pfrom->pfilter);
                             }
                         }
                         if (sendMerkleBlock) {
                             connman.PushMessage(
                                 pfrom, msgMaker.Make(NetMsgType::MERKLEBLOCK,
                                                      merkleBlock));
                             // CMerkleBlock just contains hashes, so also push
                             // any transactions in the block the client did not
                             // see. This avoids hurting performance by
                             // pointlessly requiring a round-trip. Note that
                             // there is currently no way for a node to request
                             // any single transactions we didn't send here -
                             // they must either disconnect and retry or request
                             // the full block. Thus, the protocol spec specified
                             // allows for us to provide duplicate txn here,
                             // however we MUST always provide at least what the
                             // remote peer needs.
                             typedef std::pair<unsigned int, uint256> PairType;
                             for (PairType &pair : merkleBlock.vMatchedTxn) {
                                 connman.PushMessage(
                                     pfrom,
                                     msgMaker.Make(NetMsgType::TX,
                                                   *block.vtx[pair.first]));
                             }
                         }
                         // else
                         // no response
                     } else if (inv.type == MSG_CMPCT_BLOCK) {
                         // If a peer is asking for old blocks, we're almost
                         // guaranteed they won't have a useful mempool to match
                         // against a compact block, and we don't feel like
                         // constructing the object for them, so instead we
                         // respond with the full, non-compact block.
                         int nSendFlags = 0;
                         if (CanDirectFetch(consensusParams) &&
                             mi->second->nHeight >=
                                 chainActive.Height() - MAX_CMPCTBLOCK_DEPTH) {
                             CBlockHeaderAndShortTxIDs cmpctblock(block);
                             connman.PushMessage(
                                 pfrom, msgMaker.Make(nSendFlags,
                                                      NetMsgType::CMPCTBLOCK,
                                                      cmpctblock));
                         } else {
                             connman.PushMessage(
                                 pfrom, msgMaker.Make(nSendFlags,
                                                      NetMsgType::BLOCK, block));
                         }
                     }
 
                     // Trigger the peer node to send a getblocks request for the
                     // next batch of inventory.
                     if (inv.hash == pfrom->hashContinue) {
                         // Bypass PushInventory, this must send even if
                         // redundant, and we want it right after the last block
                         // so they don't wait for other stuff first.
                         std::vector<CInv> vInv;
                         vInv.push_back(
                             CInv(MSG_BLOCK, chainActive.Tip()->GetBlockHash()));
                         connman.PushMessage(
                             pfrom, msgMaker.Make(NetMsgType::INV, vInv));
                         pfrom->hashContinue.SetNull();
                     }
                 }
             } else if (inv.type == MSG_TX) {
                 // Send stream from relay memory
                 bool push = false;
                 auto mi = mapRelay.find(inv.hash);
                 int nSendFlags = 0;
                 if (mi != mapRelay.end()) {
                     connman.PushMessage(
                         pfrom,
                         msgMaker.Make(nSendFlags, NetMsgType::TX, *mi->second));
                     push = true;
                 } else if (pfrom->timeLastMempoolReq) {
                     auto txinfo = mempool.info(inv.hash);
                     // To protect privacy, do not answer getdata using the
                     // mempool when that TX couldn't have been INVed in reply to
                     // a MEMPOOL request.
                     if (txinfo.tx &&
                         txinfo.nTime <= pfrom->timeLastMempoolReq) {
                         connman.PushMessage(pfrom, msgMaker.Make(nSendFlags,
                                                                  NetMsgType::TX,
                                                                  *txinfo.tx));
                         push = true;
                     }
                 }
                 if (!push) {
                     vNotFound.push_back(inv);
                 }
             }
 
             // Track requests for our stuff.
             GetMainSignals().Inventory(inv.hash);
 
             if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK ||
                 inv.type == MSG_CMPCT_BLOCK) {
                 break;
             }
         }
     }
 
     pfrom->vRecvGetData.erase(pfrom->vRecvGetData.begin(), it);
 
     if (!vNotFound.empty()) {
         // Let the peer know that we didn't find what it asked for, so it
         // doesn't have to wait around forever. Currently only SPV clients
         // actually care about this message: it's needed when they are
         // recursively walking the dependencies of relevant unconfirmed
         // transactions. SPV clients want to do that because they want to know
         // about (and store and rebroadcast and risk analyze) the dependencies
         // of transactions relevant to them, without having to download the
         // entire memory pool.
         connman.PushMessage(pfrom,
                             msgMaker.Make(NetMsgType::NOTFOUND, vNotFound));
     }
 }
 
 uint32_t GetFetchFlags(CNode *pfrom, const CBlockIndex *pprev,
                        const Consensus::Params &chainparams) {
     uint32_t nFetchFlags = 0;
     return nFetchFlags;
 }
 
 inline static void SendBlockTransactions(const CBlock &block,
                                          const BlockTransactionsRequest &req,
                                          CNode *pfrom, CConnman &connman) {
     BlockTransactions resp(req);
     for (size_t i = 0; i < req.indexes.size(); i++) {
         if (req.indexes[i] >= block.vtx.size()) {
             LOCK(cs_main);
             Misbehaving(pfrom, 100, "out-of-bound-tx-index");
             LogPrintf(
                 "Peer %d sent us a getblocktxn with out-of-bounds tx indices",
                 pfrom->id);
             return;
         }
         resp.txn[i] = block.vtx[req.indexes[i]];
     }
     LOCK(cs_main);
     const CNetMsgMaker msgMaker(pfrom->GetSendVersion());
     int nSendFlags = 0;
     connman.PushMessage(pfrom,
                         msgMaker.Make(nSendFlags, NetMsgType::BLOCKTXN, resp));
 }
 
 static bool ProcessMessage(const Config &config, CNode *pfrom,
                            const std::string &strCommand, CDataStream &vRecv,
                            int64_t nTimeReceived,
                            const CChainParams &chainparams, CConnman &connman,
                            const std::atomic<bool> &interruptMsgProc) {
     LogPrint("net", "received: %s (%u bytes) peer=%d\n",
              SanitizeString(strCommand), vRecv.size(), pfrom->id);
     if (IsArgSet("-dropmessagestest") &&
         GetRand(GetArg("-dropmessagestest", 0)) == 0) {
         LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n");
         return true;
     }
 
     if (!(pfrom->GetLocalServices() & NODE_BLOOM) &&
         (strCommand == NetMsgType::FILTERLOAD ||
          strCommand == NetMsgType::FILTERADD)) {
         if (pfrom->nVersion >= NO_BLOOM_VERSION) {
             LOCK(cs_main);
             Misbehaving(pfrom, 100, "no-bloom-version");
             return false;
         } else {
             pfrom->fDisconnect = true;
             return false;
         }
     }
 
     if (strCommand == NetMsgType::REJECT) {
         if (fDebug) {
             try {
                 std::string strMsg;
-                unsigned char ccode;
+                uint8_t ccode;
                 std::string strReason;
                 vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >>
                     ccode >>
                     LIMITED_STRING(strReason, MAX_REJECT_MESSAGE_LENGTH);
 
                 std::ostringstream ss;
                 ss << strMsg << " code " << itostr(ccode) << ": " << strReason;
 
                 if (strMsg == NetMsgType::BLOCK || strMsg == NetMsgType::TX) {
                     uint256 hash;
                     vRecv >> hash;
                     ss << ": hash " << hash.ToString();
                 }
                 LogPrint("net", "Reject %s\n", SanitizeString(ss.str()));
             } catch (const std::ios_base::failure &) {
                 // Avoid feedback loops by preventing reject messages from
                 // triggering a new reject message.
                 LogPrint("net", "Unparseable reject message received\n");
             }
         }
     }
 
     else if (strCommand == NetMsgType::VERSION) {
         // Each connection can only send one version message
         if (pfrom->nVersion != 0) {
             connman.PushMessage(
                 pfrom,
                 CNetMsgMaker(INIT_PROTO_VERSION)
                     .Make(NetMsgType::REJECT, strCommand, REJECT_DUPLICATE,
                           std::string("Duplicate version message")));
             LOCK(cs_main);
             Misbehaving(pfrom, 1, "multiple-version");
             return false;
         }
 
         int64_t nTime;
         CAddress addrMe;
         CAddress addrFrom;
         uint64_t nNonce = 1;
         uint64_t nServiceInt;
         ServiceFlags nServices;
         int nVersion;
         int nSendVersion;
         std::string strSubVer;
         std::string cleanSubVer;
         int nStartingHeight = -1;
         bool fRelay = true;
 
         vRecv >> nVersion >> nServiceInt >> nTime >> addrMe;
         nSendVersion = std::min(nVersion, PROTOCOL_VERSION);
         nServices = ServiceFlags(nServiceInt);
         if (!pfrom->fInbound) {
             connman.SetServices(pfrom->addr, nServices);
         }
         if (pfrom->nServicesExpected & ~nServices) {
             LogPrint("net", "peer=%d does not offer the expected services "
                             "(%08x offered, %08x expected); disconnecting\n",
                      pfrom->id, nServices, pfrom->nServicesExpected);
             connman.PushMessage(
                 pfrom,
                 CNetMsgMaker(INIT_PROTO_VERSION)
                     .Make(NetMsgType::REJECT, strCommand, REJECT_NONSTANDARD,
                           strprintf("Expected to offer services %08x",
                                     pfrom->nServicesExpected)));
             pfrom->fDisconnect = true;
             return false;
         }
 
         if (nVersion < MIN_PEER_PROTO_VERSION) {
             // disconnect from peers older than this proto version
             LogPrintf("peer=%d using obsolete version %i; disconnecting\n",
                       pfrom->id, nVersion);
             connman.PushMessage(
                 pfrom,
                 CNetMsgMaker(INIT_PROTO_VERSION)
                     .Make(NetMsgType::REJECT, strCommand, REJECT_OBSOLETE,
                           strprintf("Version must be %d or greater",
                                     MIN_PEER_PROTO_VERSION)));
             pfrom->fDisconnect = true;
             return false;
         }
 
         if (!vRecv.empty()) {
             vRecv >> addrFrom >> nNonce;
         }
         if (!vRecv.empty()) {
             vRecv >> LIMITED_STRING(strSubVer, MAX_SUBVERSION_LENGTH);
             cleanSubVer = SanitizeString(strSubVer);
         }
         if (!vRecv.empty()) {
             vRecv >> nStartingHeight;
         }
         if (!vRecv.empty()) {
             vRecv >> fRelay;
         }
         // Disconnect if we connected to ourself
         if (pfrom->fInbound && !connman.CheckIncomingNonce(nNonce)) {
             LogPrintf("connected to self at %s, disconnecting\n",
                       pfrom->addr.ToString());
             pfrom->fDisconnect = true;
             return true;
         }
 
         if (pfrom->fInbound && addrMe.IsRoutable()) {
             SeenLocal(addrMe);
         }
 
         // Be shy and don't send version until we hear
         if (pfrom->fInbound) {
             PushNodeVersion(config, pfrom, connman, GetAdjustedTime());
         }
 
         connman.PushMessage(
             pfrom, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::VERACK));
 
         pfrom->nServices = nServices;
         pfrom->SetAddrLocal(addrMe);
         {
             LOCK(pfrom->cs_SubVer);
             pfrom->strSubVer = strSubVer;
             pfrom->cleanSubVer = cleanSubVer;
         }
         pfrom->nStartingHeight = nStartingHeight;
         pfrom->fClient = !(nServices & NODE_NETWORK);
         {
             LOCK(pfrom->cs_filter);
             pfrom->fRelayTxes =
                 fRelay; // set to true after we get the first filter* message
         }
 
         // Change version
         pfrom->SetSendVersion(nSendVersion);
         pfrom->nVersion = nVersion;
 
         // Potentially mark this peer as a preferred download peer.
         {
             LOCK(cs_main);
             UpdatePreferredDownload(pfrom, State(pfrom->GetId()));
         }
 
         if (!pfrom->fInbound) {
             // Advertise our address
             if (fListen && !IsInitialBlockDownload()) {
                 CAddress addr =
                     GetLocalAddress(&pfrom->addr, pfrom->GetLocalServices());
                 FastRandomContext insecure_rand;
                 if (addr.IsRoutable()) {
                     LogPrint("net", "ProcessMessages: advertising address %s\n",
                              addr.ToString());
                     pfrom->PushAddress(addr, insecure_rand);
                 } else if (IsPeerAddrLocalGood(pfrom)) {
                     addr.SetIP(addrMe);
                     LogPrint("net", "ProcessMessages: advertising address %s\n",
                              addr.ToString());
                     pfrom->PushAddress(addr, insecure_rand);
                 }
             }
 
             // Get recent addresses
             if (pfrom->fOneShot || pfrom->nVersion >= CADDR_TIME_VERSION ||
                 connman.GetAddressCount() < 1000) {
                 connman.PushMessage(
                     pfrom,
                     CNetMsgMaker(nSendVersion).Make(NetMsgType::GETADDR));
                 pfrom->fGetAddr = true;
             }
             connman.MarkAddressGood(pfrom->addr);
         }
 
         std::string remoteAddr;
         if (fLogIPs) {
             remoteAddr = ", peeraddr=" + pfrom->addr.ToString();
         }
 
         LogPrintf("receive version message: [%s] %s: version %d, blocks=%d, "
                   "us=%s, peer=%d%s\n",
                   pfrom->addr.ToString().c_str(), cleanSubVer, pfrom->nVersion,
                   pfrom->nStartingHeight, addrMe.ToString(), pfrom->id,
                   remoteAddr);
         if (pfrom->fUsesCashMagic) {
             LogPrintf("peer %d uses CASH magic in its headers\n", pfrom->id);
         }
 
         int64_t nTimeOffset = nTime - GetTime();
         pfrom->nTimeOffset = nTimeOffset;
         AddTimeData(pfrom->addr, nTimeOffset);
 
         // If the peer is old enough to have the old alert system, send it the
         // final alert.
         if (pfrom->nVersion <= 70012) {
             CDataStream finalAlert(
                 ParseHex("60010000000000000000000000ffffff7f00000000ffffff7ffef"
                          "fff7f01ffffff7f00000000ffffff7f00ffffff7f002f55524745"
                          "4e543a20416c657274206b657920636f6d70726f6d697365642c2"
                          "075706772616465207265717569726564004630440220653febd6"
                          "410f470f6bae11cad19c48413becb1ac2c17f908fd0fd53bdc3ab"
                          "d5202206d0e9c96fe88d4a0f01ed9dedae2b6f9e00da94cad0fec"
                          "aae66ecf689bf71b50"),
                 SER_NETWORK, PROTOCOL_VERSION);
             connman.PushMessage(
                 pfrom, CNetMsgMaker(nSendVersion).Make("alert", finalAlert));
         }
 
         // Feeler connections exist only to verify if address is online.
         if (pfrom->fFeeler) {
             assert(pfrom->fInbound == false);
             pfrom->fDisconnect = true;
         }
         return true;
     }
 
     else if (pfrom->nVersion == 0) {
         // Must have a version message before anything else
         LOCK(cs_main);
         Misbehaving(pfrom, 1, "missing-version");
         return false;
     }
 
     // At this point, the outgoing message serialization version can't change.
     const CNetMsgMaker msgMaker(pfrom->GetSendVersion());
 
     if (strCommand == NetMsgType::VERACK) {
         pfrom->SetRecvVersion(
             std::min(pfrom->nVersion.load(), PROTOCOL_VERSION));
 
         if (!pfrom->fInbound) {
             // Mark this node as currently connected, so we update its timestamp
             // later.
             LOCK(cs_main);
             State(pfrom->GetId())->fCurrentlyConnected = true;
         }
 
         if (pfrom->nVersion >= SENDHEADERS_VERSION) {
             // Tell our peer we prefer to receive headers rather than inv's
             // We send this to non-NODE NETWORK peers as well, because even
             // non-NODE NETWORK peers can announce blocks (such as pruning
             // nodes)
             connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::SENDHEADERS));
         }
         if (pfrom->nVersion >= SHORT_IDS_BLOCKS_VERSION) {
             // Tell our peer we are willing to provide version 1 or 2
             // cmpctblocks. However, we do not request new block announcements
             // using cmpctblock messages. We send this to non-NODE NETWORK peers
             // as well, because they may wish to request compact blocks from us.
             bool fAnnounceUsingCMPCTBLOCK = false;
             uint64_t nCMPCTBLOCKVersion = 1;
             connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::SENDCMPCT,
                                                      fAnnounceUsingCMPCTBLOCK,
                                                      nCMPCTBLOCKVersion));
         }
         pfrom->fSuccessfullyConnected = true;
     }
 
     else if (!pfrom->fSuccessfullyConnected) {
         // Must have a verack message before anything else
         LOCK(cs_main);
         Misbehaving(pfrom, 1, "missing-verack");
         return false;
     }
 
     else if (strCommand == NetMsgType::ADDR) {
         std::vector<CAddress> vAddr;
         vRecv >> vAddr;
 
         // Don't want addr from older versions unless seeding
         if (pfrom->nVersion < CADDR_TIME_VERSION &&
             connman.GetAddressCount() > 1000) {
             return true;
         }
         if (vAddr.size() > 1000) {
             LOCK(cs_main);
             Misbehaving(pfrom, 20, "oversized-addr");
             return error("message addr size() = %u", vAddr.size());
         }
 
         // Store the new addresses
         std::vector<CAddress> vAddrOk;
         int64_t nNow = GetAdjustedTime();
         int64_t nSince = nNow - 10 * 60;
         for (CAddress &addr : vAddr) {
             if (interruptMsgProc) {
                 return true;
             }
 
             if ((addr.nServices & REQUIRED_SERVICES) != REQUIRED_SERVICES) {
                 continue;
             }
 
             if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60) {
                 addr.nTime = nNow - 5 * 24 * 60 * 60;
             }
             pfrom->AddAddressKnown(addr);
             bool fReachable = IsReachable(addr);
             if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 &&
                 addr.IsRoutable()) {
                 // Relay to a limited number of other nodes
                 RelayAddress(addr, fReachable, connman);
             }
             // Do not store addresses outside our network
             if (fReachable) {
                 vAddrOk.push_back(addr);
             }
         }
         connman.AddNewAddresses(vAddrOk, pfrom->addr, 2 * 60 * 60);
         if (vAddr.size() < 1000) {
             pfrom->fGetAddr = false;
         }
         if (pfrom->fOneShot) {
             pfrom->fDisconnect = true;
         }
     }
 
     else if (strCommand == NetMsgType::SENDHEADERS) {
         LOCK(cs_main);
         State(pfrom->GetId())->fPreferHeaders = true;
     }
 
     else if (strCommand == NetMsgType::SENDCMPCT) {
         bool fAnnounceUsingCMPCTBLOCK = false;
         uint64_t nCMPCTBLOCKVersion = 0;
         vRecv >> fAnnounceUsingCMPCTBLOCK >> nCMPCTBLOCKVersion;
         if (nCMPCTBLOCKVersion == 1) {
             LOCK(cs_main);
             // fProvidesHeaderAndIDs is used to "lock in" version of compact
             // blocks we send.
             if (!State(pfrom->GetId())->fProvidesHeaderAndIDs) {
                 State(pfrom->GetId())->fProvidesHeaderAndIDs = true;
             }
 
             State(pfrom->GetId())->fPreferHeaderAndIDs =
                 fAnnounceUsingCMPCTBLOCK;
             if (!State(pfrom->GetId())->fSupportsDesiredCmpctVersion) {
                 State(pfrom->GetId())->fSupportsDesiredCmpctVersion = true;
             }
         }
     }
 
     else if (strCommand == NetMsgType::INV) {
         std::vector<CInv> vInv;
         vRecv >> vInv;
         if (vInv.size() > MAX_INV_SZ) {
             LOCK(cs_main);
             Misbehaving(pfrom, 20, "oversized-inv");
             return error("message inv size() = %u", vInv.size());
         }
 
         bool fBlocksOnly = !fRelayTxes;
 
         // Allow whitelisted peers to send data other than blocks in blocks only
         // mode if whitelistrelay is true
         if (pfrom->fWhitelisted &&
             GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY)) {
             fBlocksOnly = false;
         }
 
         LOCK(cs_main);
 
         uint32_t nFetchFlags =
             GetFetchFlags(pfrom, chainActive.Tip(), chainparams.GetConsensus());
 
         std::vector<CInv> vToFetch;
 
         for (size_t nInv = 0; nInv < vInv.size(); nInv++) {
             CInv &inv = vInv[nInv];
 
             if (interruptMsgProc) {
                 return true;
             }
 
             bool fAlreadyHave = AlreadyHave(inv);
             LogPrint("net", "got inv: %s  %s peer=%d\n", inv.ToString(),
                      fAlreadyHave ? "have" : "new", pfrom->id);
 
             if (inv.type == MSG_TX) {
                 inv.type |= nFetchFlags;
             }
 
             if (inv.type == MSG_BLOCK) {
                 UpdateBlockAvailability(pfrom->GetId(), inv.hash);
                 if (!fAlreadyHave && !fImporting && !fReindex &&
                     !mapBlocksInFlight.count(inv.hash)) {
                     // We used to request the full block here, but since
                     // headers-announcements are now the primary method of
                     // announcement on the network, and since, in the case that
                     // a node fell back to inv we probably have a reorg which we
                     // should get the headers for first, we now only provide a
                     // getheaders response here. When we receive the headers, we
                     // will then ask for the blocks we need.
                     connman.PushMessage(
                         pfrom,
                         msgMaker.Make(NetMsgType::GETHEADERS,
                                       chainActive.GetLocator(pindexBestHeader),
                                       inv.hash));
                     LogPrint("net", "getheaders (%d) %s to peer=%d\n",
                              pindexBestHeader->nHeight, inv.hash.ToString(),
                              pfrom->id);
                 }
             } else {
                 pfrom->AddInventoryKnown(inv);
                 if (fBlocksOnly) {
                     LogPrint("net", "transaction (%s) inv sent in violation of "
                                     "protocol peer=%d\n",
                              inv.hash.ToString(), pfrom->id);
                 } else if (!fAlreadyHave && !fImporting && !fReindex &&
                            !IsInitialBlockDownload()) {
                     pfrom->AskFor(inv);
                 }
             }
 
             // Track requests for our stuff
             GetMainSignals().Inventory(inv.hash);
         }
 
         if (!vToFetch.empty()) {
             connman.PushMessage(pfrom,
                                 msgMaker.Make(NetMsgType::GETDATA, vToFetch));
         }
     }
 
     else if (strCommand == NetMsgType::GETDATA) {
         std::vector<CInv> vInv;
         vRecv >> vInv;
         if (vInv.size() > MAX_INV_SZ) {
             LOCK(cs_main);
             Misbehaving(pfrom, 20, "too-many-inv");
             return error("message getdata size() = %u", vInv.size());
         }
 
         if (fDebug || (vInv.size() != 1)) {
             LogPrint("net", "received getdata (%u invsz) peer=%d\n",
                      vInv.size(), pfrom->id);
         }
 
         if ((fDebug && vInv.size() > 0) || (vInv.size() == 1)) {
             LogPrint("net", "received getdata for: %s peer=%d\n",
                      vInv[0].ToString(), pfrom->id);
         }
 
         pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(),
                                    vInv.end());
         ProcessGetData(config, pfrom, chainparams.GetConsensus(), connman,
                        interruptMsgProc);
     }
 
     else if (strCommand == NetMsgType::GETBLOCKS) {
         CBlockLocator locator;
         uint256 hashStop;
         vRecv >> locator >> hashStop;
 
         // We might have announced the currently-being-connected tip using a
         // compact block, which resulted in the peer sending a getblocks
         // request, which we would otherwise respond to without the new block.
         // To avoid this situation we simply verify that we are on our best
         // known chain now. This is super overkill, but we handle it better
         // for getheaders requests, and there are no known nodes which support
         // compact blocks but still use getblocks to request blocks.
         {
             std::shared_ptr<const CBlock> a_recent_block;
             {
                 LOCK(cs_most_recent_block);
                 a_recent_block = most_recent_block;
             }
             CValidationState dummy;
             ActivateBestChain(config, dummy, a_recent_block);
         }
 
         LOCK(cs_main);
 
         // Find the last block the caller has in the main chain
         const CBlockIndex *pindex = FindForkInGlobalIndex(chainActive, locator);
 
         // Send the rest of the chain
         if (pindex) {
             pindex = chainActive.Next(pindex);
         }
         int nLimit = 500;
         LogPrint("net", "getblocks %d to %s limit %d from peer=%d\n",
                  (pindex ? pindex->nHeight : -1),
                  hashStop.IsNull() ? "end" : hashStop.ToString(), nLimit,
                  pfrom->id);
         for (; pindex; pindex = chainActive.Next(pindex)) {
             if (pindex->GetBlockHash() == hashStop) {
                 LogPrint("net", "  getblocks stopping at %d %s\n",
                          pindex->nHeight, pindex->GetBlockHash().ToString());
                 break;
             }
             // If pruning, don't inv blocks unless we have on disk and are
             // likely to still have for some reasonable time window (1 hour)
             // that block relay might require.
             const int nPrunedBlocksLikelyToHave =
                 MIN_BLOCKS_TO_KEEP -
                 3600 / chainparams.GetConsensus().nPowTargetSpacing;
             if (fPruneMode &&
                 (!(pindex->nStatus & BLOCK_HAVE_DATA) ||
                  pindex->nHeight <=
                      chainActive.Tip()->nHeight - nPrunedBlocksLikelyToHave)) {
                 LogPrint(
                     "net",
                     " getblocks stopping, pruned or too old block at %d %s\n",
                     pindex->nHeight, pindex->GetBlockHash().ToString());
                 break;
             }
             pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
             if (--nLimit <= 0) {
                 // When this block is requested, we'll send an inv that'll
                 // trigger the peer to getblocks the next batch of inventory.
                 LogPrint("net", "  getblocks stopping at limit %d %s\n",
                          pindex->nHeight, pindex->GetBlockHash().ToString());
                 pfrom->hashContinue = pindex->GetBlockHash();
                 break;
             }
         }
     }
 
     else if (strCommand == NetMsgType::GETBLOCKTXN) {
         BlockTransactionsRequest req;
         vRecv >> req;
 
         std::shared_ptr<const CBlock> recent_block;
         {
             LOCK(cs_most_recent_block);
             if (most_recent_block_hash == req.blockhash) {
                 recent_block = most_recent_block;
             }
             // Unlock cs_most_recent_block to avoid cs_main lock inversion
         }
         if (recent_block) {
             SendBlockTransactions(*recent_block, req, pfrom, connman);
             return true;
         }
 
         LOCK(cs_main);
 
         BlockMap::iterator it = mapBlockIndex.find(req.blockhash);
         if (it == mapBlockIndex.end() ||
             !(it->second->nStatus & BLOCK_HAVE_DATA)) {
             LogPrintf("Peer %d sent us a getblocktxn for a block we don't have",
                       pfrom->id);
             return true;
         }
 
         if (it->second->nHeight < chainActive.Height() - MAX_BLOCKTXN_DEPTH) {
             // If an older block is requested (should never happen in practice,
             // but can happen in tests) send a block response instead of a
             // blocktxn response. Sending a full block response instead of a
             // small blocktxn response is preferable in the case where a peer
             // might maliciously send lots of getblocktxn requests to trigger
             // expensive disk reads, because it will require the peer to
             // actually receive all the data read from disk over the network.
             LogPrint("net",
                      "Peer %d sent us a getblocktxn for a block > %i deep",
                      pfrom->id, MAX_BLOCKTXN_DEPTH);
             CInv inv;
             inv.type = MSG_BLOCK;
             inv.hash = req.blockhash;
             pfrom->vRecvGetData.push_back(inv);
             ProcessGetData(config, pfrom, chainparams.GetConsensus(), connman,
                            interruptMsgProc);
             return true;
         }
 
         CBlock block;
         bool ret =
             ReadBlockFromDisk(block, it->second, chainparams.GetConsensus());
         assert(ret);
 
         SendBlockTransactions(block, req, pfrom, connman);
     }
 
     else if (strCommand == NetMsgType::GETHEADERS) {
         CBlockLocator locator;
         uint256 hashStop;
         vRecv >> locator >> hashStop;
 
         LOCK(cs_main);
         if (IsInitialBlockDownload() && !pfrom->fWhitelisted) {
             LogPrint("net", "Ignoring getheaders from peer=%d because node is "
                             "in initial block download\n",
                      pfrom->id);
             return true;
         }
 
         CNodeState *nodestate = State(pfrom->GetId());
         const CBlockIndex *pindex = nullptr;
         if (locator.IsNull()) {
             // If locator is null, return the hashStop block
             BlockMap::iterator mi = mapBlockIndex.find(hashStop);
             if (mi == mapBlockIndex.end()) {
                 return true;
             }
             pindex = (*mi).second;
         } else {
             // Find the last block the caller has in the main chain
             pindex = FindForkInGlobalIndex(chainActive, locator);
             if (pindex) {
                 pindex = chainActive.Next(pindex);
             }
         }
 
         // we must use CBlocks, as CBlockHeaders won't include the 0x00 nTx
         // count at the end
         std::vector<CBlock> vHeaders;
         int nLimit = MAX_HEADERS_RESULTS;
         LogPrint("net", "getheaders %d to %s from peer=%d\n",
                  (pindex ? pindex->nHeight : -1),
                  hashStop.IsNull() ? "end" : hashStop.ToString(), pfrom->id);
         for (; pindex; pindex = chainActive.Next(pindex)) {
             vHeaders.push_back(pindex->GetBlockHeader());
             if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop) {
                 break;
             }
         }
         // pindex can be nullptr either if we sent chainActive.Tip() OR
         // if our peer has chainActive.Tip() (and thus we are sending an empty
         // headers message). In both cases it's safe to update
         // pindexBestHeaderSent to be our tip.
         //
         // It is important that we simply reset the BestHeaderSent value here,
         // and not max(BestHeaderSent, newHeaderSent). We might have announced
         // the currently-being-connected tip using a compact block, which
         // resulted in the peer sending a headers request, which we respond to
         // without the new block. By resetting the BestHeaderSent, we ensure we
         // will re-announce the new block via headers (or compact blocks again)
         // in the SendMessages logic.
         nodestate->pindexBestHeaderSent = pindex ? pindex : chainActive.Tip();
         connman.PushMessage(pfrom,
                             msgMaker.Make(NetMsgType::HEADERS, vHeaders));
     }
 
     else if (strCommand == NetMsgType::TX) {
         // Stop processing the transaction early if
         // We are in blocks only mode and peer is either not whitelisted or
         // whitelistrelay is off
         if (!fRelayTxes &&
             (!pfrom->fWhitelisted ||
              !GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY))) {
             LogPrint("net",
                      "transaction sent in violation of protocol peer=%d\n",
                      pfrom->id);
             return true;
         }
 
         std::deque<COutPoint> vWorkQueue;
         std::vector<uint256> vEraseQueue;
         CTransactionRef ptx;
         vRecv >> ptx;
         const CTransaction &tx = *ptx;
 
         CInv inv(MSG_TX, tx.GetId());
         pfrom->AddInventoryKnown(inv);
 
         LOCK(cs_main);
 
         bool fMissingInputs = false;
         CValidationState state;
 
         pfrom->setAskFor.erase(inv.hash);
         mapAlreadyAskedFor.erase(inv.hash);
 
         std::list<CTransactionRef> lRemovedTxn;
 
         if (!AlreadyHave(inv) &&
             AcceptToMemoryPool(config, mempool, state, ptx, true,
                                &fMissingInputs, &lRemovedTxn)) {
             mempool.check(pcoinsTip);
             RelayTransaction(tx, connman);
             for (size_t i = 0; i < tx.vout.size(); i++) {
                 vWorkQueue.emplace_back(inv.hash, i);
             }
 
             pfrom->nLastTXTime = GetTime();
 
             LogPrint("mempool", "AcceptToMemoryPool: peer=%d: accepted %s "
                                 "(poolsz %u txn, %u kB)\n",
                      pfrom->id, tx.GetId().ToString(), mempool.size(),
                      mempool.DynamicMemoryUsage() / 1000);
 
             // Recursively process any orphan transactions that depended on this
             // one
             std::set<NodeId> setMisbehaving;
             while (!vWorkQueue.empty()) {
                 auto itByPrev =
                     mapOrphanTransactionsByPrev.find(vWorkQueue.front());
                 vWorkQueue.pop_front();
                 if (itByPrev == mapOrphanTransactionsByPrev.end()) {
                     continue;
                 }
                 for (auto mi = itByPrev->second.begin();
                      mi != itByPrev->second.end(); ++mi) {
                     const CTransactionRef &porphanTx = (*mi)->second.tx;
                     const CTransaction &orphanTx = *porphanTx;
                     const uint256 &orphanId = orphanTx.GetId();
                     NodeId fromPeer = (*mi)->second.fromPeer;
                     bool fMissingInputs2 = false;
                     // Use a dummy CValidationState so someone can't setup nodes
                     // to counter-DoS based on orphan resolution (that is,
                     // feeding people an invalid transaction based on LegitTxX
                     // in order to get anyone relaying LegitTxX banned)
                     CValidationState stateDummy;
 
                     if (setMisbehaving.count(fromPeer)) {
                         continue;
                     }
                     if (AcceptToMemoryPool(config, mempool, stateDummy,
                                            porphanTx, true, &fMissingInputs2,
                                            &lRemovedTxn)) {
                         LogPrint("mempool", "   accepted orphan tx %s\n",
                                  orphanId.ToString());
                         RelayTransaction(orphanTx, connman);
                         for (size_t i = 0; i < orphanTx.vout.size(); i++) {
                             vWorkQueue.emplace_back(orphanId, i);
                         }
                         vEraseQueue.push_back(orphanId);
                     } else if (!fMissingInputs2) {
                         int nDos = 0;
                         if (stateDummy.IsInvalid(nDos) && nDos > 0) {
                             // Punish peer that gave us an invalid orphan tx
                             Misbehaving(fromPeer, nDos, "invalid-orphan-tx");
                             setMisbehaving.insert(fromPeer);
                             LogPrint("mempool", "   invalid orphan tx %s\n",
                                      orphanId.ToString());
                         }
                         // Has inputs but not accepted to mempool
                         // Probably non-standard or insufficient fee/priority
                         LogPrint("mempool", "   removed orphan tx %s\n",
                                  orphanId.ToString());
                         vEraseQueue.push_back(orphanId);
                         if (!stateDummy.CorruptionPossible()) {
                             // Do not use rejection cache for witness
                             // transactions or witness-stripped transactions, as
                             // they can have been malleated. See
                             // https://github.com/bitcoin/bitcoin/issues/8279
                             // for details.
                             assert(recentRejects);
                             recentRejects->insert(orphanId);
                         }
                     }
                     mempool.check(pcoinsTip);
                 }
             }
 
             for (uint256 hash : vEraseQueue) {
                 EraseOrphanTx(hash);
             }
         } else if (fMissingInputs) {
             // It may be the case that the orphans parents have all been
             // rejected.
             bool fRejectedParents = false;
             for (const CTxIn &txin : tx.vin) {
                 if (recentRejects->contains(txin.prevout.hash)) {
                     fRejectedParents = true;
                     break;
                 }
             }
             if (!fRejectedParents) {
                 uint32_t nFetchFlags = GetFetchFlags(
                     pfrom, chainActive.Tip(), chainparams.GetConsensus());
                 for (const CTxIn &txin : tx.vin) {
                     CInv _inv(MSG_TX | nFetchFlags, txin.prevout.hash);
                     pfrom->AddInventoryKnown(_inv);
                     if (!AlreadyHave(_inv)) {
                         pfrom->AskFor(_inv);
                     }
                 }
                 AddOrphanTx(ptx, pfrom->GetId());
 
                 // DoS prevention: do not allow mapOrphanTransactions to grow
                 // unbounded
                 unsigned int nMaxOrphanTx = (unsigned int)std::max(
                     int64_t(0),
                     GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
                 unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx);
                 if (nEvicted > 0) {
                     LogPrint("mempool", "mapOrphan overflow, removed %u tx\n",
                              nEvicted);
                 }
             } else {
                 LogPrint("mempool",
                          "not keeping orphan with rejected parents %s\n",
                          tx.GetId().ToString());
                 // We will continue to reject this tx since it has rejected
                 // parents so avoid re-requesting it from other peers.
                 recentRejects->insert(tx.GetId());
             }
         } else {
             if (!state.CorruptionPossible()) {
                 // Do not use rejection cache for witness transactions or
                 // witness-stripped transactions, as they can have been
                 // malleated. See https://github.com/bitcoin/bitcoin/issues/8279
                 // for details.
                 assert(recentRejects);
                 recentRejects->insert(tx.GetId());
                 if (RecursiveDynamicUsage(*ptx) < 100000) {
                     AddToCompactExtraTransactions(ptx);
                 }
             }
 
             if (pfrom->fWhitelisted &&
                 GetBoolArg("-whitelistforcerelay",
                            DEFAULT_WHITELISTFORCERELAY)) {
                 // Always relay transactions received from whitelisted peers,
                 // even if they were already in the mempool or rejected from it
                 // due to policy, allowing the node to function as a gateway for
                 // nodes hidden behind it.
                 //
                 // Never relay transactions that we would assign a non-zero DoS
                 // score for, as we expect peers to do the same with us in that
                 // case.
                 int nDoS = 0;
                 if (!state.IsInvalid(nDoS) || nDoS == 0) {
                     LogPrintf("Force relaying tx %s from whitelisted peer=%d\n",
                               tx.GetId().ToString(), pfrom->id);
                     RelayTransaction(tx, connman);
                 } else {
                     LogPrintf("Not relaying invalid transaction %s from "
                               "whitelisted peer=%d (%s)\n",
                               tx.GetId().ToString(), pfrom->id,
                               FormatStateMessage(state));
                 }
             }
         }
 
         for (const CTransactionRef &removedTx : lRemovedTxn) {
             AddToCompactExtraTransactions(removedTx);
         }
 
         int nDoS = 0;
         if (state.IsInvalid(nDoS)) {
             LogPrint("mempoolrej", "%s from peer=%d was not accepted: %s\n",
                      tx.GetId().ToString(), pfrom->id,
                      FormatStateMessage(state));
             // Never send AcceptToMemoryPool's internal codes over P2P.
             if (state.GetRejectCode() < REJECT_INTERNAL) {
                 connman.PushMessage(
                     pfrom, msgMaker.Make(NetMsgType::REJECT, strCommand,
-                                         (unsigned char)state.GetRejectCode(),
+                                         uint8_t(state.GetRejectCode()),
                                          state.GetRejectReason().substr(
                                              0, MAX_REJECT_MESSAGE_LENGTH),
                                          inv.hash));
             }
             if (nDoS > 0) {
                 Misbehaving(pfrom, nDoS, state.GetRejectReason());
             }
         }
     }
 
     // Ignore blocks received while importing
     else if (strCommand == NetMsgType::CMPCTBLOCK && !fImporting && !fReindex) {
         CBlockHeaderAndShortTxIDs cmpctblock;
         vRecv >> cmpctblock;
 
         {
             LOCK(cs_main);
 
             if (mapBlockIndex.find(cmpctblock.header.hashPrevBlock) ==
                 mapBlockIndex.end()) {
                 // Doesn't connect (or is genesis), instead of DoSing in
                 // AcceptBlockHeader, request deeper headers
                 if (!IsInitialBlockDownload()) {
                     connman.PushMessage(
                         pfrom,
                         msgMaker.Make(NetMsgType::GETHEADERS,
                                       chainActive.GetLocator(pindexBestHeader),
                                       uint256()));
                 }
                 return true;
             }
         }
 
         const CBlockIndex *pindex = nullptr;
         CValidationState state;
         if (!ProcessNewBlockHeaders(config, {cmpctblock.header}, state,
                                     &pindex)) {
             int nDoS;
             if (state.IsInvalid(nDoS)) {
                 if (nDoS > 0) {
                     LOCK(cs_main);
                     Misbehaving(pfrom, nDoS, state.GetRejectReason());
                 }
                 LogPrintf("Peer %d sent us invalid header via cmpctblock\n",
                           pfrom->id);
                 return true;
             }
         }
 
         // When we succeed in decoding a block's txids from a cmpctblock
         // message we typically jump to the BLOCKTXN handling code, with a
         // dummy (empty) BLOCKTXN message, to re-use the logic there in
         // completing processing of the putative block (without cs_main).
         bool fProcessBLOCKTXN = false;
         CDataStream blockTxnMsg(SER_NETWORK, PROTOCOL_VERSION);
 
         // If we end up treating this as a plain headers message, call that as
         // well
         // without cs_main.
         bool fRevertToHeaderProcessing = false;
         CDataStream vHeadersMsg(SER_NETWORK, PROTOCOL_VERSION);
 
         // Keep a CBlock for "optimistic" compactblock reconstructions (see
         // below)
         std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
         bool fBlockReconstructed = false;
 
         {
             LOCK(cs_main);
             // If AcceptBlockHeader returned true, it set pindex
             assert(pindex);
             UpdateBlockAvailability(pfrom->GetId(), pindex->GetBlockHash());
 
             std::map<uint256,
                      std::pair<NodeId, std::list<QueuedBlock>::iterator>>::
                 iterator blockInFlightIt =
                     mapBlocksInFlight.find(pindex->GetBlockHash());
             bool fAlreadyInFlight = blockInFlightIt != mapBlocksInFlight.end();
 
             if (pindex->nStatus & BLOCK_HAVE_DATA) {
                 // Nothing to do here
                 return true;
             }
 
             if (pindex->nChainWork <=
                     chainActive.Tip()->nChainWork || // We know something better
                 pindex->nTx != 0) {
                 // We had this block at some point, but pruned it
                 if (fAlreadyInFlight) {
                     // We requested this block for some reason, but our mempool
                     // will probably be useless so we just grab the block via
                     // normal getdata.
                     std::vector<CInv> vInv(1);
                     vInv[0] = CInv(
                         MSG_BLOCK | GetFetchFlags(pfrom, pindex->pprev,
                                                   chainparams.GetConsensus()),
                         cmpctblock.header.GetHash());
                     connman.PushMessage(
                         pfrom, msgMaker.Make(NetMsgType::GETDATA, vInv));
                 }
                 return true;
             }
 
             // If we're not close to tip yet, give up and let parallel block
             // fetch work its magic.
             if (!fAlreadyInFlight &&
                 !CanDirectFetch(chainparams.GetConsensus())) {
                 return true;
             }
 
             CNodeState *nodestate = State(pfrom->GetId());
 
             // We want to be a bit conservative just to be extra careful about
             // DoS possibilities in compact block processing...
             if (pindex->nHeight <= chainActive.Height() + 2) {
                 if ((!fAlreadyInFlight &&
                      nodestate->nBlocksInFlight <
                          MAX_BLOCKS_IN_TRANSIT_PER_PEER) ||
                     (fAlreadyInFlight &&
                      blockInFlightIt->second.first == pfrom->GetId())) {
                     std::list<QueuedBlock>::iterator *queuedBlockIt = nullptr;
                     if (!MarkBlockAsInFlight(config, pfrom->GetId(),
                                              pindex->GetBlockHash(),
                                              chainparams.GetConsensus(), pindex,
                                              &queuedBlockIt)) {
                         if (!(*queuedBlockIt)->partialBlock) {
                             (*queuedBlockIt)
                                 ->partialBlock.reset(
                                     new PartiallyDownloadedBlock(config,
                                                                  &mempool));
                         } else {
                             // The block was already in flight using compact
                             // blocks from the same peer.
                             LogPrint("net", "Peer sent us compact block we "
                                             "were already syncing!\n");
                             return true;
                         }
                     }
 
                     PartiallyDownloadedBlock &partialBlock =
                         *(*queuedBlockIt)->partialBlock;
                     ReadStatus status =
                         partialBlock.InitData(cmpctblock, vExtraTxnForCompact);
                     if (status == READ_STATUS_INVALID) {
                         // Reset in-flight state in case of whitelist
                         MarkBlockAsReceived(pindex->GetBlockHash());
                         Misbehaving(pfrom, 100, "invalid-cmpctblk");
                         LogPrintf("Peer %d sent us invalid compact block\n",
                                   pfrom->id);
                         return true;
                     } else if (status == READ_STATUS_FAILED) {
                         // Duplicate txindexes, the block is now in-flight, so
                         // just request it.
                         std::vector<CInv> vInv(1);
                         vInv[0] =
                             CInv(MSG_BLOCK |
                                      GetFetchFlags(pfrom, pindex->pprev,
                                                    chainparams.GetConsensus()),
                                  cmpctblock.header.GetHash());
                         connman.PushMessage(
                             pfrom, msgMaker.Make(NetMsgType::GETDATA, vInv));
                         return true;
                     }
 
                     BlockTransactionsRequest req;
                     for (size_t i = 0; i < cmpctblock.BlockTxCount(); i++) {
                         if (!partialBlock.IsTxAvailable(i)) {
                             req.indexes.push_back(i);
                         }
                     }
                     if (req.indexes.empty()) {
                         // Dirty hack to jump to BLOCKTXN code (TODO: move
                         // message handling into their own functions)
                         BlockTransactions txn;
                         txn.blockhash = cmpctblock.header.GetHash();
                         blockTxnMsg << txn;
                         fProcessBLOCKTXN = true;
                     } else {
                         req.blockhash = pindex->GetBlockHash();
                         connman.PushMessage(
                             pfrom, msgMaker.Make(NetMsgType::GETBLOCKTXN, req));
                     }
                 } else {
                     // This block is either already in flight from a different
                     // peer, or this peer has too many blocks outstanding to
                     // download from. Optimistically try to reconstruct anyway
                     // since we might be able to without any round trips.
                     PartiallyDownloadedBlock tempBlock(config, &mempool);
                     ReadStatus status =
                         tempBlock.InitData(cmpctblock, vExtraTxnForCompact);
                     if (status != READ_STATUS_OK) {
                         // TODO: don't ignore failures
                         return true;
                     }
                     std::vector<CTransactionRef> dummy;
                     status = tempBlock.FillBlock(*pblock, dummy);
                     if (status == READ_STATUS_OK) {
                         fBlockReconstructed = true;
                     }
                 }
             } else {
                 if (fAlreadyInFlight) {
                     // We requested this block, but its far into the future, so
                     // our mempool will probably be useless - request the block
                     // normally.
                     std::vector<CInv> vInv(1);
                     vInv[0] = CInv(
                         MSG_BLOCK | GetFetchFlags(pfrom, pindex->pprev,
                                                   chainparams.GetConsensus()),
                         cmpctblock.header.GetHash());
                     connman.PushMessage(
                         pfrom, msgMaker.Make(NetMsgType::GETDATA, vInv));
                     return true;
                 } else {
                     // If this was an announce-cmpctblock, we want the same
                     // treatment as a header message. Dirty hack to process as
                     // if it were just a headers message (TODO: move message
                     // handling into their own functions)
                     std::vector<CBlock> headers;
                     headers.push_back(cmpctblock.header);
                     vHeadersMsg << headers;
                     fRevertToHeaderProcessing = true;
                 }
             }
         } // cs_main
 
         if (fProcessBLOCKTXN) {
             return ProcessMessage(config, pfrom, NetMsgType::BLOCKTXN,
                                   blockTxnMsg, nTimeReceived, chainparams,
                                   connman, interruptMsgProc);
         }
 
         if (fRevertToHeaderProcessing) {
             return ProcessMessage(config, pfrom, NetMsgType::HEADERS,
                                   vHeadersMsg, nTimeReceived, chainparams,
                                   connman, interruptMsgProc);
         }
 
         if (fBlockReconstructed) {
             // If we got here, we were able to optimistically reconstruct a
             // block that is in flight from some other peer.
             {
                 LOCK(cs_main);
                 mapBlockSource.emplace(pblock->GetHash(),
                                        std::make_pair(pfrom->GetId(), false));
             }
             bool fNewBlock = false;
             ProcessNewBlock(config, pblock, true, &fNewBlock);
             if (fNewBlock) {
                 pfrom->nLastBlockTime = GetTime();
             }
 
             // hold cs_main for CBlockIndex::IsValid()
             LOCK(cs_main);
             if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS)) {
                 // Clear download state for this block, which is in process from
                 // some other peer. We do this after calling. ProcessNewBlock so
                 // that a malleated cmpctblock announcement can't be used to
                 // interfere with block relay.
                 MarkBlockAsReceived(pblock->GetHash());
             }
         }
 
     }
 
     else if (strCommand == NetMsgType::BLOCKTXN && !fImporting &&
              !fReindex) // Ignore blocks received while importing
     {
         BlockTransactions resp;
         vRecv >> resp;
 
         std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
         bool fBlockRead = false;
         {
             LOCK(cs_main);
 
             std::map<uint256,
                      std::pair<NodeId,
                                std::list<QueuedBlock>::iterator>>::iterator it =
                 mapBlocksInFlight.find(resp.blockhash);
             if (it == mapBlocksInFlight.end() ||
                 !it->second.second->partialBlock ||
                 it->second.first != pfrom->GetId()) {
                 LogPrint("net", "Peer %d sent us block transactions for block "
                                 "we weren't expecting\n",
                          pfrom->id);
                 return true;
             }
 
             PartiallyDownloadedBlock &partialBlock =
                 *it->second.second->partialBlock;
             ReadStatus status = partialBlock.FillBlock(*pblock, resp.txn);
             if (status == READ_STATUS_INVALID) {
                 // Reset in-flight state in case of whitelist.
                 MarkBlockAsReceived(resp.blockhash);
                 Misbehaving(pfrom, 100, "invalid-cmpctblk-txns");
                 LogPrintf("Peer %d sent us invalid compact block/non-matching "
                           "block transactions\n",
                           pfrom->id);
                 return true;
             } else if (status == READ_STATUS_FAILED) {
                 // Might have collided, fall back to getdata now :(
                 std::vector<CInv> invs;
                 invs.push_back(
                     CInv(MSG_BLOCK | GetFetchFlags(pfrom, chainActive.Tip(),
                                                    chainparams.GetConsensus()),
                          resp.blockhash));
                 connman.PushMessage(pfrom,
                                     msgMaker.Make(NetMsgType::GETDATA, invs));
             } else {
                 // Block is either okay, or possibly we received
                 // READ_STATUS_CHECKBLOCK_FAILED.
                 // Note that CheckBlock can only fail for one of a few reasons:
                 // 1. bad-proof-of-work (impossible here, because we've already
                 //    accepted the header)
                 // 2. merkleroot doesn't match the transactions given (already
                 //    caught in FillBlock with READ_STATUS_FAILED, so
                 //    impossible here)
                 // 3. the block is otherwise invalid (eg invalid coinbase,
                 //    block is too big, too many legacy sigops, etc).
                 // So if CheckBlock failed, #3 is the only possibility.
                 // Under BIP 152, we don't DoS-ban unless proof of work is
                 // invalid (we don't require all the stateless checks to have
                 // been run). This is handled below, so just treat this as
                 // though the block was successfully read, and rely on the
                 // handling in ProcessNewBlock to ensure the block index is
                 // updated, reject messages go out, etc.
 
                 // it is now an empty pointer
                 MarkBlockAsReceived(resp.blockhash);
                 fBlockRead = true;
                 // mapBlockSource is only used for sending reject messages and
                 // DoS scores, so the race between here and cs_main in
                 // ProcessNewBlock is fine. BIP 152 permits peers to relay
                 // compact blocks after validating the header only; we should
                 // not punish peers if the block turns out to be invalid.
                 mapBlockSource.emplace(resp.blockhash,
                                        std::make_pair(pfrom->GetId(), false));
             }
         } // Don't hold cs_main when we call into ProcessNewBlock
         if (fBlockRead) {
             bool fNewBlock = false;
             // Since we requested this block (it was in mapBlocksInFlight),
             // force it to be processed, even if it would not be a candidate for
             // new tip (missing previous block, chain not long enough, etc)
             ProcessNewBlock(config, pblock, true, &fNewBlock);
             if (fNewBlock) {
                 pfrom->nLastBlockTime = GetTime();
             }
         }
     }
 
     // Ignore headers received while importing
     else if (strCommand == NetMsgType::HEADERS && !fImporting && !fReindex) {
         std::vector<CBlockHeader> headers;
 
         // Bypass the normal CBlock deserialization, as we don't want to risk
         // deserializing 2000 full blocks.
         unsigned int nCount = ReadCompactSize(vRecv);
         if (nCount > MAX_HEADERS_RESULTS) {
             LOCK(cs_main);
             Misbehaving(pfrom, 20, "too-many-headers");
             return error("headers message size = %u", nCount);
         }
         headers.resize(nCount);
         for (unsigned int n = 0; n < nCount; n++) {
             vRecv >> headers[n];
             // Ignore tx count; assume it is 0.
             ReadCompactSize(vRecv);
         }
 
         if (nCount == 0) {
             // Nothing interesting. Stop asking this peers for more headers.
             return true;
         }
 
         const CBlockIndex *pindexLast = nullptr;
         {
             LOCK(cs_main);
             CNodeState *nodestate = State(pfrom->GetId());
 
             // If this looks like it could be a block announcement (nCount <
             // MAX_BLOCKS_TO_ANNOUNCE), use special logic for handling headers
             // that
             // don't connect:
             // - Send a getheaders message in response to try to connect the
             // chain.
             // - The peer can send up to MAX_UNCONNECTING_HEADERS in a row that
             //   don't connect before giving DoS points
             // - Once a headers message is received that is valid and does
             // connect,
             //   nUnconnectingHeaders gets reset back to 0.
             if (mapBlockIndex.find(headers[0].hashPrevBlock) ==
                     mapBlockIndex.end() &&
                 nCount < MAX_BLOCKS_TO_ANNOUNCE) {
                 nodestate->nUnconnectingHeaders++;
                 connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::GETHEADERS,
                                                          chainActive.GetLocator(
                                                              pindexBestHeader),
                                                          uint256()));
                 LogPrint("net", "received header %s: missing prev block %s, "
                                 "sending getheaders (%d) to end (peer=%d, "
                                 "nUnconnectingHeaders=%d)\n",
                          headers[0].GetHash().ToString(),
                          headers[0].hashPrevBlock.ToString(),
                          pindexBestHeader->nHeight, pfrom->id,
                          nodestate->nUnconnectingHeaders);
                 // Set hashLastUnknownBlock for this peer, so that if we
                 // eventually get the headers - even from a different peer -
                 // we can use this peer to download.
                 UpdateBlockAvailability(pfrom->GetId(),
                                         headers.back().GetHash());
 
                 if (nodestate->nUnconnectingHeaders %
                         MAX_UNCONNECTING_HEADERS ==
                     0) {
                     // The peer is sending us many headers we can't connect.
                     Misbehaving(pfrom, 20, "too-many-unconnected-headers");
                 }
                 return true;
             }
 
             uint256 hashLastBlock;
             for (const CBlockHeader &header : headers) {
                 if (!hashLastBlock.IsNull() &&
                     header.hashPrevBlock != hashLastBlock) {
                     Misbehaving(pfrom, 20, "disconnected-header");
                     return error("non-continuous headers sequence");
                 }
                 hashLastBlock = header.GetHash();
             }
         }
 
         CValidationState state;
         if (!ProcessNewBlockHeaders(config, headers, state, &pindexLast)) {
             int nDoS;
             if (state.IsInvalid(nDoS)) {
                 if (nDoS > 0) {
                     LOCK(cs_main);
                     Misbehaving(pfrom, nDoS, state.GetRejectReason());
                 }
                 return error("invalid header received");
             }
         }
 
         {
             LOCK(cs_main);
             CNodeState *nodestate = State(pfrom->GetId());
             if (nodestate->nUnconnectingHeaders > 0) {
                 LogPrint("net",
                          "peer=%d: resetting nUnconnectingHeaders (%d -> 0)\n",
                          pfrom->id, nodestate->nUnconnectingHeaders);
             }
             nodestate->nUnconnectingHeaders = 0;
 
             assert(pindexLast);
             UpdateBlockAvailability(pfrom->GetId(), pindexLast->GetBlockHash());
 
             if (nCount == MAX_HEADERS_RESULTS) {
                 // Headers message had its maximum size; the peer may have more
                 // headers.
                 // TODO: optimize: if pindexLast is an ancestor of
                 // chainActive.Tip or pindexBestHeader, continue from there
                 // instead.
                 LogPrint(
                     "net",
                     "more getheaders (%d) to end to peer=%d (startheight:%d)\n",
                     pindexLast->nHeight, pfrom->id, pfrom->nStartingHeight);
                 connman.PushMessage(
                     pfrom, msgMaker.Make(NetMsgType::GETHEADERS,
                                          chainActive.GetLocator(pindexLast),
                                          uint256()));
             }
 
             bool fCanDirectFetch = CanDirectFetch(chainparams.GetConsensus());
             // If this set of headers is valid and ends in a block with at least
             // as much work as our tip, download as much as possible.
             if (fCanDirectFetch && pindexLast->IsValid(BLOCK_VALID_TREE) &&
                 chainActive.Tip()->nChainWork <= pindexLast->nChainWork) {
                 std::vector<const CBlockIndex *> vToFetch;
                 const CBlockIndex *pindexWalk = pindexLast;
                 // Calculate all the blocks we'd need to switch to pindexLast,
                 // up to a limit.
                 while (pindexWalk && !chainActive.Contains(pindexWalk) &&
                        vToFetch.size() <= MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
                     if (!(pindexWalk->nStatus & BLOCK_HAVE_DATA) &&
                         !mapBlocksInFlight.count(pindexWalk->GetBlockHash())) {
                         // We don't have this block, and it's not yet in flight.
                         vToFetch.push_back(pindexWalk);
                     }
                     pindexWalk = pindexWalk->pprev;
                 }
                 // If pindexWalk still isn't on our main chain, we're looking at
                 // a very large reorg at a time we think we're close to caught
                 // up to the main chain -- this shouldn't really happen. Bail
                 // out on the direct fetch and rely on parallel download
                 // instead.
                 if (!chainActive.Contains(pindexWalk)) {
                     LogPrint("net",
                              "Large reorg, won't direct fetch to %s (%d)\n",
                              pindexLast->GetBlockHash().ToString(),
                              pindexLast->nHeight);
                 } else {
                     std::vector<CInv> vGetData;
                     // Download as much as possible, from earliest to latest.
                     for (const CBlockIndex *pindex :
                          boost::adaptors::reverse(vToFetch)) {
                         if (nodestate->nBlocksInFlight >=
                             MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
                             // Can't download any more from this peer
                             break;
                         }
                         uint32_t nFetchFlags = GetFetchFlags(
                             pfrom, pindex->pprev, chainparams.GetConsensus());
                         vGetData.push_back(CInv(MSG_BLOCK | nFetchFlags,
                                                 pindex->GetBlockHash()));
                         MarkBlockAsInFlight(config, pfrom->GetId(),
                                             pindex->GetBlockHash(),
                                             chainparams.GetConsensus(), pindex);
                         LogPrint("net", "Requesting block %s from  peer=%d\n",
                                  pindex->GetBlockHash().ToString(), pfrom->id);
                     }
                     if (vGetData.size() > 1) {
                         LogPrint("net", "Downloading blocks toward %s (%d) via "
                                         "headers direct fetch\n",
                                  pindexLast->GetBlockHash().ToString(),
                                  pindexLast->nHeight);
                     }
                     if (vGetData.size() > 0) {
                         if (nodestate->fSupportsDesiredCmpctVersion &&
                             vGetData.size() == 1 &&
                             mapBlocksInFlight.size() == 1 &&
                             pindexLast->pprev->IsValid(BLOCK_VALID_CHAIN)) {
                             // In any case, we want to download using a compact
                             // block, not a regular one.
                             vGetData[0] =
                                 CInv(MSG_CMPCT_BLOCK, vGetData[0].hash);
                         }
                         connman.PushMessage(
                             pfrom,
                             msgMaker.Make(NetMsgType::GETDATA, vGetData));
                     }
                 }
             }
         }
     }
 
     else if (strCommand == NetMsgType::BLOCK && !fImporting &&
              !fReindex) // Ignore blocks received while importing
     {
         std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
         vRecv >> *pblock;
 
         LogPrint("net", "received block %s peer=%d\n",
                  pblock->GetHash().ToString(), pfrom->id);
 
         // Process all blocks from whitelisted peers, even if not requested,
         // unless we're still syncing with the network. Such an unrequested
         // block may still be processed, subject to the conditions in
         // AcceptBlock().
         bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload();
         const uint256 hash(pblock->GetHash());
         {
             LOCK(cs_main);
             // Also always process if we requested the block explicitly, as we
             // may need it even though it is not a candidate for a new best tip.
             forceProcessing |= MarkBlockAsReceived(hash);
             // mapBlockSource is only used for sending reject messages and DoS
             // scores, so the race between here and cs_main in ProcessNewBlock
             // is fine.
             mapBlockSource.emplace(hash, std::make_pair(pfrom->GetId(), true));
         }
         bool fNewBlock = false;
         ProcessNewBlock(config, pblock, forceProcessing, &fNewBlock);
         if (fNewBlock) {
             pfrom->nLastBlockTime = GetTime();
         }
     }
 
     else if (strCommand == NetMsgType::GETADDR) {
         // This asymmetric behavior for inbound and outbound connections was
         // introduced to prevent a fingerprinting attack: an attacker can send
         // specific fake addresses to users' AddrMan and later request them by
         // sending getaddr messages. Making nodes which are behind NAT and can
         // only make outgoing connections ignore the getaddr message mitigates
         // the attack.
         if (!pfrom->fInbound) {
             LogPrint("net",
                      "Ignoring \"getaddr\" from outbound connection. peer=%d\n",
                      pfrom->id);
             return true;
         }
 
         // Only send one GetAddr response per connection to reduce resource
         // waste and discourage addr stamping of INV announcements.
         if (pfrom->fSentAddr) {
             LogPrint("net", "Ignoring repeated \"getaddr\". peer=%d\n",
                      pfrom->id);
             return true;
         }
         pfrom->fSentAddr = true;
 
         pfrom->vAddrToSend.clear();
         std::vector<CAddress> vAddr = connman.GetAddresses();
         FastRandomContext insecure_rand;
         for (const CAddress &addr : vAddr) {
             pfrom->PushAddress(addr, insecure_rand);
         }
     }
 
     else if (strCommand == NetMsgType::MEMPOOL) {
         if (!(pfrom->GetLocalServices() & NODE_BLOOM) && !pfrom->fWhitelisted) {
             LogPrint("net", "mempool request with bloom filters disabled, "
                             "disconnect peer=%d\n",
                      pfrom->GetId());
             pfrom->fDisconnect = true;
             return true;
         }
 
         if (connman.OutboundTargetReached(false) && !pfrom->fWhitelisted) {
             LogPrint("net", "mempool request with bandwidth limit reached, "
                             "disconnect peer=%d\n",
                      pfrom->GetId());
             pfrom->fDisconnect = true;
             return true;
         }
 
         LOCK(pfrom->cs_inventory);
         pfrom->fSendMempool = true;
     }
 
     else if (strCommand == NetMsgType::PING) {
         if (pfrom->nVersion > BIP0031_VERSION) {
             uint64_t nonce = 0;
             vRecv >> nonce;
             // Echo the message back with the nonce. This allows for two useful
             // features:
             //
             // 1) A remote node can quickly check if the connection is
             // operational.
             // 2) Remote nodes can measure the latency of the network thread. If
             // this node is overloaded it won't respond to pings quickly and the
             // remote node can avoid sending us more work, like chain download
             // requests.
             //
             // The nonce stops the remote getting confused between different
             // pings: without it, if the remote node sends a ping once per
             // second and this node takes 5 seconds to respond to each, the 5th
             // ping the remote sends would appear to return very quickly.
             connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::PONG, nonce));
         }
     }
 
     else if (strCommand == NetMsgType::PONG) {
         int64_t pingUsecEnd = nTimeReceived;
         uint64_t nonce = 0;
         size_t nAvail = vRecv.in_avail();
         bool bPingFinished = false;
         std::string sProblem;
 
         if (nAvail >= sizeof(nonce)) {
             vRecv >> nonce;
 
             // Only process pong message if there is an outstanding ping (old
             // ping without nonce should never pong)
             if (pfrom->nPingNonceSent != 0) {
                 if (nonce == pfrom->nPingNonceSent) {
                     // Matching pong received, this ping is no longer
                     // outstanding
                     bPingFinished = true;
                     int64_t pingUsecTime = pingUsecEnd - pfrom->nPingUsecStart;
                     if (pingUsecTime > 0) {
                         // Successful ping time measurement, replace previous
                         pfrom->nPingUsecTime = pingUsecTime;
                         pfrom->nMinPingUsecTime = std::min(
                             pfrom->nMinPingUsecTime.load(), pingUsecTime);
                     } else {
                         // This should never happen
                         sProblem = "Timing mishap";
                     }
                 } else {
                     // Nonce mismatches are normal when pings are overlapping
                     sProblem = "Nonce mismatch";
                     if (nonce == 0) {
                         // This is most likely a bug in another implementation
                         // somewhere; cancel this ping
                         bPingFinished = true;
                         sProblem = "Nonce zero";
                     }
                 }
             } else {
                 sProblem = "Unsolicited pong without ping";
             }
         } else {
             // This is most likely a bug in another implementation somewhere;
             // cancel this ping
             bPingFinished = true;
             sProblem = "Short payload";
         }
 
         if (!(sProblem.empty())) {
             LogPrint("net",
                      "pong peer=%d: %s, %x expected, %x received, %u bytes\n",
                      pfrom->id, sProblem, pfrom->nPingNonceSent, nonce, nAvail);
         }
         if (bPingFinished) {
             pfrom->nPingNonceSent = 0;
         }
     }
 
     else if (strCommand == NetMsgType::FILTERLOAD) {
         CBloomFilter filter;
         vRecv >> filter;
 
         if (!filter.IsWithinSizeConstraints()) {
             // There is no excuse for sending a too-large filter
             LOCK(cs_main);
             Misbehaving(pfrom, 100, "oversized-bloom-filter");
         } else {
             LOCK(pfrom->cs_filter);
             delete pfrom->pfilter;
             pfrom->pfilter = new CBloomFilter(filter);
             pfrom->pfilter->UpdateEmptyFull();
             pfrom->fRelayTxes = true;
         }
     }
 
     else if (strCommand == NetMsgType::FILTERADD) {
-        std::vector<unsigned char> vData;
+        std::vector<uint8_t> vData;
         vRecv >> vData;
 
         // Nodes must NEVER send a data item > 520 bytes (the max size for a
         // script data object, and thus, the maximum size any matched object can
         // have) in a filteradd message.
         bool bad = false;
         if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE) {
             bad = true;
         } else {
             LOCK(pfrom->cs_filter);
             if (pfrom->pfilter) {
                 pfrom->pfilter->insert(vData);
             } else {
                 bad = true;
             }
         }
         if (bad) {
             LOCK(cs_main);
             // The structure of this code doesn't really allow for a good error
             // code. We'll go generic.
             Misbehaving(pfrom, 100, "invalid-filteradd");
         }
     }
 
     else if (strCommand == NetMsgType::FILTERCLEAR) {
         LOCK(pfrom->cs_filter);
         if (pfrom->GetLocalServices() & NODE_BLOOM) {
             delete pfrom->pfilter;
             pfrom->pfilter = new CBloomFilter();
         }
         pfrom->fRelayTxes = true;
     }
 
     else if (strCommand == NetMsgType::FEEFILTER) {
         CAmount newFeeFilter = 0;
         vRecv >> newFeeFilter;
         if (MoneyRange(newFeeFilter)) {
             {
                 LOCK(pfrom->cs_feeFilter);
                 pfrom->minFeeFilter = newFeeFilter;
             }
             LogPrint("net", "received: feefilter of %s from peer=%d\n",
                      CFeeRate(newFeeFilter).ToString(), pfrom->id);
         }
     }
 
     else if (strCommand == NetMsgType::NOTFOUND) {
         // We do not care about the NOTFOUND message, but logging an Unknown
         // Command message would be undesirable as we transmit it ourselves.
     }
 
     else {
         // Ignore unknown commands for extensibility
         LogPrint("net", "Unknown command \"%s\" from peer=%d\n",
                  SanitizeString(strCommand), pfrom->id);
     }
 
     return true;
 }
 
 static bool SendRejectsAndCheckIfBanned(CNode *pnode, CConnman &connman) {
     AssertLockHeld(cs_main);
     CNodeState &state = *State(pnode->GetId());
 
     for (const CBlockReject &reject : state.rejects) {
         connman.PushMessage(
             pnode, CNetMsgMaker(INIT_PROTO_VERSION)
                        .Make(NetMsgType::REJECT, (std::string)NetMsgType::BLOCK,
                              reject.chRejectCode, reject.strRejectReason,
                              reject.hashBlock));
     }
     state.rejects.clear();
 
     if (state.fShouldBan) {
         state.fShouldBan = false;
         if (pnode->fWhitelisted) {
             LogPrintf("Warning: not punishing whitelisted peer %s!\n",
                       pnode->addr.ToString());
         } else if (pnode->fAddnode) {
             LogPrintf("Warning: not punishing addnoded peer %s!\n",
                       pnode->addr.ToString());
         } else {
             pnode->fDisconnect = true;
             if (pnode->addr.IsLocal()) {
                 LogPrintf("Warning: not banning local peer %s!\n",
                           pnode->addr.ToString());
             } else {
                 connman.Ban(pnode->addr, BanReasonNodeMisbehaving);
             }
         }
         return true;
     }
     return false;
 }
 
 bool ProcessMessages(const Config &config, CNode *pfrom, CConnman &connman,
                      const std::atomic<bool> &interruptMsgProc) {
     const CChainParams &chainparams = Params();
     //
     // Message format
     //  (4) message start
     //  (12) command
     //  (4) size
     //  (4) checksum
     //  (x) data
     //
     bool fMoreWork = false;
 
     if (!pfrom->vRecvGetData.empty()) {
         ProcessGetData(config, pfrom, chainparams.GetConsensus(), connman,
                        interruptMsgProc);
     }
 
     if (pfrom->fDisconnect) {
         return false;
     }
 
     // this maintains the order of responses
     if (!pfrom->vRecvGetData.empty()) {
         return true;
     }
 
     // Don't bother if send buffer is too full to respond anyway
     if (pfrom->fPauseSend) {
         return false;
     }
 
     std::list<CNetMessage> msgs;
     {
         LOCK(pfrom->cs_vProcessMsg);
         if (pfrom->vProcessMsg.empty()) {
             return false;
         }
         // Just take one message
         msgs.splice(msgs.begin(), pfrom->vProcessMsg,
                     pfrom->vProcessMsg.begin());
         pfrom->nProcessQueueSize -=
             msgs.front().vRecv.size() + CMessageHeader::HEADER_SIZE;
         pfrom->fPauseRecv =
             pfrom->nProcessQueueSize > connman.GetReceiveFloodSize();
         fMoreWork = !pfrom->vProcessMsg.empty();
     }
     CNetMessage &msg(msgs.front());
 
     msg.SetVersion(pfrom->GetRecvVersion());
 
     // This is a new peer. Before doing anything, we need to detect what magic
     // the peer is using.
     if (pfrom->nVersion == 0 &&
         memcmp(msg.hdr.pchMessageStart, chainparams.CashMessageStart(),
                CMessageHeader::MESSAGE_START_SIZE) == 0) {
         pfrom->fUsesCashMagic = true;
     }
 
     // Scan for message start
     if (memcmp(msg.hdr.pchMessageStart, pfrom->GetMagic(chainparams),
                CMessageHeader::MESSAGE_START_SIZE) != 0) {
         LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n",
                   SanitizeString(msg.hdr.GetCommand()), pfrom->id);
         pfrom->fDisconnect = true;
         return false;
     }
 
     // Read header
     CMessageHeader &hdr = msg.hdr;
     if (!hdr.IsValid(pfrom->GetMagic(chainparams))) {
         LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n",
                   SanitizeString(hdr.GetCommand()), pfrom->id);
         return fMoreWork;
     }
     std::string strCommand = hdr.GetCommand();
 
     // Message size
     unsigned int nMessageSize = hdr.nMessageSize;
 
     // Checksum
     CDataStream &vRecv = msg.vRecv;
     const uint256 &hash = msg.GetMessageHash();
     if (memcmp(hash.begin(), hdr.pchChecksum, CMessageHeader::CHECKSUM_SIZE) !=
         0) {
         LogPrintf(
             "%s(%s, %u bytes): CHECKSUM ERROR expected %s was %s\n", __func__,
             SanitizeString(strCommand), nMessageSize,
             HexStr(hash.begin(), hash.begin() + CMessageHeader::CHECKSUM_SIZE),
             HexStr(hdr.pchChecksum,
                    hdr.pchChecksum + CMessageHeader::CHECKSUM_SIZE));
         return fMoreWork;
     }
 
     // Process message
     bool fRet = false;
     try {
         fRet = ProcessMessage(config, pfrom, strCommand, vRecv, msg.nTime,
                               chainparams, connman, interruptMsgProc);
         if (interruptMsgProc) {
             return false;
         }
         if (!pfrom->vRecvGetData.empty()) {
             fMoreWork = true;
         }
     } catch (const std::ios_base::failure &e) {
         connman.PushMessage(
             pfrom, CNetMsgMaker(INIT_PROTO_VERSION)
                        .Make(NetMsgType::REJECT, strCommand, REJECT_MALFORMED,
                              std::string("error parsing message")));
         if (strstr(e.what(), "end of data")) {
             // Allow exceptions from under-length message on vRecv
             LogPrintf(
                 "%s(%s, %u bytes): Exception '%s' caught, normally caused by a "
                 "message being shorter than its stated length\n",
                 __func__, SanitizeString(strCommand), nMessageSize, e.what());
         } else if (strstr(e.what(), "size too large")) {
             // Allow exceptions from over-long size
             LogPrintf("%s(%s, %u bytes): Exception '%s' caught\n", __func__,
                       SanitizeString(strCommand), nMessageSize, e.what());
         } else if (strstr(e.what(), "non-canonical ReadCompactSize()")) {
             // Allow exceptions from non-canonical encoding
             LogPrintf("%s(%s, %u bytes): Exception '%s' caught\n", __func__,
                       SanitizeString(strCommand), nMessageSize, e.what());
         } else {
             PrintExceptionContinue(&e, "ProcessMessages()");
         }
     } catch (const std::exception &e) {
         PrintExceptionContinue(&e, "ProcessMessages()");
     } catch (...) {
         PrintExceptionContinue(nullptr, "ProcessMessages()");
     }
 
     if (!fRet) {
         LogPrintf("%s(%s, %u bytes) FAILED peer=%d\n", __func__,
                   SanitizeString(strCommand), nMessageSize, pfrom->id);
     }
 
     LOCK(cs_main);
     SendRejectsAndCheckIfBanned(pfrom, connman);
 
     return fMoreWork;
 }
 
 class CompareInvMempoolOrder {
     CTxMemPool *mp;
 
 public:
     CompareInvMempoolOrder(CTxMemPool *_mempool) { mp = _mempool; }
 
     bool operator()(std::set<uint256>::iterator a,
                     std::set<uint256>::iterator b) {
         /* As std::make_heap produces a max-heap, we want the entries with the
          * fewest ancestors/highest fee to sort later. */
         return mp->CompareDepthAndScore(*b, *a);
     }
 };
 
 bool SendMessages(const Config &config, CNode *pto, CConnman &connman,
                   const std::atomic<bool> &interruptMsgProc) {
     const Consensus::Params &consensusParams = Params().GetConsensus();
 
     // Don't send anything until the version handshake is complete
     if (!pto->fSuccessfullyConnected || pto->fDisconnect) {
         return true;
     }
 
     // If we get here, the outgoing message serialization version is set and
     // can't change.
     const CNetMsgMaker msgMaker(pto->GetSendVersion());
 
     //
     // Message: ping
     //
     bool pingSend = false;
     if (pto->fPingQueued) {
         // RPC ping request by user
         pingSend = true;
     }
     if (pto->nPingNonceSent == 0 &&
         pto->nPingUsecStart + PING_INTERVAL * 1000000 < GetTimeMicros()) {
         // Ping automatically sent as a latency probe & keepalive.
         pingSend = true;
     }
     if (pingSend) {
         uint64_t nonce = 0;
         while (nonce == 0) {
-            GetRandBytes((unsigned char *)&nonce, sizeof(nonce));
+            GetRandBytes((uint8_t *)&nonce, sizeof(nonce));
         }
         pto->fPingQueued = false;
         pto->nPingUsecStart = GetTimeMicros();
         if (pto->nVersion > BIP0031_VERSION) {
             pto->nPingNonceSent = nonce;
             connman.PushMessage(pto, msgMaker.Make(NetMsgType::PING, nonce));
         } else {
             // Peer is too old to support ping command with nonce, pong will
             // never arrive.
             pto->nPingNonceSent = 0;
             connman.PushMessage(pto, msgMaker.Make(NetMsgType::PING));
         }
     }
 
     // Acquire cs_main for IsInitialBlockDownload() and CNodeState()
     TRY_LOCK(cs_main, lockMain);
     if (!lockMain) {
         return true;
     }
 
     if (SendRejectsAndCheckIfBanned(pto, connman)) {
         return true;
     }
     CNodeState &state = *State(pto->GetId());
 
     // Address refresh broadcast
     int64_t nNow = GetTimeMicros();
     if (!IsInitialBlockDownload() && pto->nNextLocalAddrSend < nNow) {
         AdvertiseLocal(pto);
         pto->nNextLocalAddrSend =
             PoissonNextSend(nNow, AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL);
     }
 
     //
     // Message: addr
     //
     if (pto->nNextAddrSend < nNow) {
         pto->nNextAddrSend =
             PoissonNextSend(nNow, AVG_ADDRESS_BROADCAST_INTERVAL);
         std::vector<CAddress> vAddr;
         vAddr.reserve(pto->vAddrToSend.size());
         for (const CAddress &addr : pto->vAddrToSend) {
             if (!pto->addrKnown.contains(addr.GetKey())) {
                 pto->addrKnown.insert(addr.GetKey());
                 vAddr.push_back(addr);
                 // receiver rejects addr messages larger than 1000
                 if (vAddr.size() >= 1000) {
                     connman.PushMessage(pto,
                                         msgMaker.Make(NetMsgType::ADDR, vAddr));
                     vAddr.clear();
                 }
             }
         }
         pto->vAddrToSend.clear();
         if (!vAddr.empty()) {
             connman.PushMessage(pto, msgMaker.Make(NetMsgType::ADDR, vAddr));
         }
 
         // we only send the big addr message once
         if (pto->vAddrToSend.capacity() > 40) {
             pto->vAddrToSend.shrink_to_fit();
         }
     }
 
     // Start block sync
     if (pindexBestHeader == nullptr) {
         pindexBestHeader = chainActive.Tip();
     }
 
     // Download if this is a nice peer, or we have no nice peers and this one
     // might do.
     bool fFetch = state.fPreferredDownload ||
                   (nPreferredDownload == 0 && !pto->fClient && !pto->fOneShot);
 
     if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex) {
         // Only actively request headers from a single peer, unless we're close
         // to today.
         if ((nSyncStarted == 0 && fFetch) ||
             pindexBestHeader->GetBlockTime() >
                 GetAdjustedTime() - 24 * 60 * 60) {
             state.fSyncStarted = true;
             nSyncStarted++;
             const CBlockIndex *pindexStart = pindexBestHeader;
             /**
              * If possible, start at the block preceding the currently best
              * known header. This ensures that we always get a non-empty list of
              * headers back as long as the peer is up-to-date. With a non-empty
              * response, we can initialise the peer's known best block. This
              * wouldn't be possible if we requested starting at pindexBestHeader
              * and got back an empty response.
              */
             if (pindexStart->pprev) {
                 pindexStart = pindexStart->pprev;
             }
 
             LogPrint("net",
                      "initial getheaders (%d) to peer=%d (startheight:%d)\n",
                      pindexStart->nHeight, pto->id, pto->nStartingHeight);
             connman.PushMessage(
                 pto,
                 msgMaker.Make(NetMsgType::GETHEADERS,
                               chainActive.GetLocator(pindexStart), uint256()));
         }
     }
 
     // Resend wallet transactions that haven't gotten in a block yet
     // Except during reindex, importing and IBD, when old wallet transactions
     // become unconfirmed and spams other nodes.
     if (!fReindex && !fImporting && !IsInitialBlockDownload()) {
         GetMainSignals().Broadcast(nTimeBestReceived, &connman);
     }
 
     //
     // Try sending block announcements via headers
     //
     {
         // If we have less than MAX_BLOCKS_TO_ANNOUNCE in our list of block
         // hashes we're relaying, and our peer wants headers announcements, then
         // find the first header not yet known to our peer but would connect,
         // and send. If no header would connect, or if we have too many blocks,
         // or if the peer doesn't want headers, just add all to the inv queue.
         LOCK(pto->cs_inventory);
         std::vector<CBlock> vHeaders;
         bool fRevertToInv =
             ((!state.fPreferHeaders &&
               (!state.fPreferHeaderAndIDs ||
                pto->vBlockHashesToAnnounce.size() > 1)) ||
              pto->vBlockHashesToAnnounce.size() > MAX_BLOCKS_TO_ANNOUNCE);
         // last header queued for delivery
         const CBlockIndex *pBestIndex = nullptr;
         // ensure pindexBestKnownBlock is up-to-date
         ProcessBlockAvailability(pto->id);
 
         if (!fRevertToInv) {
             bool fFoundStartingHeader = false;
             // Try to find first header that our peer doesn't have, and then
             // send all headers past that one. If we come across an headers that
             // aren't on chainActive, give up.
             for (const uint256 &hash : pto->vBlockHashesToAnnounce) {
                 BlockMap::iterator mi = mapBlockIndex.find(hash);
                 assert(mi != mapBlockIndex.end());
                 const CBlockIndex *pindex = mi->second;
                 if (chainActive[pindex->nHeight] != pindex) {
                     // Bail out if we reorged away from this block
                     fRevertToInv = true;
                     break;
                 }
                 if (pBestIndex != nullptr && pindex->pprev != pBestIndex) {
                     // This means that the list of blocks to announce don't
                     // connect to each other. This shouldn't really be possible
                     // to hit during regular operation (because reorgs should
                     // take us to a chain that has some block not on the prior
                     // chain, which should be caught by the prior check), but
                     // one way this could happen is by using invalidateblock /
                     // reconsiderblock repeatedly on the tip, causing it to be
                     // added multiple times to vBlockHashesToAnnounce. Robustly
                     // deal with this rare situation by reverting to an inv.
                     fRevertToInv = true;
                     break;
                 }
                 pBestIndex = pindex;
                 if (fFoundStartingHeader) {
                     // add this to the headers message
                     vHeaders.push_back(pindex->GetBlockHeader());
                 } else if (PeerHasHeader(&state, pindex)) {
                     // Keep looking for the first new block.
                     continue;
                 } else if (pindex->pprev == nullptr ||
                            PeerHasHeader(&state, pindex->pprev)) {
                     // Peer doesn't have this header but they do have the prior
                     // one.
                     // Start sending headers.
                     fFoundStartingHeader = true;
                     vHeaders.push_back(pindex->GetBlockHeader());
                 } else {
                     // Peer doesn't have this header or the prior one --
                     // nothing will connect, so bail out.
                     fRevertToInv = true;
                     break;
                 }
             }
         }
         if (!fRevertToInv && !vHeaders.empty()) {
             if (vHeaders.size() == 1 && state.fPreferHeaderAndIDs) {
                 // We only send up to 1 block as header-and-ids, as otherwise
                 // probably means we're doing an initial-ish-sync or they're
                 // slow.
                 LogPrint("net", "%s sending header-and-ids %s to peer=%d\n",
                          __func__, vHeaders.front().GetHash().ToString(),
                          pto->id);
 
                 int nSendFlags = 0;
 
                 bool fGotBlockFromCache = false;
                 {
                     LOCK(cs_most_recent_block);
                     if (most_recent_block_hash == pBestIndex->GetBlockHash()) {
                         CBlockHeaderAndShortTxIDs cmpctblock(
                             *most_recent_block);
                         connman.PushMessage(
                             pto,
                             msgMaker.Make(nSendFlags, NetMsgType::CMPCTBLOCK,
                                           cmpctblock));
                         fGotBlockFromCache = true;
                     }
                 }
                 if (!fGotBlockFromCache) {
                     CBlock block;
                     bool ret =
                         ReadBlockFromDisk(block, pBestIndex, consensusParams);
                     assert(ret);
                     CBlockHeaderAndShortTxIDs cmpctblock(block);
                     connman.PushMessage(
                         pto, msgMaker.Make(nSendFlags, NetMsgType::CMPCTBLOCK,
                                            cmpctblock));
                 }
                 state.pindexBestHeaderSent = pBestIndex;
             } else if (state.fPreferHeaders) {
                 if (vHeaders.size() > 1) {
                     LogPrint("net",
                              "%s: %u headers, range (%s, %s), to peer=%d\n",
                              __func__, vHeaders.size(),
                              vHeaders.front().GetHash().ToString(),
                              vHeaders.back().GetHash().ToString(), pto->id);
                 } else {
                     LogPrint("net", "%s: sending header %s to peer=%d\n",
                              __func__, vHeaders.front().GetHash().ToString(),
                              pto->id);
                 }
                 connman.PushMessage(
                     pto, msgMaker.Make(NetMsgType::HEADERS, vHeaders));
                 state.pindexBestHeaderSent = pBestIndex;
             } else {
                 fRevertToInv = true;
             }
         }
         if (fRevertToInv) {
             // If falling back to using an inv, just try to inv the tip. The
             // last entry in vBlockHashesToAnnounce was our tip at some point in
             // the past.
             if (!pto->vBlockHashesToAnnounce.empty()) {
                 const uint256 &hashToAnnounce =
                     pto->vBlockHashesToAnnounce.back();
                 BlockMap::iterator mi = mapBlockIndex.find(hashToAnnounce);
                 assert(mi != mapBlockIndex.end());
                 const CBlockIndex *pindex = mi->second;
 
                 // Warn if we're announcing a block that is not on the main
                 // chain. This should be very rare and could be optimized out.
                 // Just log for now.
                 if (chainActive[pindex->nHeight] != pindex) {
                     LogPrint("net",
                              "Announcing block %s not on main chain (tip=%s)\n",
                              hashToAnnounce.ToString(),
                              chainActive.Tip()->GetBlockHash().ToString());
                 }
 
                 // If the peer's chain has this block, don't inv it back.
                 if (!PeerHasHeader(&state, pindex)) {
                     pto->PushInventory(CInv(MSG_BLOCK, hashToAnnounce));
                     LogPrint("net", "%s: sending inv peer=%d hash=%s\n",
                              __func__, pto->id, hashToAnnounce.ToString());
                 }
             }
         }
         pto->vBlockHashesToAnnounce.clear();
     }
 
     //
     // Message: inventory
     //
     std::vector<CInv> vInv;
     {
         LOCK(pto->cs_inventory);
         vInv.reserve(std::max<size_t>(pto->vInventoryBlockToSend.size(),
                                       INVENTORY_BROADCAST_MAX));
 
         // Add blocks
         for (const uint256 &hash : pto->vInventoryBlockToSend) {
             vInv.push_back(CInv(MSG_BLOCK, hash));
             if (vInv.size() == MAX_INV_SZ) {
                 connman.PushMessage(pto, msgMaker.Make(NetMsgType::INV, vInv));
                 vInv.clear();
             }
         }
         pto->vInventoryBlockToSend.clear();
 
         // Check whether periodic sends should happen
         bool fSendTrickle = pto->fWhitelisted;
         if (pto->nNextInvSend < nNow) {
             fSendTrickle = true;
             // Use half the delay for outbound peers, as there is less privacy
             // concern for them.
             pto->nNextInvSend = PoissonNextSend(
                 nNow, INVENTORY_BROADCAST_INTERVAL >> !pto->fInbound);
         }
 
         // Time to send but the peer has requested we not relay transactions.
         if (fSendTrickle) {
             LOCK(pto->cs_filter);
             if (!pto->fRelayTxes) {
                 pto->setInventoryTxToSend.clear();
             }
         }
 
         // Respond to BIP35 mempool requests
         if (fSendTrickle && pto->fSendMempool) {
             auto vtxinfo = mempool.infoAll();
             pto->fSendMempool = false;
             CAmount filterrate = 0;
             {
                 LOCK(pto->cs_feeFilter);
                 filterrate = pto->minFeeFilter;
             }
 
             LOCK(pto->cs_filter);
 
             for (const auto &txinfo : vtxinfo) {
                 const uint256 &txid = txinfo.tx->GetId();
                 CInv inv(MSG_TX, txid);
                 pto->setInventoryTxToSend.erase(txid);
                 if (filterrate) {
                     if (txinfo.feeRate.GetFeePerK() < filterrate) {
                         continue;
                     }
                 }
                 if (pto->pfilter) {
                     if (!pto->pfilter->IsRelevantAndUpdate(*txinfo.tx)) {
                         continue;
                     }
                 }
                 pto->filterInventoryKnown.insert(txid);
                 vInv.push_back(inv);
                 if (vInv.size() == MAX_INV_SZ) {
                     connman.PushMessage(pto,
                                         msgMaker.Make(NetMsgType::INV, vInv));
                     vInv.clear();
                 }
             }
             pto->timeLastMempoolReq = GetTime();
         }
 
         // Determine transactions to relay
         if (fSendTrickle) {
             // Produce a vector with all candidates for sending
             std::vector<std::set<uint256>::iterator> vInvTx;
             vInvTx.reserve(pto->setInventoryTxToSend.size());
             for (std::set<uint256>::iterator it =
                      pto->setInventoryTxToSend.begin();
                  it != pto->setInventoryTxToSend.end(); it++) {
                 vInvTx.push_back(it);
             }
             CAmount filterrate = 0;
             {
                 LOCK(pto->cs_feeFilter);
                 filterrate = pto->minFeeFilter;
             }
             // Topologically and fee-rate sort the inventory we send for privacy
             // and priority reasons. A heap is used so that not all items need
             // sorting if only a few are being sent.
             CompareInvMempoolOrder compareInvMempoolOrder(&mempool);
             std::make_heap(vInvTx.begin(), vInvTx.end(),
                            compareInvMempoolOrder);
             // No reason to drain out at many times the network's capacity,
             // especially since we have many peers and some will draw much
             // shorter delays.
             unsigned int nRelayedTransactions = 0;
             LOCK(pto->cs_filter);
             while (!vInvTx.empty() &&
                    nRelayedTransactions < INVENTORY_BROADCAST_MAX) {
                 // Fetch the top element from the heap
                 std::pop_heap(vInvTx.begin(), vInvTx.end(),
                               compareInvMempoolOrder);
                 std::set<uint256>::iterator it = vInvTx.back();
                 vInvTx.pop_back();
                 uint256 hash = *it;
                 // Remove it from the to-be-sent set
                 pto->setInventoryTxToSend.erase(it);
                 // Check if not in the filter already
                 if (pto->filterInventoryKnown.contains(hash)) {
                     continue;
                 }
                 // Not in the mempool anymore? don't bother sending it.
                 auto txinfo = mempool.info(hash);
                 if (!txinfo.tx) {
                     continue;
                 }
                 if (filterrate && txinfo.feeRate.GetFeePerK() < filterrate) {
                     continue;
                 }
                 if (pto->pfilter &&
                     !pto->pfilter->IsRelevantAndUpdate(*txinfo.tx)) {
                     continue;
                 }
                 // Send
                 vInv.push_back(CInv(MSG_TX, hash));
                 nRelayedTransactions++;
                 {
                     // Expire old relay messages
                     while (!vRelayExpiration.empty() &&
                            vRelayExpiration.front().first < nNow) {
                         mapRelay.erase(vRelayExpiration.front().second);
                         vRelayExpiration.pop_front();
                     }
 
                     auto ret = mapRelay.insert(
                         std::make_pair(hash, std::move(txinfo.tx)));
                     if (ret.second) {
                         vRelayExpiration.push_back(std::make_pair(
                             nNow + 15 * 60 * 1000000, ret.first));
                     }
                 }
                 if (vInv.size() == MAX_INV_SZ) {
                     connman.PushMessage(pto,
                                         msgMaker.Make(NetMsgType::INV, vInv));
                     vInv.clear();
                 }
                 pto->filterInventoryKnown.insert(hash);
             }
         }
     }
     if (!vInv.empty()) {
         connman.PushMessage(pto, msgMaker.Make(NetMsgType::INV, vInv));
     }
 
     // Detect whether we're stalling
     nNow = GetTimeMicros();
     if (state.nStallingSince &&
         state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) {
         // Stalling only triggers when the block download window cannot move.
         // During normal steady state, the download window should be much larger
         // than the to-be-downloaded set of blocks, so disconnection should only
         // happen during initial block download.
         LogPrintf("Peer=%d is stalling block download, disconnecting\n",
                   pto->id);
         pto->fDisconnect = true;
         return true;
     }
     // In case there is a block that has been in flight from this peer for 2 +
     // 0.5 * N times the block interval (with N the number of peers from which
     // we're downloading validated blocks), disconnect due to timeout. We
     // compensate for other peers to prevent killing off peers due to our own
     // downstream link being saturated. We only count validated in-flight blocks
     // so peers can't advertise non-existing block hashes to unreasonably
     // increase our timeout.
     if (state.vBlocksInFlight.size() > 0) {
         QueuedBlock &queuedBlock = state.vBlocksInFlight.front();
         int nOtherPeersWithValidatedDownloads =
             nPeersWithValidatedDownloads -
             (state.nBlocksInFlightValidHeaders > 0);
         if (nNow > state.nDownloadingSince +
                        consensusParams.nPowTargetSpacing *
                            (BLOCK_DOWNLOAD_TIMEOUT_BASE +
                             BLOCK_DOWNLOAD_TIMEOUT_PER_PEER *
                                 nOtherPeersWithValidatedDownloads)) {
             LogPrintf("Timeout downloading block %s from peer=%d, "
                       "disconnecting\n",
                       queuedBlock.hash.ToString(), pto->id);
             pto->fDisconnect = true;
             return true;
         }
     }
 
     //
     // Message: getdata (blocks)
     //
     std::vector<CInv> vGetData;
     if (!pto->fClient && (fFetch || !IsInitialBlockDownload()) &&
         state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
         std::vector<const CBlockIndex *> vToDownload;
         NodeId staller = -1;
         FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER -
                                                    state.nBlocksInFlight,
                                  vToDownload, staller, consensusParams);
         for (const CBlockIndex *pindex : vToDownload) {
             uint32_t nFetchFlags =
                 GetFetchFlags(pto, pindex->pprev, consensusParams);
             vGetData.push_back(
                 CInv(MSG_BLOCK | nFetchFlags, pindex->GetBlockHash()));
             MarkBlockAsInFlight(config, pto->GetId(), pindex->GetBlockHash(),
                                 consensusParams, pindex);
             LogPrint("net", "Requesting block %s (%d) peer=%d\n",
                      pindex->GetBlockHash().ToString(), pindex->nHeight,
                      pto->id);
         }
         if (state.nBlocksInFlight == 0 && staller != -1) {
             if (State(staller)->nStallingSince == 0) {
                 State(staller)->nStallingSince = nNow;
                 LogPrint("net", "Stall started peer=%d\n", staller);
             }
         }
     }
 
     //
     // Message: getdata (non-blocks)
     //
     while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow) {
         const CInv &inv = (*pto->mapAskFor.begin()).second;
         if (!AlreadyHave(inv)) {
             if (fDebug) {
                 LogPrint("net", "Requesting %s peer=%d\n", inv.ToString(),
                          pto->id);
             }
             vGetData.push_back(inv);
             if (vGetData.size() >= 1000) {
                 connman.PushMessage(
                     pto, msgMaker.Make(NetMsgType::GETDATA, vGetData));
                 vGetData.clear();
             }
         } else {
             // If we're not going to ask, don't expect a response.
             pto->setAskFor.erase(inv.hash);
         }
         pto->mapAskFor.erase(pto->mapAskFor.begin());
     }
     if (!vGetData.empty()) {
         connman.PushMessage(pto, msgMaker.Make(NetMsgType::GETDATA, vGetData));
     }
 
     //
     // Message: feefilter
     //
     // We don't want white listed peers to filter txs to us if we have
     // -whitelistforcerelay
     if (pto->nVersion >= FEEFILTER_VERSION &&
         GetBoolArg("-feefilter", DEFAULT_FEEFILTER) &&
         !(pto->fWhitelisted &&
           GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY))) {
         CAmount currentFilter =
             mempool
                 .GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) *
                            1000000)
                 .GetFeePerK();
         int64_t timeNow = GetTimeMicros();
         if (timeNow > pto->nextSendTimeFeeFilter) {
             static CFeeRate default_feerate(DEFAULT_MIN_RELAY_TX_FEE);
             static FeeFilterRounder filterRounder(default_feerate);
             CAmount filterToSend = filterRounder.round(currentFilter);
             // If we don't allow free transactions, then we always have a fee
             // filter of at least minRelayTxFee
             if (GetArg("-limitfreerelay", DEFAULT_LIMITFREERELAY) <= 0) {
                 filterToSend =
                     std::max(filterToSend, ::minRelayTxFee.GetFeePerK());
             }
 
             if (filterToSend != pto->lastSentFeeFilter) {
                 connman.PushMessage(
                     pto, msgMaker.Make(NetMsgType::FEEFILTER, filterToSend));
                 pto->lastSentFeeFilter = filterToSend;
             }
             pto->nextSendTimeFeeFilter =
                 PoissonNextSend(timeNow, AVG_FEEFILTER_BROADCAST_INTERVAL);
         }
         // If the fee filter has changed substantially and it's still more than
         // MAX_FEEFILTER_CHANGE_DELAY until scheduled broadcast, then move the
         // broadcast to within MAX_FEEFILTER_CHANGE_DELAY.
         else if (timeNow + MAX_FEEFILTER_CHANGE_DELAY * 1000000 <
                      pto->nextSendTimeFeeFilter &&
                  (currentFilter < 3 * pto->lastSentFeeFilter / 4 ||
                   currentFilter > 4 * pto->lastSentFeeFilter / 3)) {
             pto->nextSendTimeFeeFilter =
                 timeNow + GetRandInt(MAX_FEEFILTER_CHANGE_DELAY) * 1000000;
         }
     }
     return true;
 }
 
 class CNetProcessingCleanup {
 public:
     CNetProcessingCleanup() {}
     ~CNetProcessingCleanup() {
         // orphan transactions
         mapOrphanTransactions.clear();
         mapOrphanTransactionsByPrev.clear();
     }
 } instance_of_cnetprocessingcleanup;
diff --git a/src/netaddress.cpp b/src/netaddress.cpp
index 92f9ccddd..5ca399c48 100644
--- a/src/netaddress.cpp
+++ b/src/netaddress.cpp
@@ -1,680 +1,679 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #ifdef HAVE_CONFIG_H
 #include "config/bitcoin-config.h"
 #endif
 
 #include "hash.h"
 #include "netaddress.h"
 #include "tinyformat.h"
 #include "utilstrencodings.h"
 
-static const unsigned char pchIPv4[12] = {0, 0, 0, 0, 0,    0,
-                                          0, 0, 0, 0, 0xff, 0xff};
-static const unsigned char pchOnionCat[] = {0xFD, 0x87, 0xD8, 0x7E, 0xEB, 0x43};
+static const uint8_t pchIPv4[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff};
+static const uint8_t pchOnionCat[] = {0xFD, 0x87, 0xD8, 0x7E, 0xEB, 0x43};
 
 void CNetAddr::Init() {
     memset(ip, 0, sizeof(ip));
     scopeId = 0;
 }
 
 void CNetAddr::SetIP(const CNetAddr &ipIn) {
     memcpy(ip, ipIn.ip, sizeof(ip));
 }
 
 void CNetAddr::SetRaw(Network network, const uint8_t *ip_in) {
     switch (network) {
         case NET_IPV4:
             memcpy(ip, pchIPv4, 12);
             memcpy(ip + 12, ip_in, 4);
             break;
         case NET_IPV6:
             memcpy(ip, ip_in, 16);
             break;
         default:
             assert(!"invalid network");
     }
 }
 
 bool CNetAddr::SetSpecial(const std::string &strName) {
     if (strName.size() > 6 &&
         strName.substr(strName.size() - 6, 6) == ".onion") {
-        std::vector<unsigned char> vchAddr =
+        std::vector<uint8_t> vchAddr =
             DecodeBase32(strName.substr(0, strName.size() - 6).c_str());
         if (vchAddr.size() != 16 - sizeof(pchOnionCat)) return false;
         memcpy(ip, pchOnionCat, sizeof(pchOnionCat));
         for (unsigned int i = 0; i < 16 - sizeof(pchOnionCat); i++)
             ip[i + sizeof(pchOnionCat)] = vchAddr[i];
         return true;
     }
     return false;
 }
 
 CNetAddr::CNetAddr() {
     Init();
 }
 
 CNetAddr::CNetAddr(const struct in_addr &ipv4Addr) {
     SetRaw(NET_IPV4, (const uint8_t *)&ipv4Addr);
 }
 
 CNetAddr::CNetAddr(const struct in6_addr &ipv6Addr, const uint32_t scope) {
     SetRaw(NET_IPV6, (const uint8_t *)&ipv6Addr);
     scopeId = scope;
 }
 
 unsigned int CNetAddr::GetByte(int n) const {
     return ip[15 - n];
 }
 
 bool CNetAddr::IsIPv4() const {
     return (memcmp(ip, pchIPv4, sizeof(pchIPv4)) == 0);
 }
 
 bool CNetAddr::IsIPv6() const {
     return (!IsIPv4() && !IsTor());
 }
 
 bool CNetAddr::IsRFC1918() const {
     return IsIPv4() &&
            (GetByte(3) == 10 || (GetByte(3) == 192 && GetByte(2) == 168) ||
             (GetByte(3) == 172 && (GetByte(2) >= 16 && GetByte(2) <= 31)));
 }
 
 bool CNetAddr::IsRFC2544() const {
     return IsIPv4() && GetByte(3) == 198 &&
            (GetByte(2) == 18 || GetByte(2) == 19);
 }
 
 bool CNetAddr::IsRFC3927() const {
     return IsIPv4() && (GetByte(3) == 169 && GetByte(2) == 254);
 }
 
 bool CNetAddr::IsRFC6598() const {
     return IsIPv4() && GetByte(3) == 100 && GetByte(2) >= 64 &&
            GetByte(2) <= 127;
 }
 
 bool CNetAddr::IsRFC5737() const {
     return IsIPv4() &&
            ((GetByte(3) == 192 && GetByte(2) == 0 && GetByte(1) == 2) ||
             (GetByte(3) == 198 && GetByte(2) == 51 && GetByte(1) == 100) ||
             (GetByte(3) == 203 && GetByte(2) == 0 && GetByte(1) == 113));
 }
 
 bool CNetAddr::IsRFC3849() const {
     return GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x0D &&
            GetByte(12) == 0xB8;
 }
 
 bool CNetAddr::IsRFC3964() const {
     return (GetByte(15) == 0x20 && GetByte(14) == 0x02);
 }
 
 bool CNetAddr::IsRFC6052() const {
-    static const unsigned char pchRFC6052[] = {0, 0x64, 0xFF, 0x9B, 0, 0,
-                                               0, 0,    0,    0,    0, 0};
+    static const uint8_t pchRFC6052[] = {0, 0x64, 0xFF, 0x9B, 0, 0,
+                                         0, 0,    0,    0,    0, 0};
     return (memcmp(ip, pchRFC6052, sizeof(pchRFC6052)) == 0);
 }
 
 bool CNetAddr::IsRFC4380() const {
     return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0 &&
             GetByte(12) == 0);
 }
 
 bool CNetAddr::IsRFC4862() const {
-    static const unsigned char pchRFC4862[] = {0xFE, 0x80, 0, 0, 0, 0, 0, 0};
+    static const uint8_t pchRFC4862[] = {0xFE, 0x80, 0, 0, 0, 0, 0, 0};
     return (memcmp(ip, pchRFC4862, sizeof(pchRFC4862)) == 0);
 }
 
 bool CNetAddr::IsRFC4193() const {
     return ((GetByte(15) & 0xFE) == 0xFC);
 }
 
 bool CNetAddr::IsRFC6145() const {
-    static const unsigned char pchRFC6145[] = {0, 0, 0,    0,    0, 0,
-                                               0, 0, 0xFF, 0xFF, 0, 0};
+    static const uint8_t pchRFC6145[] = {0, 0, 0,    0,    0, 0,
+                                         0, 0, 0xFF, 0xFF, 0, 0};
     return (memcmp(ip, pchRFC6145, sizeof(pchRFC6145)) == 0);
 }
 
 bool CNetAddr::IsRFC4843() const {
     return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x00 &&
             (GetByte(12) & 0xF0) == 0x10);
 }
 
 bool CNetAddr::IsTor() const {
     return (memcmp(ip, pchOnionCat, sizeof(pchOnionCat)) == 0);
 }
 
 bool CNetAddr::IsLocal() const {
     // IPv4 loopback
     if (IsIPv4() && (GetByte(3) == 127 || GetByte(3) == 0)) return true;
 
     // IPv6 loopback (::1/128)
-    static const unsigned char pchLocal[16] = {0, 0, 0, 0, 0, 0, 0, 0,
-                                               0, 0, 0, 0, 0, 0, 0, 1};
+    static const uint8_t pchLocal[16] = {0, 0, 0, 0, 0, 0, 0, 0,
+                                         0, 0, 0, 0, 0, 0, 0, 1};
     if (memcmp(ip, pchLocal, 16) == 0) return true;
 
     return false;
 }
 
 bool CNetAddr::IsMulticast() const {
     return (IsIPv4() && (GetByte(3) & 0xF0) == 0xE0) || (GetByte(15) == 0xFF);
 }
 
 bool CNetAddr::IsValid() const {
     // Cleanup 3-byte shifted addresses caused by garbage in size field of addr
     // messages from versions before 0.2.9 checksum.
     // Two consecutive addr messages look like this:
     // header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26
     // addr26 addr26... so if the first length field is garbled, it reads the
     // second batch of addr misaligned by 3 bytes.
     if (memcmp(ip, pchIPv4 + 3, sizeof(pchIPv4) - 3) == 0) return false;
 
     // unspecified IPv6 address (::/128)
-    unsigned char ipNone6[16] = {};
+    uint8_t ipNone6[16] = {};
     if (memcmp(ip, ipNone6, 16) == 0) return false;
 
     // documentation IPv6 address
     if (IsRFC3849()) return false;
 
     if (IsIPv4()) {
         // INADDR_NONE
         uint32_t ipNone = INADDR_NONE;
         if (memcmp(ip + 12, &ipNone, 4) == 0) return false;
 
         // 0
         ipNone = 0;
         if (memcmp(ip + 12, &ipNone, 4) == 0) return false;
     }
 
     return true;
 }
 
 bool CNetAddr::IsRoutable() const {
     return IsValid() &&
            !(IsRFC1918() || IsRFC2544() || IsRFC3927() || IsRFC4862() ||
              IsRFC6598() || IsRFC5737() || (IsRFC4193() && !IsTor()) ||
              IsRFC4843() || IsLocal());
 }
 
 enum Network CNetAddr::GetNetwork() const {
     if (!IsRoutable()) return NET_UNROUTABLE;
 
     if (IsIPv4()) return NET_IPV4;
 
     if (IsTor()) return NET_TOR;
 
     return NET_IPV6;
 }
 
 std::string CNetAddr::ToStringIP() const {
     if (IsTor()) return EncodeBase32(&ip[6], 10) + ".onion";
     CService serv(*this, 0);
     struct sockaddr_storage sockaddr;
     socklen_t socklen = sizeof(sockaddr);
     if (serv.GetSockAddr((struct sockaddr *)&sockaddr, &socklen)) {
         char name[1025] = "";
         if (!getnameinfo((const struct sockaddr *)&sockaddr, socklen, name,
                          sizeof(name), nullptr, 0, NI_NUMERICHOST))
             return std::string(name);
     }
     if (IsIPv4())
         return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1),
                          GetByte(0));
     else
         return strprintf(
             "%x:%x:%x:%x:%x:%x:%x:%x", GetByte(15) << 8 | GetByte(14),
             GetByte(13) << 8 | GetByte(12), GetByte(11) << 8 | GetByte(10),
             GetByte(9) << 8 | GetByte(8), GetByte(7) << 8 | GetByte(6),
             GetByte(5) << 8 | GetByte(4), GetByte(3) << 8 | GetByte(2),
             GetByte(1) << 8 | GetByte(0));
 }
 
 std::string CNetAddr::ToString() const {
     return ToStringIP();
 }
 
 bool operator==(const CNetAddr &a, const CNetAddr &b) {
     return (memcmp(a.ip, b.ip, 16) == 0);
 }
 
 bool operator!=(const CNetAddr &a, const CNetAddr &b) {
     return (memcmp(a.ip, b.ip, 16) != 0);
 }
 
 bool operator<(const CNetAddr &a, const CNetAddr &b) {
     return (memcmp(a.ip, b.ip, 16) < 0);
 }
 
 bool CNetAddr::GetInAddr(struct in_addr *pipv4Addr) const {
     if (!IsIPv4()) return false;
     memcpy(pipv4Addr, ip + 12, 4);
     return true;
 }
 
 bool CNetAddr::GetIn6Addr(struct in6_addr *pipv6Addr) const {
     memcpy(pipv6Addr, ip, 16);
     return true;
 }
 
 // get canonical identifier of an address' group no two connections will be
 // attempted to addresses with the same group
-std::vector<unsigned char> CNetAddr::GetGroup() const {
-    std::vector<unsigned char> vchRet;
+std::vector<uint8_t> CNetAddr::GetGroup() const {
+    std::vector<uint8_t> vchRet;
     int nClass = NET_IPV6;
     int nStartByte = 0;
     int nBits = 16;
 
     // all local addresses belong to the same group
     if (IsLocal()) {
         nClass = 255;
         nBits = 0;
     }
 
     if (!IsRoutable()) {
         // all unroutable addresses belong to the same group
         nClass = NET_UNROUTABLE;
         nBits = 0;
     } else if (IsIPv4() || IsRFC6145() || IsRFC6052()) {
         // for IPv4 addresses, '1' + the 16 higher-order bits of the IP includes
         // mapped IPv4, SIIT translated IPv4, and the well-known prefix
         nClass = NET_IPV4;
         nStartByte = 12;
     } else if (IsRFC3964()) {
         // for 6to4 tunnelled addresses, use the encapsulated IPv4 address
         nClass = NET_IPV4;
         nStartByte = 2;
     } else if (IsRFC4380()) {
         // for Teredo-tunnelled IPv6 addresses, use the encapsulated IPv4
         // address
         vchRet.push_back(NET_IPV4);
         vchRet.push_back(GetByte(3) ^ 0xFF);
         vchRet.push_back(GetByte(2) ^ 0xFF);
         return vchRet;
     } else if (IsTor()) {
         nClass = NET_TOR;
         nStartByte = 6;
         nBits = 4;
     } else if (GetByte(15) == 0x20 && GetByte(14) == 0x01 &&
                GetByte(13) == 0x04 && GetByte(12) == 0x70) {
         // for he.net, use /36 groups
         nBits = 36;
     } else {
         // for the rest of the IPv6 network, use /32 groups
         nBits = 32;
     }
 
     vchRet.push_back(nClass);
     while (nBits >= 8) {
         vchRet.push_back(GetByte(15 - nStartByte));
         nStartByte++;
         nBits -= 8;
     }
     if (nBits > 0)
         vchRet.push_back(GetByte(15 - nStartByte) | ((1 << (8 - nBits)) - 1));
 
     return vchRet;
 }
 
 uint64_t CNetAddr::GetHash() const {
     uint256 hash = Hash(&ip[0], &ip[16]);
     uint64_t nRet;
     memcpy(&nRet, &hash, sizeof(nRet));
     return nRet;
 }
 
 // private extensions to enum Network, only returned by GetExtNetwork, and only
 // used in GetReachabilityFrom
 static const int NET_UNKNOWN = NET_MAX + 0;
 static const int NET_TEREDO = NET_MAX + 1;
 static int GetExtNetwork(const CNetAddr *addr) {
     if (addr == nullptr) return NET_UNKNOWN;
     if (addr->IsRFC4380()) return NET_TEREDO;
     return addr->GetNetwork();
 }
 
 /** Calculates a metric for how reachable (*this) is from a given partner */
 int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const {
     enum Reachability {
         REACH_UNREACHABLE,
         REACH_DEFAULT,
         REACH_TEREDO,
         REACH_IPV6_WEAK,
         REACH_IPV4,
         REACH_IPV6_STRONG,
         REACH_PRIVATE
     };
 
     if (!IsRoutable()) return REACH_UNREACHABLE;
 
     int ourNet = GetExtNetwork(this);
     int theirNet = GetExtNetwork(paddrPartner);
     bool fTunnel = IsRFC3964() || IsRFC6052() || IsRFC6145();
 
     switch (theirNet) {
         case NET_IPV4:
             switch (ourNet) {
                 default:
                     return REACH_DEFAULT;
                 case NET_IPV4:
                     return REACH_IPV4;
             }
         case NET_IPV6:
             switch (ourNet) {
                 default:
                     return REACH_DEFAULT;
                 case NET_TEREDO:
                     return REACH_TEREDO;
                 case NET_IPV4:
                     return REACH_IPV4;
                 // only prefer giving our IPv6 address if it's not tunnelled
                 case NET_IPV6:
                     return fTunnel ? REACH_IPV6_WEAK : REACH_IPV6_STRONG;
             }
         case NET_TOR:
             switch (ourNet) {
                 default:
                     return REACH_DEFAULT;
                 // Tor users can connect to IPv4 as well
                 case NET_IPV4:
                     return REACH_IPV4;
                 case NET_TOR:
                     return REACH_PRIVATE;
             }
         case NET_TEREDO:
             switch (ourNet) {
                 default:
                     return REACH_DEFAULT;
                 case NET_TEREDO:
                     return REACH_TEREDO;
                 case NET_IPV6:
                     return REACH_IPV6_WEAK;
                 case NET_IPV4:
                     return REACH_IPV4;
             }
         case NET_UNKNOWN:
         case NET_UNROUTABLE:
         default:
             switch (ourNet) {
                 default:
                     return REACH_DEFAULT;
                 case NET_TEREDO:
                     return REACH_TEREDO;
                 case NET_IPV6:
                     return REACH_IPV6_WEAK;
                 case NET_IPV4:
                     return REACH_IPV4;
                 // either from Tor, or don't care about our address
                 case NET_TOR:
                     return REACH_PRIVATE;
             }
     }
 }
 
 void CService::Init() {
     port = 0;
 }
 
 CService::CService() {
     Init();
 }
 
 CService::CService(const CNetAddr &cip, unsigned short portIn)
     : CNetAddr(cip), port(portIn) {}
 
 CService::CService(const struct in_addr &ipv4Addr, unsigned short portIn)
     : CNetAddr(ipv4Addr), port(portIn) {}
 
 CService::CService(const struct in6_addr &ipv6Addr, unsigned short portIn)
     : CNetAddr(ipv6Addr), port(portIn) {}
 
 CService::CService(const struct sockaddr_in &addr)
     : CNetAddr(addr.sin_addr), port(ntohs(addr.sin_port)) {
     assert(addr.sin_family == AF_INET);
 }
 
 CService::CService(const struct sockaddr_in6 &addr)
     : CNetAddr(addr.sin6_addr, addr.sin6_scope_id),
       port(ntohs(addr.sin6_port)) {
     assert(addr.sin6_family == AF_INET6);
 }
 
 bool CService::SetSockAddr(const struct sockaddr *paddr) {
     switch (paddr->sa_family) {
         case AF_INET:
             *this = CService(*(const struct sockaddr_in *)paddr);
             return true;
         case AF_INET6:
             *this = CService(*(const struct sockaddr_in6 *)paddr);
             return true;
         default:
             return false;
     }
 }
 
 unsigned short CService::GetPort() const {
     return port;
 }
 
 bool operator==(const CService &a, const CService &b) {
     return (CNetAddr)a == (CNetAddr)b && a.port == b.port;
 }
 
 bool operator!=(const CService &a, const CService &b) {
     return (CNetAddr)a != (CNetAddr)b || a.port != b.port;
 }
 
 bool operator<(const CService &a, const CService &b) {
     return (CNetAddr)a < (CNetAddr)b ||
            ((CNetAddr)a == (CNetAddr)b && a.port < b.port);
 }
 
 bool CService::GetSockAddr(struct sockaddr *paddr, socklen_t *addrlen) const {
     if (IsIPv4()) {
         if (*addrlen < (socklen_t)sizeof(struct sockaddr_in)) return false;
         *addrlen = sizeof(struct sockaddr_in);
         struct sockaddr_in *paddrin = (struct sockaddr_in *)paddr;
         memset(paddrin, 0, *addrlen);
         if (!GetInAddr(&paddrin->sin_addr)) return false;
         paddrin->sin_family = AF_INET;
         paddrin->sin_port = htons(port);
         return true;
     }
     if (IsIPv6()) {
         if (*addrlen < (socklen_t)sizeof(struct sockaddr_in6)) return false;
         *addrlen = sizeof(struct sockaddr_in6);
         struct sockaddr_in6 *paddrin6 = (struct sockaddr_in6 *)paddr;
         memset(paddrin6, 0, *addrlen);
         if (!GetIn6Addr(&paddrin6->sin6_addr)) return false;
         paddrin6->sin6_scope_id = scopeId;
         paddrin6->sin6_family = AF_INET6;
         paddrin6->sin6_port = htons(port);
         return true;
     }
     return false;
 }
 
-std::vector<unsigned char> CService::GetKey() const {
-    std::vector<unsigned char> vKey;
+std::vector<uint8_t> CService::GetKey() const {
+    std::vector<uint8_t> vKey;
     vKey.resize(18);
     memcpy(&vKey[0], ip, 16);
     vKey[16] = port / 0x100;
     vKey[17] = port & 0x0FF;
     return vKey;
 }
 
 std::string CService::ToStringPort() const {
     return strprintf("%u", port);
 }
 
 std::string CService::ToStringIPPort() const {
     if (IsIPv4() || IsTor()) {
         return ToStringIP() + ":" + ToStringPort();
     } else {
         return "[" + ToStringIP() + "]:" + ToStringPort();
     }
 }
 
 std::string CService::ToString() const {
     return ToStringIPPort();
 }
 
 void CService::SetPort(unsigned short portIn) {
     port = portIn;
 }
 
 CSubNet::CSubNet() : valid(false) {
     memset(netmask, 0, sizeof(netmask));
 }
 
 CSubNet::CSubNet(const CNetAddr &addr, int32_t mask) {
     valid = true;
     network = addr;
     // Default to /32 (IPv4) or /128 (IPv6), i.e. match single address
     memset(netmask, 255, sizeof(netmask));
 
     // IPv4 addresses start at offset 12, and first 12 bytes must match, so just
     // offset n
     const int astartofs = network.IsIPv4() ? 12 : 0;
 
     // Only valid if in range of bits of address
     int32_t n = mask;
     if (n >= 0 && n <= (128 - astartofs * 8)) {
         n += astartofs * 8;
         // Clear bits [n..127]
         for (; n < 128; ++n)
             netmask[n >> 3] &= ~(1 << (7 - (n & 7)));
     } else {
         valid = false;
     }
 
     // Normalize network according to netmask
     for (int x = 0; x < 16; ++x) {
         network.ip[x] &= netmask[x];
     }
 }
 
 CSubNet::CSubNet(const CNetAddr &addr, const CNetAddr &mask) {
     valid = true;
     network = addr;
     // Default to /32 (IPv4) or /128 (IPv6), i.e. match single address
     memset(netmask, 255, sizeof(netmask));
 
     // IPv4 addresses start at offset 12, and first 12 bytes must match, so just
     // offset n
     const int astartofs = network.IsIPv4() ? 12 : 0;
 
     for (int x = astartofs; x < 16; ++x)
         netmask[x] = mask.ip[x];
 
     // Normalize network according to netmask
     for (int x = 0; x < 16; ++x)
         network.ip[x] &= netmask[x];
 }
 
 CSubNet::CSubNet(const CNetAddr &addr) : valid(addr.IsValid()) {
     memset(netmask, 255, sizeof(netmask));
     network = addr;
 }
 
 bool CSubNet::Match(const CNetAddr &addr) const {
     if (!valid || !addr.IsValid()) return false;
     for (int x = 0; x < 16; ++x)
         if ((addr.ip[x] & netmask[x]) != network.ip[x]) return false;
     return true;
 }
 
 static inline int NetmaskBits(uint8_t x) {
     switch (x) {
         case 0x00:
             return 0;
             break;
         case 0x80:
             return 1;
             break;
         case 0xc0:
             return 2;
             break;
         case 0xe0:
             return 3;
             break;
         case 0xf0:
             return 4;
             break;
         case 0xf8:
             return 5;
             break;
         case 0xfc:
             return 6;
             break;
         case 0xfe:
             return 7;
             break;
         case 0xff:
             return 8;
             break;
         default:
             return -1;
             break;
     }
 }
 
 std::string CSubNet::ToString() const {
     /* Parse binary 1{n}0{N-n} to see if mask can be represented as /n */
     int cidr = 0;
     bool valid_cidr = true;
     int n = network.IsIPv4() ? 12 : 0;
     for (; n < 16 && netmask[n] == 0xff; ++n)
         cidr += 8;
     if (n < 16) {
         int bits = NetmaskBits(netmask[n]);
         if (bits < 0)
             valid_cidr = false;
         else
             cidr += bits;
         ++n;
     }
     for (; n < 16 && valid_cidr; ++n)
         if (netmask[n] != 0x00) valid_cidr = false;
 
     /* Format output */
     std::string strNetmask;
     if (valid_cidr) {
         strNetmask = strprintf("%u", cidr);
     } else {
         if (network.IsIPv4())
             strNetmask = strprintf("%u.%u.%u.%u", netmask[12], netmask[13],
                                    netmask[14], netmask[15]);
         else
             strNetmask = strprintf(
                 "%x:%x:%x:%x:%x:%x:%x:%x", netmask[0] << 8 | netmask[1],
                 netmask[2] << 8 | netmask[3], netmask[4] << 8 | netmask[5],
                 netmask[6] << 8 | netmask[7], netmask[8] << 8 | netmask[9],
                 netmask[10] << 8 | netmask[11], netmask[12] << 8 | netmask[13],
                 netmask[14] << 8 | netmask[15]);
     }
 
     return network.ToString() + "/" + strNetmask;
 }
 
 bool CSubNet::IsValid() const {
     return valid;
 }
 
 bool operator==(const CSubNet &a, const CSubNet &b) {
     return a.valid == b.valid && a.network == b.network &&
            !memcmp(a.netmask, b.netmask, 16);
 }
 
 bool operator!=(const CSubNet &a, const CSubNet &b) {
     return !(a == b);
 }
 
 bool operator<(const CSubNet &a, const CSubNet &b) {
     return (a.network < b.network ||
             (a.network == b.network && memcmp(a.netmask, b.netmask, 16) < 0));
 }
diff --git a/src/netaddress.h b/src/netaddress.h
index 43431c745..b9a2f518b 100644
--- a/src/netaddress.h
+++ b/src/netaddress.h
@@ -1,186 +1,186 @@
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_NETADDRESS_H
 #define BITCOIN_NETADDRESS_H
 
 #if defined(HAVE_CONFIG_H)
 #include "config/bitcoin-config.h"
 #endif
 
 #include "compat.h"
 #include "serialize.h"
 
 #include <cstdint>
 #include <string>
 #include <vector>
 
 enum Network {
     NET_UNROUTABLE = 0,
     NET_IPV4,
     NET_IPV6,
     NET_TOR,
 
     NET_MAX,
 };
 
 /** IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96)) */
 class CNetAddr {
 protected:
     // in network byte order
-    unsigned char ip[16];
+    uint8_t ip[16];
     // for scoped/link-local ipv6 addresses
     uint32_t scopeId;
 
 public:
     CNetAddr();
     CNetAddr(const struct in_addr &ipv4Addr);
     void Init();
     void SetIP(const CNetAddr &ip);
 
     /**
      * Set raw IPv4 or IPv6 address (in network byte order)
      * @note Only NET_IPV4 and NET_IPV6 are allowed for network.
      */
     void SetRaw(Network network, const uint8_t *data);
 
     // for Tor addresses
     bool SetSpecial(const std::string &strName);
     // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0)
     bool IsIPv4() const;
     // IPv6 address (not mapped IPv4, not Tor)
     bool IsIPv6() const;
     // IPv4 private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12)
     bool IsRFC1918() const;
     // IPv4 inter-network communications (192.18.0.0/15)
     bool IsRFC2544() const;
     // IPv4 ISP-level NAT (100.64.0.0/10)
     bool IsRFC6598() const;
     // IPv4 documentation addresses (192.0.2.0/24, 198.51.100.0/24,
     // 203.0.113.0/24)
     bool IsRFC5737() const;
     // IPv6 documentation address (2001:0DB8::/32)
     bool IsRFC3849() const;
     // IPv4 autoconfig (169.254.0.0/16)
     bool IsRFC3927() const;
     // IPv6 6to4 tunnelling (2002::/16)
     bool IsRFC3964() const;
     // IPv6 unique local (FC00::/7)
     bool IsRFC4193() const;
     // IPv6 Teredo tunnelling (2001::/32)
     bool IsRFC4380() const;
     // IPv6 ORCHID (2001:10::/28)
     bool IsRFC4843() const;
     // IPv6 autoconfig (FE80::/64)
     bool IsRFC4862() const;
     // IPv6 well-known prefix (64:FF9B::/96)
     bool IsRFC6052() const;
     // IPv6 IPv4-translated address (::FFFF:0:0:0/96)
     bool IsRFC6145() const;
     bool IsTor() const;
     bool IsLocal() const;
     bool IsRoutable() const;
     bool IsValid() const;
     bool IsMulticast() const;
     enum Network GetNetwork() const;
     std::string ToString() const;
     std::string ToStringIP() const;
     unsigned int GetByte(int n) const;
     uint64_t GetHash() const;
     bool GetInAddr(struct in_addr *pipv4Addr) const;
-    std::vector<unsigned char> GetGroup() const;
+    std::vector<uint8_t> GetGroup() const;
     int GetReachabilityFrom(const CNetAddr *paddrPartner = nullptr) const;
 
     CNetAddr(const struct in6_addr &pipv6Addr, const uint32_t scope = 0);
     bool GetIn6Addr(struct in6_addr *pipv6Addr) const;
 
     friend bool operator==(const CNetAddr &a, const CNetAddr &b);
     friend bool operator!=(const CNetAddr &a, const CNetAddr &b);
     friend bool operator<(const CNetAddr &a, const CNetAddr &b);
 
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
     inline void SerializationOp(Stream &s, Operation ser_action) {
         READWRITE(FLATDATA(ip));
     }
 
     friend class CSubNet;
 };
 
 class CSubNet {
 protected:
     /// Network (base) address
     CNetAddr network;
     /// Netmask, in network byte order
     uint8_t netmask[16];
     /// Is this value valid? (only used to signal parse errors)
     bool valid;
 
 public:
     CSubNet();
     CSubNet(const CNetAddr &addr, int32_t mask);
     CSubNet(const CNetAddr &addr, const CNetAddr &mask);
 
     // constructor for single ip subnet (<ipv4>/32 or <ipv6>/128)
     explicit CSubNet(const CNetAddr &addr);
 
     bool Match(const CNetAddr &addr) const;
 
     std::string ToString() const;
     bool IsValid() const;
 
     friend bool operator==(const CSubNet &a, const CSubNet &b);
     friend bool operator!=(const CSubNet &a, const CSubNet &b);
     friend bool operator<(const CSubNet &a, const CSubNet &b);
 
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
     inline void SerializationOp(Stream &s, Operation ser_action) {
         READWRITE(network);
         READWRITE(FLATDATA(netmask));
         READWRITE(FLATDATA(valid));
     }
 };
 
 /** A combination of a network address (CNetAddr) and a (TCP) port */
 class CService : public CNetAddr {
 protected:
     // host order
     unsigned short port;
 
 public:
     CService();
     CService(const CNetAddr &ip, unsigned short port);
     CService(const struct in_addr &ipv4Addr, unsigned short port);
     CService(const struct sockaddr_in &addr);
     void Init();
     void SetPort(unsigned short portIn);
     unsigned short GetPort() const;
     bool GetSockAddr(struct sockaddr *paddr, socklen_t *addrlen) const;
     bool SetSockAddr(const struct sockaddr *paddr);
     friend bool operator==(const CService &a, const CService &b);
     friend bool operator!=(const CService &a, const CService &b);
     friend bool operator<(const CService &a, const CService &b);
-    std::vector<unsigned char> GetKey() const;
+    std::vector<uint8_t> GetKey() const;
     std::string ToString() const;
     std::string ToStringPort() const;
     std::string ToStringIPPort() const;
 
     CService(const struct in6_addr &ipv6Addr, unsigned short port);
     CService(const struct sockaddr_in6 &addr);
 
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
     inline void SerializationOp(Stream &s, Operation ser_action) {
         READWRITE(FLATDATA(ip));
         unsigned short portN = htons(port);
         READWRITE(FLATDATA(portN));
         if (ser_action.ForRead()) port = ntohs(portN);
     }
 };
 
 #endif // BITCOIN_NETADDRESS_H
diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp
index 086a166ef..f31138832 100644
--- a/src/policy/policy.cpp
+++ b/src/policy/policy.cpp
@@ -1,145 +1,145 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 // NOTE: This file is intended to be customised by the end user, and includes
 // only local node policy logic
 
 #include "policy/policy.h"
 
 #include "tinyformat.h"
 #include "util.h"
 #include "utilstrencodings.h"
 #include "validation.h"
 
 /**
  * Check transaction inputs to mitigate two potential denial-of-service attacks:
  *
  * 1. scriptSigs with extra data stuffed into them, not consumed by scriptPubKey
  * (or P2SH script)
  * 2. P2SH scripts with a crazy number of expensive CHECKSIG/CHECKMULTISIG
  * operations
  *
  * Why bother? To avoid denial-of-service attacks; an attacker can submit a
  * standard HASH... OP_EQUAL transaction, which will get accepted into blocks.
  * The redemption script can be anything; an attacker could use a very
  * expensive-to-check-upon-redemption script like:
  *   DUP CHECKSIG DROP ... repeated 100 times... OP_1
  */
 bool IsStandard(const CScript &scriptPubKey, txnouttype &whichType) {
-    std::vector<std::vector<unsigned char>> vSolutions;
+    std::vector<std::vector<uint8_t>> vSolutions;
     if (!Solver(scriptPubKey, whichType, vSolutions)) return false;
 
     if (whichType == TX_MULTISIG) {
-        unsigned char m = vSolutions.front()[0];
-        unsigned char n = vSolutions.back()[0];
+        uint8_t m = vSolutions.front()[0];
+        uint8_t n = vSolutions.back()[0];
         // Support up to x-of-3 multisig txns as standard
         if (n < 1 || n > 3) return false;
         if (m < 1 || m > n) return false;
     } else if (whichType == TX_NULL_DATA &&
                (!fAcceptDatacarrier ||
                 scriptPubKey.size() > nMaxDatacarrierBytes))
         return false;
 
     return whichType != TX_NONSTANDARD;
 }
 
 bool IsStandardTx(const CTransaction &tx, std::string &reason) {
     if (tx.nVersion > CTransaction::MAX_STANDARD_VERSION || tx.nVersion < 1) {
         reason = "version";
         return false;
     }
 
     // Extremely large transactions with lots of inputs can cost the network
     // almost as much to process as they cost the sender in fees, because
     // computing signature hashes is O(ninputs*txsize). Limiting transactions
     // to MAX_STANDARD_TX_SIZE mitigates CPU exhaustion attacks.
     unsigned int sz = GetTransactionSize(tx);
     if (sz >= MAX_STANDARD_TX_SIZE) {
         reason = "tx-size";
         return false;
     }
 
     for (const CTxIn &txin : tx.vin) {
         // Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed
         // keys (remember the 520 byte limit on redeemScript size). That works
         // out to a (15*(33+1))+3=513 byte redeemScript, 513+1+15*(73+1)+3=1627
         // bytes of scriptSig, which we round off to 1650 bytes for some minor
         // future-proofing. That's also enough to spend a 20-of-20 CHECKMULTISIG
         // scriptPubKey, though such a scriptPubKey is not considered standard.
         if (txin.scriptSig.size() > 1650) {
             reason = "scriptsig-size";
             return false;
         }
         if (!txin.scriptSig.IsPushOnly()) {
             reason = "scriptsig-not-pushonly";
             return false;
         }
     }
 
     unsigned int nDataOut = 0;
     txnouttype whichType;
     for (const CTxOut &txout : tx.vout) {
         if (!::IsStandard(txout.scriptPubKey, whichType)) {
             reason = "scriptpubkey";
             return false;
         }
 
         if (whichType == TX_NULL_DATA)
             nDataOut++;
         else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) {
             reason = "bare-multisig";
             return false;
         } else if (txout.IsDust(dustRelayFee)) {
             reason = "dust";
             return false;
         }
     }
 
     // only one OP_RETURN txout is permitted
     if (nDataOut > 1) {
         reason = "multi-op-return";
         return false;
     }
 
     return true;
 }
 
 bool AreInputsStandard(const CTransaction &tx,
                        const CCoinsViewCache &mapInputs) {
     if (tx.IsCoinBase()) {
         // Coinbases don't use vin normally.
         return true;
     }
 
     for (unsigned int i = 0; i < tx.vin.size(); i++) {
         const CTxOut &prev = mapInputs.GetOutputFor(tx.vin[i]);
 
-        std::vector<std::vector<unsigned char>> vSolutions;
+        std::vector<std::vector<uint8_t>> vSolutions;
         txnouttype whichType;
         // get the scriptPubKey corresponding to this input:
         const CScript &prevScript = prev.scriptPubKey;
         if (!Solver(prevScript, whichType, vSolutions)) return false;
 
         if (whichType == TX_SCRIPTHASH) {
-            std::vector<std::vector<unsigned char>> stack;
+            std::vector<std::vector<uint8_t>> stack;
             // convert the scriptSig into a stack, so we can inspect the
             // redeemScript
             if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE,
                             BaseSignatureChecker()))
                 return false;
             if (stack.empty()) return false;
             CScript subscript(stack.back().begin(), stack.back().end());
             if (subscript.GetSigOpCount(true) > MAX_P2SH_SIGOPS) {
                 return false;
             }
         }
     }
 
     return true;
 }
 
 CFeeRate incrementalRelayFee = CFeeRate(DEFAULT_INCREMENTAL_RELAY_FEE);
 CFeeRate dustRelayFee = CFeeRate(DUST_RELAY_TX_FEE);
 unsigned int nBytesPerSigOp = DEFAULT_BYTES_PER_SIGOP;
diff --git a/src/protocol.h b/src/protocol.h
index f08e7d180..2c169eeab 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -1,380 +1,380 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #ifndef __cplusplus
 #error This header can only be compiled as C++.
 #endif
 
 #ifndef BITCOIN_PROTOCOL_H
 #define BITCOIN_PROTOCOL_H
 
 #include "netaddress.h"
 #include "serialize.h"
 #include "uint256.h"
 #include "version.h"
 
 #include <cstdint>
 #include <string>
 
 /** Message header.
  * (4) message start.
  * (12) command.
  * (4) size.
  * (4) checksum.
  */
 class CMessageHeader {
 public:
     enum {
         MESSAGE_START_SIZE = 4,
         COMMAND_SIZE = 12,
         MESSAGE_SIZE_SIZE = 4,
         CHECKSUM_SIZE = 4,
 
         MESSAGE_SIZE_OFFSET = MESSAGE_START_SIZE + COMMAND_SIZE,
         CHECKSUM_OFFSET = MESSAGE_SIZE_OFFSET + MESSAGE_SIZE_SIZE,
         HEADER_SIZE = MESSAGE_START_SIZE + COMMAND_SIZE + MESSAGE_SIZE_SIZE +
                       CHECKSUM_SIZE
     };
-    typedef unsigned char MessageStartChars[MESSAGE_START_SIZE];
+    typedef uint8_t MessageStartChars[MESSAGE_START_SIZE];
 
     CMessageHeader(const MessageStartChars &pchMessageStartIn);
     CMessageHeader(const MessageStartChars &pchMessageStartIn,
                    const char *pszCommand, unsigned int nMessageSizeIn);
 
     std::string GetCommand() const;
     bool IsValid(const MessageStartChars &messageStart) const;
 
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
     inline void SerializationOp(Stream &s, Operation ser_action) {
         READWRITE(FLATDATA(pchMessageStart));
         READWRITE(FLATDATA(pchCommand));
         READWRITE(nMessageSize);
         READWRITE(FLATDATA(pchChecksum));
     }
 
     char pchMessageStart[MESSAGE_START_SIZE];
     char pchCommand[COMMAND_SIZE];
     uint32_t nMessageSize;
     uint8_t pchChecksum[CHECKSUM_SIZE];
 };
 
 /**
  * Bitcoin protocol message types. When adding new message types, don't forget
  * to update allNetMessageTypes in protocol.cpp.
  */
 namespace NetMsgType {
 
 /**
  * The version message provides information about the transmitting node to the
  * receiving node at the beginning of a connection.
  * @see https://bitcoin.org/en/developer-reference#version
  */
 extern const char *VERSION;
 /**
  * The verack message acknowledges a previously-received version message,
  * informing the connecting node that it can begin to send other messages.
  * @see https://bitcoin.org/en/developer-reference#verack
  */
 extern const char *VERACK;
 /**
  * The addr (IP address) message relays connection information for peers on the
  * network.
  * @see https://bitcoin.org/en/developer-reference#addr
  */
 extern const char *ADDR;
 /**
  * The inv message (inventory message) transmits one or more inventories of
  * objects known to the transmitting peer.
  * @see https://bitcoin.org/en/developer-reference#inv
  */
 extern const char *INV;
 /**
  * The getdata message requests one or more data objects from another node.
  * @see https://bitcoin.org/en/developer-reference#getdata
  */
 extern const char *GETDATA;
 /**
  * The merkleblock message is a reply to a getdata message which requested a
  * block using the inventory type MSG_MERKLEBLOCK.
  * @since protocol version 70001 as described by BIP37.
  * @see https://bitcoin.org/en/developer-reference#merkleblock
  */
 extern const char *MERKLEBLOCK;
 /**
  * The getblocks message requests an inv message that provides block header
  * hashes starting from a particular point in the block chain.
  * @see https://bitcoin.org/en/developer-reference#getblocks
  */
 extern const char *GETBLOCKS;
 /**
  * The getheaders message requests a headers message that provides block
  * headers starting from a particular point in the block chain.
  * @since protocol version 31800.
  * @see https://bitcoin.org/en/developer-reference#getheaders
  */
 extern const char *GETHEADERS;
 /**
  * The tx message transmits a single transaction.
  * @see https://bitcoin.org/en/developer-reference#tx
  */
 extern const char *TX;
 /**
  * The headers message sends one or more block headers to a node which
  * previously requested certain headers with a getheaders message.
  * @since protocol version 31800.
  * @see https://bitcoin.org/en/developer-reference#headers
  */
 extern const char *HEADERS;
 /**
  * The block message transmits a single serialized block.
  * @see https://bitcoin.org/en/developer-reference#block
  */
 extern const char *BLOCK;
 /**
  * The getaddr message requests an addr message from the receiving node,
  * preferably one with lots of IP addresses of other receiving nodes.
  * @see https://bitcoin.org/en/developer-reference#getaddr
  */
 extern const char *GETADDR;
 /**
  * The mempool message requests the TXIDs of transactions that the receiving
  * node has verified as valid but which have not yet appeared in a block.
  * @since protocol version 60002.
  * @see https://bitcoin.org/en/developer-reference#mempool
  */
 extern const char *MEMPOOL;
 /**
  * The ping message is sent periodically to help confirm that the receiving
  * peer is still connected.
  * @see https://bitcoin.org/en/developer-reference#ping
  */
 extern const char *PING;
 /**
  * The pong message replies to a ping message, proving to the pinging node that
  * the ponging node is still alive.
  * @since protocol version 60001 as described by BIP31.
  * @see https://bitcoin.org/en/developer-reference#pong
  */
 extern const char *PONG;
 /**
  * The notfound message is a reply to a getdata message which requested an
  * object the receiving node does not have available for relay.
  * @ince protocol version 70001.
  * @see https://bitcoin.org/en/developer-reference#notfound
  */
 extern const char *NOTFOUND;
 /**
  * The filterload message tells the receiving peer to filter all relayed
  * transactions and requested merkle blocks through the provided filter.
  * @since protocol version 70001 as described by BIP37.
  *   Only available with service bit NODE_BLOOM since protocol version
  *   70011 as described by BIP111.
  * @see https://bitcoin.org/en/developer-reference#filterload
  */
 extern const char *FILTERLOAD;
 /**
  * The filteradd message tells the receiving peer to add a single element to a
  * previously-set bloom filter, such as a new public key.
  * @since protocol version 70001 as described by BIP37.
  *   Only available with service bit NODE_BLOOM since protocol version
  *   70011 as described by BIP111.
  * @see https://bitcoin.org/en/developer-reference#filteradd
  */
 extern const char *FILTERADD;
 /**
  * The filterclear message tells the receiving peer to remove a previously-set
  * bloom filter.
  * @since protocol version 70001 as described by BIP37.
  *   Only available with service bit NODE_BLOOM since protocol version
  *   70011 as described by BIP111.
  * @see https://bitcoin.org/en/developer-reference#filterclear
  */
 extern const char *FILTERCLEAR;
 /**
  * The reject message informs the receiving node that one of its previous
  * messages has been rejected.
  * @since protocol version 70002 as described by BIP61.
  * @see https://bitcoin.org/en/developer-reference#reject
  */
 extern const char *REJECT;
 /**
  * Indicates that a node prefers to receive new block announcements via a
  * "headers" message rather than an "inv".
  * @since protocol version 70012 as described by BIP130.
  * @see https://bitcoin.org/en/developer-reference#sendheaders
  */
 extern const char *SENDHEADERS;
 /**
  * The feefilter message tells the receiving peer not to inv us any txs
  * which do not meet the specified min fee rate.
  * @since protocol version 70013 as described by BIP133
  */
 extern const char *FEEFILTER;
 /**
  * Contains a 1-byte bool and 8-byte LE version number.
  * Indicates that a node is willing to provide blocks via "cmpctblock" messages.
  * May indicate that a node prefers to receive new block announcements via a
  * "cmpctblock" message rather than an "inv", depending on message contents.
  * @since protocol version 70014 as described by BIP 152
  */
 extern const char *SENDCMPCT;
 /**
  * Contains a CBlockHeaderAndShortTxIDs object - providing a header and
  * list of "short txids".
  * @since protocol version 70014 as described by BIP 152
  */
 extern const char *CMPCTBLOCK;
 /**
  * Contains a BlockTransactionsRequest
  * Peer should respond with "blocktxn" message.
  * @since protocol version 70014 as described by BIP 152
  */
 extern const char *GETBLOCKTXN;
 /**
  * Contains a BlockTransactions.
  * Sent in response to a "getblocktxn" message.
  * @since protocol version 70014 as described by BIP 152
  */
 extern const char *BLOCKTXN;
 };
 
 /* Get a vector of all valid message types (see above) */
 const std::vector<std::string> &getAllNetMessageTypes();
 
 /** nServices flags */
 enum ServiceFlags : uint64_t {
     // Nothing
     NODE_NONE = 0,
     // NODE_NETWORK means that the node is capable of serving the block chain.
     // It is currently set by all Bitcoin Core nodes, and is unset by SPV
     // clients or other peers that just want network services but don't provide
     // them.
     NODE_NETWORK = (1 << 0),
     // NODE_GETUTXO means the node is capable of responding to the getutxo
     // protocol request. Bitcoin Core does not support this but a patch set
     // called Bitcoin XT does. See BIP 64 for details on how this is
     // implemented.
     NODE_GETUTXO = (1 << 1),
     // NODE_BLOOM means the node is capable and willing to handle bloom-filtered
     // connections. Bitcoin Core nodes used to support this by default, without
     // advertising this bit, but no longer do as of protocol version 70011 (=
     // NO_BLOOM_VERSION)
     NODE_BLOOM = (1 << 2),
     // NODE_XTHIN means the node supports Xtreme Thinblocks. If this is turned
     // off then the node will not service nor make xthin requests.
     NODE_XTHIN = (1 << 4),
     // NODE_BITCOIN_CASH means the node supports Bitcoin Cash and the
     // associated consensus rule changes.
     // This service bit is intended to be used prior until some time after the
     // UAHF activation when the Bitcoin Cash network has adequately separated.
     // TODO: remove (free up) the NODE_BITCOIN_CASH service bit once no longer
     // needed.
     NODE_BITCOIN_CASH = (1 << 5),
 
     // Bits 24-31 are reserved for temporary experiments. Just pick a bit that
     // isn't getting used, or one not being used much, and notify the
     // bitcoin-development mailing list. Remember that service bits are just
     // unauthenticated advertisements, so your code must be robust against
     // collisions and other cases where nodes may be advertising a service they
     // do not actually support. Other service bits should be allocated via the
     // BIP process.
 };
 
 /** A CService with information about it as peer */
 class CAddress : public CService {
 public:
     CAddress();
     explicit CAddress(CService ipIn, ServiceFlags nServicesIn);
 
     void Init();
 
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
     inline void SerializationOp(Stream &s, Operation ser_action) {
         if (ser_action.ForRead()) Init();
         int nVersion = s.GetVersion();
         if (s.GetType() & SER_DISK) READWRITE(nVersion);
         if ((s.GetType() & SER_DISK) ||
             (nVersion >= CADDR_TIME_VERSION && !(s.GetType() & SER_GETHASH)))
             READWRITE(nTime);
         uint64_t nServicesInt = nServices;
         READWRITE(nServicesInt);
         nServices = (ServiceFlags)nServicesInt;
         READWRITE(*(CService *)this);
     }
 
     // TODO: make private (improves encapsulation)
 public:
     ServiceFlags nServices;
 
     // disk and network only
     unsigned int nTime;
 };
 
 /** getdata message type flags */
 const uint32_t MSG_EXT_FLAG = 1 << 29;
 const uint32_t MSG_TYPE_MASK = 0xffffffff >> 3;
 
 /** getdata / inv message types.
  * These numbers are defined by the protocol. When adding a new value, be sure
  * to mention it in the respective BIP.
  */
 enum GetDataMsg {
     UNDEFINED = 0,
     MSG_TX = 1,
     MSG_BLOCK = 2,
     // The following can only occur in getdata. Invs always use TX or BLOCK.
     //!< Defined in BIP37
     MSG_FILTERED_BLOCK = 3,
     //!< Defined in BIP152
     MSG_CMPCT_BLOCK = 4,
 
     //!< Extension block
     MSG_EXT_TX = MSG_TX | MSG_EXT_FLAG,
     MSG_EXT_BLOCK = MSG_BLOCK | MSG_EXT_FLAG,
 };
 
 /** inv message data */
 class CInv {
 public:
     CInv();
     CInv(int typeIn, const uint256 &hashIn);
 
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
     inline void SerializationOp(Stream &s, Operation ser_action) {
         READWRITE(type);
         READWRITE(hash);
     }
 
     friend bool operator<(const CInv &a, const CInv &b);
 
     std::string GetCommand() const;
     std::string ToString() const;
 
     uint32_t GetKind() const { return type & MSG_TYPE_MASK; }
 
     bool IsTx() const {
         auto k = GetKind();
         return k == MSG_TX;
     }
 
     bool IsSomeBlock() const {
         auto k = GetKind();
         return k == MSG_BLOCK || k == MSG_FILTERED_BLOCK ||
                k == MSG_CMPCT_BLOCK;
     }
 
     // TODO: make private (improves encapsulation)
 public:
     int type;
     uint256 hash;
 };
 
 #endif // BITCOIN_PROTOCOL_H
diff --git a/src/pubkey.cpp b/src/pubkey.cpp
index f20626c6b..6d30b760f 100644
--- a/src/pubkey.cpp
+++ b/src/pubkey.cpp
@@ -1,323 +1,323 @@
 // Copyright (c) 2009-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.
 
 #include "pubkey.h"
 
 #include <secp256k1.h>
 #include <secp256k1_recovery.h>
 
 namespace {
 /* Global secp256k1_context object used for verification. */
 secp256k1_context *secp256k1_context_verify = nullptr;
 }
 
 /**
  * This function is taken from the libsecp256k1 distribution and implements DER
  * parsing for ECDSA signatures, while supporting an arbitrary subset of format
  * violations.
  *
  * Supported violations include negative integers, excessive padding, garbage at
  * the end, and overly long length descriptors. This is safe to use in Bitcoin
  * because since the activation of BIP66, signatures are verified to be strict
  * DER before being passed to this module, and we know it supports all
  * violations present in the blockchain before that point.
  */
 static int ecdsa_signature_parse_der_lax(const secp256k1_context *ctx,
                                          secp256k1_ecdsa_signature *sig,
-                                         const unsigned char *input,
+                                         const uint8_t *input,
                                          size_t inputlen) {
     size_t rpos, rlen, spos, slen;
     size_t pos = 0;
     size_t lenbyte;
-    unsigned char tmpsig[64] = {0};
+    uint8_t tmpsig[64] = {0};
     int overflow = 0;
 
     /* Hack to initialize sig with a correctly-parsed but invalid signature. */
     secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
 
     /* Sequence tag byte */
     if (pos == inputlen || input[pos] != 0x30) {
         return 0;
     }
     pos++;
 
     /* Sequence length bytes */
     if (pos == inputlen) {
         return 0;
     }
     lenbyte = input[pos++];
     if (lenbyte & 0x80) {
         lenbyte -= 0x80;
         if (pos + lenbyte > inputlen) {
             return 0;
         }
         pos += lenbyte;
     }
 
     /* Integer tag byte for R */
     if (pos == inputlen || input[pos] != 0x02) {
         return 0;
     }
     pos++;
 
     /* Integer length for R */
     if (pos == inputlen) {
         return 0;
     }
     lenbyte = input[pos++];
     if (lenbyte & 0x80) {
         lenbyte -= 0x80;
         if (pos + lenbyte > inputlen) {
             return 0;
         }
         while (lenbyte > 0 && input[pos] == 0) {
             pos++;
             lenbyte--;
         }
         if (lenbyte >= sizeof(size_t)) {
             return 0;
         }
         rlen = 0;
         while (lenbyte > 0) {
             rlen = (rlen << 8) + input[pos];
             pos++;
             lenbyte--;
         }
     } else {
         rlen = lenbyte;
     }
     if (rlen > inputlen - pos) {
         return 0;
     }
     rpos = pos;
     pos += rlen;
 
     /* Integer tag byte for S */
     if (pos == inputlen || input[pos] != 0x02) {
         return 0;
     }
     pos++;
 
     /* Integer length for S */
     if (pos == inputlen) {
         return 0;
     }
     lenbyte = input[pos++];
     if (lenbyte & 0x80) {
         lenbyte -= 0x80;
         if (pos + lenbyte > inputlen) {
             return 0;
         }
         while (lenbyte > 0 && input[pos] == 0) {
             pos++;
             lenbyte--;
         }
         if (lenbyte >= sizeof(size_t)) {
             return 0;
         }
         slen = 0;
         while (lenbyte > 0) {
             slen = (slen << 8) + input[pos];
             pos++;
             lenbyte--;
         }
     } else {
         slen = lenbyte;
     }
     if (slen > inputlen - pos) {
         return 0;
     }
     spos = pos;
     pos += slen;
 
     /* Ignore leading zeroes in R */
     while (rlen > 0 && input[rpos] == 0) {
         rlen--;
         rpos++;
     }
     /* Copy R value */
     if (rlen > 32) {
         overflow = 1;
     } else {
         memcpy(tmpsig + 32 - rlen, input + rpos, rlen);
     }
 
     /* Ignore leading zeroes in S */
     while (slen > 0 && input[spos] == 0) {
         slen--;
         spos++;
     }
     /* Copy S value */
     if (slen > 32) {
         overflow = 1;
     } else {
         memcpy(tmpsig + 64 - slen, input + spos, slen);
     }
 
     if (!overflow) {
         overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
     }
     if (overflow) {
         /* Overwrite the result again with a correctly-parsed but invalid
            signature if parsing failed. */
         memset(tmpsig, 0, 64);
         secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
     }
     return 1;
 }
 
 bool CPubKey::Verify(const uint256 &hash,
-                     const std::vector<unsigned char> &vchSig) const {
+                     const std::vector<uint8_t> &vchSig) const {
     if (!IsValid()) return false;
     secp256k1_pubkey pubkey;
     secp256k1_ecdsa_signature sig;
     if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey,
                                    &(*this)[0], size())) {
         return false;
     }
     if (vchSig.size() == 0) {
         return false;
     }
     if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig,
                                        &vchSig[0], vchSig.size())) {
         return false;
     }
     /**
      * libsecp256k1's ECDSA verification requires lower-S signatures, which have
      * not historically been enforced in Bitcoin, so normalize them first.
      */
     secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, &sig, &sig);
     return secp256k1_ecdsa_verify(secp256k1_context_verify, &sig, hash.begin(),
                                   &pubkey);
 }
 
 bool CPubKey::RecoverCompact(const uint256 &hash,
-                             const std::vector<unsigned char> &vchSig) {
+                             const std::vector<uint8_t> &vchSig) {
     if (vchSig.size() != 65) return false;
     int recid = (vchSig[0] - 27) & 3;
     bool fComp = ((vchSig[0] - 27) & 4) != 0;
     secp256k1_pubkey pubkey;
     secp256k1_ecdsa_recoverable_signature sig;
     if (!secp256k1_ecdsa_recoverable_signature_parse_compact(
             secp256k1_context_verify, &sig, &vchSig[1], recid)) {
         return false;
     }
     if (!secp256k1_ecdsa_recover(secp256k1_context_verify, &pubkey, &sig,
                                  hash.begin())) {
         return false;
     }
-    unsigned char pub[65];
+    uint8_t pub[65];
     size_t publen = 65;
     secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen,
                                   &pubkey, fComp ? SECP256K1_EC_COMPRESSED
                                                  : SECP256K1_EC_UNCOMPRESSED);
     Set(pub, pub + publen);
     return true;
 }
 
 bool CPubKey::IsFullyValid() const {
     if (!IsValid()) return false;
     secp256k1_pubkey pubkey;
     return secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey,
                                      &(*this)[0], size());
 }
 
 bool CPubKey::Decompress() {
     if (!IsValid()) return false;
     secp256k1_pubkey pubkey;
     if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey,
                                    &(*this)[0], size())) {
         return false;
     }
-    unsigned char pub[65];
+    uint8_t pub[65];
     size_t publen = 65;
     secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen,
                                   &pubkey, SECP256K1_EC_UNCOMPRESSED);
     Set(pub, pub + publen);
     return true;
 }
 
 bool CPubKey::Derive(CPubKey &pubkeyChild, ChainCode &ccChild,
                      unsigned int nChild, const ChainCode &cc) const {
     assert(IsValid());
     assert((nChild >> 31) == 0);
     assert(begin() + 33 == end());
-    unsigned char out[64];
+    uint8_t out[64];
     BIP32Hash(cc, nChild, *begin(), begin() + 1, out);
     memcpy(ccChild.begin(), out + 32, 32);
     secp256k1_pubkey pubkey;
     if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey,
                                    &(*this)[0], size())) {
         return false;
     }
     if (!secp256k1_ec_pubkey_tweak_add(secp256k1_context_verify, &pubkey,
                                        out)) {
         return false;
     }
-    unsigned char pub[33];
+    uint8_t pub[33];
     size_t publen = 33;
     secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen,
                                   &pubkey, SECP256K1_EC_COMPRESSED);
     pubkeyChild.Set(pub, pub + publen);
     return true;
 }
 
-void CExtPubKey::Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const {
+void CExtPubKey::Encode(uint8_t code[BIP32_EXTKEY_SIZE]) const {
     code[0] = nDepth;
     memcpy(code + 1, vchFingerprint, 4);
     code[5] = (nChild >> 24) & 0xFF;
     code[6] = (nChild >> 16) & 0xFF;
     code[7] = (nChild >> 8) & 0xFF;
     code[8] = (nChild >> 0) & 0xFF;
     memcpy(code + 9, chaincode.begin(), 32);
     assert(pubkey.size() == 33);
     memcpy(code + 41, pubkey.begin(), 33);
 }
 
-void CExtPubKey::Decode(const unsigned char code[BIP32_EXTKEY_SIZE]) {
+void CExtPubKey::Decode(const uint8_t code[BIP32_EXTKEY_SIZE]) {
     nDepth = code[0];
     memcpy(vchFingerprint, code + 1, 4);
     nChild = (code[5] << 24) | (code[6] << 16) | (code[7] << 8) | code[8];
     memcpy(chaincode.begin(), code + 9, 32);
     pubkey.Set(code + 41, code + BIP32_EXTKEY_SIZE);
 }
 
 bool CExtPubKey::Derive(CExtPubKey &out, unsigned int _nChild) const {
     out.nDepth = nDepth + 1;
     CKeyID id = pubkey.GetID();
     memcpy(&out.vchFingerprint[0], &id, 4);
     out.nChild = _nChild;
     return pubkey.Derive(out.pubkey, out.chaincode, _nChild, chaincode);
 }
 
-/* static */ bool CPubKey::CheckLowS(const std::vector<unsigned char> &vchSig) {
+/* static */ bool CPubKey::CheckLowS(const std::vector<uint8_t> &vchSig) {
     secp256k1_ecdsa_signature sig;
     if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig,
                                        &vchSig[0], vchSig.size())) {
         return false;
     }
     return (!secp256k1_ecdsa_signature_normalize(secp256k1_context_verify,
                                                  nullptr, &sig));
 }
 
 /* static */ int ECCVerifyHandle::refcount = 0;
 
 ECCVerifyHandle::ECCVerifyHandle() {
     if (refcount == 0) {
         assert(secp256k1_context_verify == nullptr);
         secp256k1_context_verify =
             secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
         assert(secp256k1_context_verify != nullptr);
     }
     refcount++;
 }
 
 ECCVerifyHandle::~ECCVerifyHandle() {
     refcount--;
     if (refcount == 0) {
         assert(secp256k1_context_verify != nullptr);
         secp256k1_context_destroy(secp256k1_context_verify);
         secp256k1_context_verify = nullptr;
     }
 }
diff --git a/src/pubkey.h b/src/pubkey.h
index 4865660a7..8b1606a38 100644
--- a/src/pubkey.h
+++ b/src/pubkey.h
@@ -1,213 +1,210 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_PUBKEY_H
 #define BITCOIN_PUBKEY_H
 
 #include "hash.h"
 #include "serialize.h"
 #include "uint256.h"
 
 #include <stdexcept>
 #include <vector>
 
 /**
  * secp256k1:
  * const unsigned int PRIVATE_KEY_SIZE = 279;
  * const unsigned int PUBLIC_KEY_SIZE  = 65;
  * const unsigned int SIGNATURE_SIZE   = 72;
  *
  * see www.keylength.com
  * script supports up to 75 for single byte push
  */
 
 const unsigned int BIP32_EXTKEY_SIZE = 74;
 
 /** A reference to a CKey: the Hash160 of its serialized public key */
 class CKeyID : public uint160 {
 public:
     CKeyID() : uint160() {}
     CKeyID(const uint160 &in) : uint160(in) {}
 };
 
 typedef uint256 ChainCode;
 
 /** An encapsulated public key. */
 class CPubKey {
 private:
     /**
      * Just store the serialized data.
      * Its length can very cheaply be computed from the first byte.
      */
-    unsigned char vch[65];
+    uint8_t vch[65];
 
     //! Compute the length of a pubkey with a given first byte.
-    static unsigned int GetLen(unsigned char chHeader) {
+    static unsigned int GetLen(uint8_t chHeader) {
         if (chHeader == 2 || chHeader == 3) return 33;
         if (chHeader == 4 || chHeader == 6 || chHeader == 7) return 65;
         return 0;
     }
 
     //! Set this key data to be invalid
     void Invalidate() { vch[0] = 0xFF; }
 
 public:
     //! Construct an invalid public key.
     CPubKey() { Invalidate(); }
 
     //! Initialize a public key using begin/end iterators to byte data.
     template <typename T> void Set(const T pbegin, const T pend) {
         int len = pend == pbegin ? 0 : GetLen(pbegin[0]);
         if (len && len == (pend - pbegin))
-            memcpy(vch, (unsigned char *)&pbegin[0], len);
+            memcpy(vch, (uint8_t *)&pbegin[0], len);
         else
             Invalidate();
     }
 
     //! Construct a public key using begin/end iterators to byte data.
     template <typename T> CPubKey(const T pbegin, const T pend) {
         Set(pbegin, pend);
     }
 
     //! Construct a public key from a byte vector.
-    CPubKey(const std::vector<unsigned char> &_vch) {
-        Set(_vch.begin(), _vch.end());
-    }
+    CPubKey(const std::vector<uint8_t> &_vch) { Set(_vch.begin(), _vch.end()); }
 
     //! Simple read-only vector-like interface to the pubkey data.
     unsigned int size() const { return GetLen(vch[0]); }
-    const unsigned char *begin() const { return vch; }
-    const unsigned char *end() const { return vch + size(); }
-    const unsigned char &operator[](unsigned int pos) const { return vch[pos]; }
+    const uint8_t *begin() const { return vch; }
+    const uint8_t *end() const { return vch + size(); }
+    const uint8_t &operator[](unsigned int pos) const { return vch[pos]; }
 
     //! Comparator implementation.
     friend bool operator==(const CPubKey &a, const CPubKey &b) {
         return a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) == 0;
     }
     friend bool operator!=(const CPubKey &a, const CPubKey &b) {
         return !(a == b);
     }
     friend bool operator<(const CPubKey &a, const CPubKey &b) {
         return a.vch[0] < b.vch[0] ||
                (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) < 0);
     }
 
     //! Implement serialization, as if this was a byte vector.
     template <typename Stream> void Serialize(Stream &s) const {
         unsigned int len = size();
         ::WriteCompactSize(s, len);
         s.write((char *)vch, len);
     }
     template <typename Stream> void Unserialize(Stream &s) {
         unsigned int len = ::ReadCompactSize(s);
         if (len <= 65) {
             s.read((char *)vch, len);
         } else {
             // invalid pubkey, skip available data
             char dummy;
             while (len--)
                 s.read(&dummy, 1);
             Invalidate();
         }
     }
 
     //! Get the KeyID of this public key (hash of its serialization)
     CKeyID GetID() const { return CKeyID(Hash160(vch, vch + size())); }
 
     //! Get the 256-bit hash of this public key.
     uint256 GetHash() const { return Hash(vch, vch + size()); }
 
     /*
      * Check syntactic correctness.
      *
      * Note that this is consensus critical as CheckSig() calls it!
      */
     bool IsValid() const { return size() > 0; }
 
     //! fully validate whether this is a valid public key (more expensive than
     //! IsValid())
     bool IsFullyValid() const;
 
     //! Check whether this is a compressed public key.
     bool IsCompressed() const { return size() == 33; }
 
     /**
      * Verify a DER signature (~72 bytes).
      * If this public key is not fully valid, the return value will be false.
      */
-    bool Verify(const uint256 &hash,
-                const std::vector<unsigned char> &vchSig) const;
+    bool Verify(const uint256 &hash, const std::vector<uint8_t> &vchSig) const;
 
     /**
      * Check whether a signature is normalized (lower-S).
      */
-    static bool CheckLowS(const std::vector<unsigned char> &vchSig);
+    static bool CheckLowS(const std::vector<uint8_t> &vchSig);
 
     //! Recover a public key from a compact signature.
     bool RecoverCompact(const uint256 &hash,
-                        const std::vector<unsigned char> &vchSig);
+                        const std::vector<uint8_t> &vchSig);
 
     //! Turn this public key into an uncompressed public key.
     bool Decompress();
 
     //! Derive BIP32 child pubkey.
     bool Derive(CPubKey &pubkeyChild, ChainCode &ccChild, unsigned int nChild,
                 const ChainCode &cc) const;
 };
 
 struct CExtPubKey {
-    unsigned char nDepth;
-    unsigned char vchFingerprint[4];
+    uint8_t nDepth;
+    uint8_t vchFingerprint[4];
     unsigned int nChild;
     ChainCode chaincode;
     CPubKey pubkey;
 
     friend bool operator==(const CExtPubKey &a, const CExtPubKey &b) {
         return a.nDepth == b.nDepth &&
                memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0],
                       sizeof(vchFingerprint)) == 0 &&
                a.nChild == b.nChild && a.chaincode == b.chaincode &&
                a.pubkey == b.pubkey;
     }
 
-    void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const;
-    void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]);
+    void Encode(uint8_t code[BIP32_EXTKEY_SIZE]) const;
+    void Decode(const uint8_t code[BIP32_EXTKEY_SIZE]);
     bool Derive(CExtPubKey &out, unsigned int nChild) const;
 
     void Serialize(CSizeComputer &s) const {
         // Optimized implementation for ::GetSerializeSize that avoids copying.
         // add one byte for the size (compact int)
         s.seek(BIP32_EXTKEY_SIZE + 1);
     }
     template <typename Stream> void Serialize(Stream &s) const {
         unsigned int len = BIP32_EXTKEY_SIZE;
         ::WriteCompactSize(s, len);
-        unsigned char code[BIP32_EXTKEY_SIZE];
+        uint8_t code[BIP32_EXTKEY_SIZE];
         Encode(code);
         s.write((const char *)&code[0], len);
     }
     template <typename Stream> void Unserialize(Stream &s) {
         unsigned int len = ::ReadCompactSize(s);
-        unsigned char code[BIP32_EXTKEY_SIZE];
+        uint8_t code[BIP32_EXTKEY_SIZE];
         if (len != BIP32_EXTKEY_SIZE)
             throw std::runtime_error("Invalid extended key size\n");
         s.read((char *)&code[0], len);
         Decode(code);
     }
 };
 
 /**
  * Users of this module must hold an ECCVerifyHandle. The constructor and
  * destructor of these are not allowed to run in parallel, though.
  */
 class ECCVerifyHandle {
     static int refcount;
 
 public:
     ECCVerifyHandle();
     ~ECCVerifyHandle();
 };
 
 #endif // BITCOIN_PUBKEY_H
diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp
index fc1722156..b519dcb9f 100644
--- a/src/qt/coincontroldialog.cpp
+++ b/src/qt/coincontroldialog.cpp
@@ -1,842 +1,841 @@
 // Copyright (c) 2011-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.
 
 #include "coincontroldialog.h"
 #include "ui_coincontroldialog.h"
 
 #include "addresstablemodel.h"
 #include "bitcoinunits.h"
 #include "guiutil.h"
 #include "optionsmodel.h"
 #include "platformstyle.h"
 #include "txmempool.h"
 #include "walletmodel.h"
 
 #include "init.h"
 #include "policy/policy.h"
 #include "validation.h" // For mempool
 #include "wallet/coincontrol.h"
 #include "wallet/wallet.h"
 
 #include <boost/assign/list_of.hpp> // for 'map_list_of()'
 
 #include <QApplication>
 #include <QCheckBox>
 #include <QCursor>
 #include <QDialogButtonBox>
 #include <QFlags>
 #include <QIcon>
 #include <QSettings>
 #include <QString>
 #include <QTreeWidget>
 #include <QTreeWidgetItem>
 
 QList<CAmount> CoinControlDialog::payAmounts;
 CCoinControl *CoinControlDialog::coinControl = new CCoinControl();
 bool CoinControlDialog::fSubtractFeeFromAmount = false;
 
 bool CCoinControlWidgetItem::operator<(const QTreeWidgetItem &other) const {
     int column = treeWidget()->sortColumn();
     if (column == CoinControlDialog::COLUMN_AMOUNT ||
         column == CoinControlDialog::COLUMN_DATE ||
         column == CoinControlDialog::COLUMN_CONFIRMATIONS)
         return data(column, Qt::UserRole).toLongLong() <
                other.data(column, Qt::UserRole).toLongLong();
     return QTreeWidgetItem::operator<(other);
 }
 
 CoinControlDialog::CoinControlDialog(const PlatformStyle *_platformStyle,
                                      QWidget *parent)
     : QDialog(parent), ui(new Ui::CoinControlDialog), model(0),
       platformStyle(_platformStyle) {
     ui->setupUi(this);
 
     // context menu actions
     QAction *copyAddressAction = new QAction(tr("Copy address"), this);
     QAction *copyLabelAction = new QAction(tr("Copy label"), this);
     QAction *copyAmountAction = new QAction(tr("Copy amount"), this);
     // we need to enable/disable this
     copyTransactionHashAction = new QAction(tr("Copy transaction ID"), this);
     // we need to enable/disable this
     lockAction = new QAction(tr("Lock unspent"), this);
     // we need to enable/disable this
     unlockAction = new QAction(tr("Unlock unspent"), this);
 
     // context menu
     contextMenu = new QMenu(this);
     contextMenu->addAction(copyAddressAction);
     contextMenu->addAction(copyLabelAction);
     contextMenu->addAction(copyAmountAction);
     contextMenu->addAction(copyTransactionHashAction);
     contextMenu->addSeparator();
     contextMenu->addAction(lockAction);
     contextMenu->addAction(unlockAction);
 
     // context menu signals
     connect(ui->treeWidget, SIGNAL(customContextMenuRequested(QPoint)), this,
             SLOT(showMenu(QPoint)));
     connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(copyAddress()));
     connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(copyLabel()));
     connect(copyAmountAction, SIGNAL(triggered()), this, SLOT(copyAmount()));
     connect(copyTransactionHashAction, SIGNAL(triggered()), this,
             SLOT(copyTransactionHash()));
     connect(lockAction, SIGNAL(triggered()), this, SLOT(lockCoin()));
     connect(unlockAction, SIGNAL(triggered()), this, SLOT(unlockCoin()));
 
     // clipboard actions
     QAction *clipboardQuantityAction = new QAction(tr("Copy quantity"), this);
     QAction *clipboardAmountAction = new QAction(tr("Copy amount"), this);
     QAction *clipboardFeeAction = new QAction(tr("Copy fee"), this);
     QAction *clipboardAfterFeeAction = new QAction(tr("Copy after fee"), this);
     QAction *clipboardBytesAction = new QAction(tr("Copy bytes"), this);
     QAction *clipboardLowOutputAction = new QAction(tr("Copy dust"), this);
     QAction *clipboardChangeAction = new QAction(tr("Copy change"), this);
 
     connect(clipboardQuantityAction, SIGNAL(triggered()), this,
             SLOT(clipboardQuantity()));
     connect(clipboardAmountAction, SIGNAL(triggered()), this,
             SLOT(clipboardAmount()));
     connect(clipboardFeeAction, SIGNAL(triggered()), this,
             SLOT(clipboardFee()));
     connect(clipboardAfterFeeAction, SIGNAL(triggered()), this,
             SLOT(clipboardAfterFee()));
     connect(clipboardBytesAction, SIGNAL(triggered()), this,
             SLOT(clipboardBytes()));
     connect(clipboardLowOutputAction, SIGNAL(triggered()), this,
             SLOT(clipboardLowOutput()));
     connect(clipboardChangeAction, SIGNAL(triggered()), this,
             SLOT(clipboardChange()));
 
     ui->labelCoinControlQuantity->addAction(clipboardQuantityAction);
     ui->labelCoinControlAmount->addAction(clipboardAmountAction);
     ui->labelCoinControlFee->addAction(clipboardFeeAction);
     ui->labelCoinControlAfterFee->addAction(clipboardAfterFeeAction);
     ui->labelCoinControlBytes->addAction(clipboardBytesAction);
     ui->labelCoinControlLowOutput->addAction(clipboardLowOutputAction);
     ui->labelCoinControlChange->addAction(clipboardChangeAction);
 
     // toggle tree/list mode
     connect(ui->radioTreeMode, SIGNAL(toggled(bool)), this,
             SLOT(radioTreeMode(bool)));
     connect(ui->radioListMode, SIGNAL(toggled(bool)), this,
             SLOT(radioListMode(bool)));
 
     // click on checkbox
     connect(ui->treeWidget, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this,
             SLOT(viewItemChanged(QTreeWidgetItem *, int)));
 
 // click on header
 #if QT_VERSION < 0x050000
     ui->treeWidget->header()->setClickable(true);
 #else
     ui->treeWidget->header()->setSectionsClickable(true);
 #endif
     connect(ui->treeWidget->header(), SIGNAL(sectionClicked(int)), this,
             SLOT(headerSectionClicked(int)));
 
     // ok button
     connect(ui->buttonBox, SIGNAL(clicked(QAbstractButton *)), this,
             SLOT(buttonBoxClicked(QAbstractButton *)));
 
     // (un)select all
     connect(ui->pushButtonSelectAll, SIGNAL(clicked()), this,
             SLOT(buttonSelectAllClicked()));
 
     // change coin control first column label due Qt4 bug.
     // see https://github.com/bitcoin/bitcoin/issues/5716
     ui->treeWidget->headerItem()->setText(COLUMN_CHECKBOX, QString());
 
     ui->treeWidget->setColumnWidth(COLUMN_CHECKBOX, 84);
     ui->treeWidget->setColumnWidth(COLUMN_AMOUNT, 110);
     ui->treeWidget->setColumnWidth(COLUMN_LABEL, 190);
     ui->treeWidget->setColumnWidth(COLUMN_ADDRESS, 320);
     ui->treeWidget->setColumnWidth(COLUMN_DATE, 130);
     ui->treeWidget->setColumnWidth(COLUMN_CONFIRMATIONS, 110);
     // store transaction hash in this column, but don't show it
     ui->treeWidget->setColumnHidden(COLUMN_TXHASH, true);
     // store vout index in this column, but don't show it
     ui->treeWidget->setColumnHidden(COLUMN_VOUT_INDEX, true);
 
     // default view is sorted by amount desc
     sortView(COLUMN_AMOUNT, Qt::DescendingOrder);
 
     // restore list mode and sortorder as a convenience feature
     QSettings settings;
     if (settings.contains("nCoinControlMode") &&
         !settings.value("nCoinControlMode").toBool())
         ui->radioTreeMode->click();
     if (settings.contains("nCoinControlSortColumn") &&
         settings.contains("nCoinControlSortOrder"))
         sortView(
             settings.value("nCoinControlSortColumn").toInt(),
             ((Qt::SortOrder)settings.value("nCoinControlSortOrder").toInt()));
 }
 
 CoinControlDialog::~CoinControlDialog() {
     QSettings settings;
     settings.setValue("nCoinControlMode", ui->radioListMode->isChecked());
     settings.setValue("nCoinControlSortColumn", sortColumn);
     settings.setValue("nCoinControlSortOrder", (int)sortOrder);
 
     delete ui;
 }
 
 void CoinControlDialog::setModel(WalletModel *_model) {
     this->model = _model;
 
     if (_model && _model->getOptionsModel() && _model->getAddressTableModel()) {
         updateView();
         updateLabelLocked();
         CoinControlDialog::updateLabels(_model, this);
     }
 }
 
 // ok button
 void CoinControlDialog::buttonBoxClicked(QAbstractButton *button) {
     if (ui->buttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole) {
         // closes the dialog
         done(QDialog::Accepted);
     }
 }
 
 // (un)select all
 void CoinControlDialog::buttonSelectAllClicked() {
     Qt::CheckState state = Qt::Checked;
     for (int i = 0; i < ui->treeWidget->topLevelItemCount(); i++) {
         if (ui->treeWidget->topLevelItem(i)->checkState(COLUMN_CHECKBOX) !=
             Qt::Unchecked) {
             state = Qt::Unchecked;
             break;
         }
     }
     ui->treeWidget->setEnabled(false);
     for (int i = 0; i < ui->treeWidget->topLevelItemCount(); i++)
         if (ui->treeWidget->topLevelItem(i)->checkState(COLUMN_CHECKBOX) !=
             state)
             ui->treeWidget->topLevelItem(i)->setCheckState(COLUMN_CHECKBOX,
                                                            state);
     ui->treeWidget->setEnabled(true);
     if (state == Qt::Unchecked) {
         // just to be sure
         coinControl->UnSelectAll();
     }
     CoinControlDialog::updateLabels(model, this);
 }
 
 // context menu
 void CoinControlDialog::showMenu(const QPoint &point) {
     QTreeWidgetItem *item = ui->treeWidget->itemAt(point);
     if (item) {
         contextMenuItem = item;
 
         // disable some items (like Copy Transaction ID, lock, unlock) for tree
         // roots in context menu
         if (item->text(COLUMN_TXHASH).length() == 64) {
             // transaction hash is 64 characters (this means its a child node,
             // so its not a parent node in tree mode)
             copyTransactionHashAction->setEnabled(true);
             if (model->isLockedCoin(
                     uint256S(item->text(COLUMN_TXHASH).toStdString()),
                     item->text(COLUMN_VOUT_INDEX).toUInt())) {
                 lockAction->setEnabled(false);
                 unlockAction->setEnabled(true);
             } else {
                 lockAction->setEnabled(true);
                 unlockAction->setEnabled(false);
             }
         } else {
             // this means click on parent node in tree mode -> disable all
             copyTransactionHashAction->setEnabled(false);
             lockAction->setEnabled(false);
             unlockAction->setEnabled(false);
         }
 
         // show context menu
         contextMenu->exec(QCursor::pos());
     }
 }
 
 // context menu action: copy amount
 void CoinControlDialog::copyAmount() {
     GUIUtil::setClipboard(
         BitcoinUnits::removeSpaces(contextMenuItem->text(COLUMN_AMOUNT)));
 }
 
 // context menu action: copy label
 void CoinControlDialog::copyLabel() {
     if (ui->radioTreeMode->isChecked() &&
         contextMenuItem->text(COLUMN_LABEL).length() == 0 &&
         contextMenuItem->parent())
         GUIUtil::setClipboard(contextMenuItem->parent()->text(COLUMN_LABEL));
     else
         GUIUtil::setClipboard(contextMenuItem->text(COLUMN_LABEL));
 }
 
 // context menu action: copy address
 void CoinControlDialog::copyAddress() {
     if (ui->radioTreeMode->isChecked() &&
         contextMenuItem->text(COLUMN_ADDRESS).length() == 0 &&
         contextMenuItem->parent())
         GUIUtil::setClipboard(contextMenuItem->parent()->text(COLUMN_ADDRESS));
     else
         GUIUtil::setClipboard(contextMenuItem->text(COLUMN_ADDRESS));
 }
 
 // context menu action: copy transaction id
 void CoinControlDialog::copyTransactionHash() {
     GUIUtil::setClipboard(contextMenuItem->text(COLUMN_TXHASH));
 }
 
 // context menu action: lock coin
 void CoinControlDialog::lockCoin() {
     if (contextMenuItem->checkState(COLUMN_CHECKBOX) == Qt::Checked)
         contextMenuItem->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
 
     COutPoint outpt(
         uint256S(contextMenuItem->text(COLUMN_TXHASH).toStdString()),
         contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt());
     model->lockCoin(outpt);
     contextMenuItem->setDisabled(true);
     contextMenuItem->setIcon(
         COLUMN_CHECKBOX, platformStyle->SingleColorIcon(":/icons/lock_closed"));
     updateLabelLocked();
 }
 
 // context menu action: unlock coin
 void CoinControlDialog::unlockCoin() {
     COutPoint outpt(
         uint256S(contextMenuItem->text(COLUMN_TXHASH).toStdString()),
         contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt());
     model->unlockCoin(outpt);
     contextMenuItem->setDisabled(false);
     contextMenuItem->setIcon(COLUMN_CHECKBOX, QIcon());
     updateLabelLocked();
 }
 
 // copy label "Quantity" to clipboard
 void CoinControlDialog::clipboardQuantity() {
     GUIUtil::setClipboard(ui->labelCoinControlQuantity->text());
 }
 
 // copy label "Amount" to clipboard
 void CoinControlDialog::clipboardAmount() {
     GUIUtil::setClipboard(ui->labelCoinControlAmount->text().left(
         ui->labelCoinControlAmount->text().indexOf(" ")));
 }
 
 // copy label "Fee" to clipboard
 void CoinControlDialog::clipboardFee() {
     GUIUtil::setClipboard(
         ui->labelCoinControlFee->text()
             .left(ui->labelCoinControlFee->text().indexOf(" "))
             .replace(ASYMP_UTF8, ""));
 }
 
 // copy label "After fee" to clipboard
 void CoinControlDialog::clipboardAfterFee() {
     GUIUtil::setClipboard(
         ui->labelCoinControlAfterFee->text()
             .left(ui->labelCoinControlAfterFee->text().indexOf(" "))
             .replace(ASYMP_UTF8, ""));
 }
 
 // copy label "Bytes" to clipboard
 void CoinControlDialog::clipboardBytes() {
     GUIUtil::setClipboard(
         ui->labelCoinControlBytes->text().replace(ASYMP_UTF8, ""));
 }
 
 // copy label "Dust" to clipboard
 void CoinControlDialog::clipboardLowOutput() {
     GUIUtil::setClipboard(ui->labelCoinControlLowOutput->text());
 }
 
 // copy label "Change" to clipboard
 void CoinControlDialog::clipboardChange() {
     GUIUtil::setClipboard(
         ui->labelCoinControlChange->text()
             .left(ui->labelCoinControlChange->text().indexOf(" "))
             .replace(ASYMP_UTF8, ""));
 }
 
 // treeview: sort
 void CoinControlDialog::sortView(int column, Qt::SortOrder order) {
     sortColumn = column;
     sortOrder = order;
     ui->treeWidget->sortItems(column, order);
     ui->treeWidget->header()->setSortIndicator(sortColumn, sortOrder);
 }
 
 // treeview: clicked on header
 void CoinControlDialog::headerSectionClicked(int logicalIndex) {
     // click on most left column -> do nothing
     if (logicalIndex == COLUMN_CHECKBOX) {
         ui->treeWidget->header()->setSortIndicator(sortColumn, sortOrder);
     } else {
         if (sortColumn == logicalIndex)
             sortOrder =
                 ((sortOrder == Qt::AscendingOrder) ? Qt::DescendingOrder
                                                    : Qt::AscendingOrder);
         else {
             sortColumn = logicalIndex;
             // if label or address then default => asc, else default => desc
             sortOrder =
                 ((sortColumn == COLUMN_LABEL || sortColumn == COLUMN_ADDRESS)
                      ? Qt::AscendingOrder
                      : Qt::DescendingOrder);
         }
 
         sortView(sortColumn, sortOrder);
     }
 }
 
 // toggle tree mode
 void CoinControlDialog::radioTreeMode(bool checked) {
     if (checked && model) updateView();
 }
 
 // toggle list mode
 void CoinControlDialog::radioListMode(bool checked) {
     if (checked && model) updateView();
 }
 
 // checkbox clicked by user
 void CoinControlDialog::viewItemChanged(QTreeWidgetItem *item, int column) {
     // transaction hash is 64 characters (this means its a child node, so its
     // not a parent node in tree mode)
     if (column == COLUMN_CHECKBOX && item->text(COLUMN_TXHASH).length() == 64) {
         COutPoint outpt(uint256S(item->text(COLUMN_TXHASH).toStdString()),
                         item->text(COLUMN_VOUT_INDEX).toUInt());
 
         if (item->checkState(COLUMN_CHECKBOX) == Qt::Unchecked) {
             coinControl->UnSelect(outpt);
         } else if (item->isDisabled()) {
             // locked (this happens if "check all" through parent node)
             item->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
         } else {
             coinControl->Select(outpt);
         }
 
         // selection changed -> update labels
         if (ui->treeWidget->isEnabled()) {
             // do not update on every click for (un)select all
             CoinControlDialog::updateLabels(model, this);
         }
     }
 
 // TODO: Remove this temporary qt5 fix after Qt5.3 and Qt5.4 are no longer used.
 //       Fixed in Qt5.5 and above: https://bugreports.qt.io/browse/QTBUG-43473
 #if QT_VERSION >= 0x050000
     else if (column == COLUMN_CHECKBOX && item->childCount() > 0) {
         if (item->checkState(COLUMN_CHECKBOX) == Qt::PartiallyChecked &&
             item->child(0)->checkState(COLUMN_CHECKBOX) == Qt::PartiallyChecked)
             item->setCheckState(COLUMN_CHECKBOX, Qt::Checked);
     }
 #endif
 }
 
 // shows count of locked unspent outputs
 void CoinControlDialog::updateLabelLocked() {
     std::vector<COutPoint> vOutpts;
     model->listLockedCoins(vOutpts);
     if (vOutpts.size() > 0) {
         ui->labelLocked->setText(tr("(%1 locked)").arg(vOutpts.size()));
         ui->labelLocked->setVisible(true);
     } else
         ui->labelLocked->setVisible(false);
 }
 
 void CoinControlDialog::updateLabels(WalletModel *model, QDialog *dialog) {
     if (!model) return;
 
     // nPayAmount
     CAmount nPayAmount = 0;
     bool fDust = false;
     CMutableTransaction txDummy;
     for (const CAmount &amount : CoinControlDialog::payAmounts) {
         nPayAmount += amount;
 
         if (amount > 0) {
-            CTxOut txout(amount, (CScript)std::vector<unsigned char>(24, 0));
+            CTxOut txout(amount, (CScript)std::vector<uint8_t>(24, 0));
             txDummy.vout.push_back(txout);
             if (txout.IsDust(dustRelayFee)) fDust = true;
         }
     }
 
     CAmount nAmount = 0;
     CAmount nPayFee = 0;
     CAmount nAfterFee = 0;
     CAmount nChange = 0;
     unsigned int nBytes = 0;
     unsigned int nBytesInputs = 0;
     double dPriority = 0;
     double dPriorityInputs = 0;
     unsigned int nQuantity = 0;
     int nQuantityUncompressed = 0;
     bool fAllowFree = false;
 
     std::vector<COutPoint> vCoinControl;
     std::vector<COutput> vOutputs;
     coinControl->ListSelected(vCoinControl);
     model->getOutputs(vCoinControl, vOutputs);
 
     for (const COutput &out : vOutputs) {
         // unselect already spent, very unlikely scenario, this could happen
         // when selected are spent elsewhere, like rpc or another computer
         uint256 txhash = out.tx->GetId();
         COutPoint outpt(txhash, out.i);
         if (model->isSpent(outpt)) {
             coinControl->UnSelect(outpt);
             continue;
         }
 
         // Quantity
         nQuantity++;
 
         // Amount
         nAmount += out.tx->tx->vout[out.i].nValue;
 
         // Priority
         dPriorityInputs +=
             (double)out.tx->tx->vout[out.i].nValue * (out.nDepth + 1);
 
         // Bytes
         CTxDestination address;
         if (ExtractDestination(out.tx->tx->vout[out.i].scriptPubKey, address)) {
             CPubKey pubkey;
             CKeyID *keyid = boost::get<CKeyID>(&address);
             if (keyid && model->getPubKey(*keyid, pubkey)) {
                 nBytesInputs += (pubkey.IsCompressed() ? 148 : 180);
                 if (!pubkey.IsCompressed()) nQuantityUncompressed++;
             } else {
                 // in all error cases, simply assume 148 here
                 nBytesInputs += 148;
             }
         } else
             nBytesInputs += 148;
     }
 
     // calculation
     if (nQuantity > 0) {
         // Bytes
         // always assume +1 output for change here
         nBytes = nBytesInputs + ((CoinControlDialog::payAmounts.size() > 0
                                       ? CoinControlDialog::payAmounts.size() + 1
                                       : 2) *
                                  34) +
                  10;
 
         // in the subtract fee from amount case, we can tell if zero change
         // already and subtract the bytes, so that fee calculation afterwards is
         // accurate
         if (CoinControlDialog::fSubtractFeeFromAmount)
             if (nAmount - nPayAmount == 0) nBytes -= 34;
 
         // Fee
         nPayFee = CWallet::GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
         if (nPayFee > 0 && coinControl->nMinimumTotalFee > nPayFee)
             nPayFee = coinControl->nMinimumTotalFee;
 
         // Allow free? (require at least hard-coded threshold and default to
         // that if no estimate)
         double mempoolEstimatePriority =
             mempool.estimateSmartPriority(nTxConfirmTarget);
         // 29 = 180 - 151 (uncompressed public keys are over the limit. max 151
         // bytes of the input are ignored for priority)
         dPriority = dPriorityInputs /
                     (nBytes - nBytesInputs + (nQuantityUncompressed * 29));
         double dPriorityNeeded =
             std::max(mempoolEstimatePriority, AllowFreeThreshold());
         fAllowFree = (dPriority >= dPriorityNeeded);
 
         if (fSendFreeTransactions)
             if (fAllowFree && nBytes <= MAX_FREE_TRANSACTION_CREATE_SIZE)
                 nPayFee = 0;
 
         if (nPayAmount > 0) {
             nChange = nAmount - nPayAmount;
             if (!CoinControlDialog::fSubtractFeeFromAmount) nChange -= nPayFee;
 
             // Never create dust outputs; if we would, just add the dust to the
             // fee.
             if (nChange > 0 && nChange < MIN_CHANGE) {
-                CTxOut txout(nChange,
-                             (CScript)std::vector<unsigned char>(24, 0));
+                CTxOut txout(nChange, (CScript)std::vector<uint8_t>(24, 0));
                 if (txout.IsDust(dustRelayFee)) {
                     // dust-change will be raised until no dust
                     if (CoinControlDialog::fSubtractFeeFromAmount) {
                         nChange = txout.GetDustThreshold(dustRelayFee);
                     } else {
                         nPayFee += nChange;
                         nChange = 0;
                     }
                 }
             }
 
             if (nChange == 0 && !CoinControlDialog::fSubtractFeeFromAmount) {
                 nBytes -= 34;
             }
         }
 
         // after fee
         nAfterFee = std::max<CAmount>(nAmount - nPayFee, 0);
     }
 
     // actually update labels
     int nDisplayUnit = BitcoinUnits::BCC;
     if (model && model->getOptionsModel()) {
         nDisplayUnit = model->getOptionsModel()->getDisplayUnit();
     }
 
     QLabel *l1 = dialog->findChild<QLabel *>("labelCoinControlQuantity");
     QLabel *l2 = dialog->findChild<QLabel *>("labelCoinControlAmount");
     QLabel *l3 = dialog->findChild<QLabel *>("labelCoinControlFee");
     QLabel *l4 = dialog->findChild<QLabel *>("labelCoinControlAfterFee");
     QLabel *l5 = dialog->findChild<QLabel *>("labelCoinControlBytes");
     QLabel *l7 = dialog->findChild<QLabel *>("labelCoinControlLowOutput");
     QLabel *l8 = dialog->findChild<QLabel *>("labelCoinControlChange");
 
     // enable/disable "dust" and "change"
     dialog->findChild<QLabel *>("labelCoinControlLowOutputText")
         ->setEnabled(nPayAmount > 0);
     dialog->findChild<QLabel *>("labelCoinControlLowOutput")
         ->setEnabled(nPayAmount > 0);
     dialog->findChild<QLabel *>("labelCoinControlChangeText")
         ->setEnabled(nPayAmount > 0);
     dialog->findChild<QLabel *>("labelCoinControlChange")
         ->setEnabled(nPayAmount > 0);
 
     // stats
     // Quantity
     l1->setText(QString::number(nQuantity));
     // Amount
     l2->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nAmount));
     // Fee
     l3->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nPayFee));
     // After Fee
     l4->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nAfterFee));
     // Bytes
     l5->setText(((nBytes > 0) ? ASYMP_UTF8 : "") + QString::number(nBytes));
     // Dust
     l7->setText(fDust ? tr("yes") : tr("no"));
     // Change
     l8->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nChange));
     if (nPayFee > 0 && (coinControl->nMinimumTotalFee < nPayFee)) {
         l3->setText(ASYMP_UTF8 + l3->text());
         l4->setText(ASYMP_UTF8 + l4->text());
         if (nChange > 0 && !CoinControlDialog::fSubtractFeeFromAmount) {
             l8->setText(ASYMP_UTF8 + l8->text());
         }
     }
 
     // turn label red when dust
     l7->setStyleSheet((fDust) ? "color:red;" : "");
 
     // tool tips
     QString toolTipDust =
         tr("This label turns red if any recipient receives an amount smaller "
            "than the current dust threshold.");
 
     // how many satoshis the estimated fee can vary per byte we guess wrong
     double dFeeVary;
     if (payTxFee.GetFeePerK() > 0) {
         dFeeVary = (double)std::max(CWallet::GetRequiredFee(1000),
                                     payTxFee.GetFeePerK()) /
                    1000;
     } else {
         dFeeVary =
             (double)std::max(
                 CWallet::GetRequiredFee(1000),
                 mempool.estimateSmartFee(nTxConfirmTarget).GetFeePerK()) /
             1000;
     }
     QString toolTip4 =
         tr("Can vary +/- %1 satoshi(s) per input.").arg(dFeeVary);
 
     l3->setToolTip(toolTip4);
     l4->setToolTip(toolTip4);
     l7->setToolTip(toolTipDust);
     l8->setToolTip(toolTip4);
     dialog->findChild<QLabel *>("labelCoinControlFeeText")
         ->setToolTip(l3->toolTip());
     dialog->findChild<QLabel *>("labelCoinControlAfterFeeText")
         ->setToolTip(l4->toolTip());
     dialog->findChild<QLabel *>("labelCoinControlBytesText")
         ->setToolTip(l5->toolTip());
     dialog->findChild<QLabel *>("labelCoinControlLowOutputText")
         ->setToolTip(l7->toolTip());
     dialog->findChild<QLabel *>("labelCoinControlChangeText")
         ->setToolTip(l8->toolTip());
 
     // Insufficient funds
     QLabel *label = dialog->findChild<QLabel *>("labelCoinControlInsuffFunds");
     if (label) {
         label->setVisible(nChange < 0);
     }
 }
 
 void CoinControlDialog::updateView() {
     if (!model || !model->getOptionsModel() || !model->getAddressTableModel()) {
         return;
     }
 
     bool treeMode = ui->radioTreeMode->isChecked();
 
     ui->treeWidget->clear();
     // performance, otherwise updateLabels would be called for every checked
     // checkbox
     ui->treeWidget->setEnabled(false);
     ui->treeWidget->setAlternatingRowColors(!treeMode);
     QFlags<Qt::ItemFlag> flgCheckbox =
         Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
     QFlags<Qt::ItemFlag> flgTristate =
         Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable |
         Qt::ItemIsTristate;
 
     int nDisplayUnit = model->getOptionsModel()->getDisplayUnit();
 
     std::map<QString, std::vector<COutput>> mapCoins;
     model->listCoins(mapCoins);
 
     for (const std::pair<QString, std::vector<COutput>> &coins : mapCoins) {
         CCoinControlWidgetItem *itemWalletAddress =
             new CCoinControlWidgetItem();
         itemWalletAddress->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
         QString sWalletAddress = coins.first;
         QString sWalletLabel =
             model->getAddressTableModel()->labelForAddress(sWalletAddress);
         if (sWalletLabel.isEmpty()) {
             sWalletLabel = tr("(no label)");
         }
 
         if (treeMode) {
             // wallet address
             ui->treeWidget->addTopLevelItem(itemWalletAddress);
 
             itemWalletAddress->setFlags(flgTristate);
             itemWalletAddress->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
 
             // label
             itemWalletAddress->setText(COLUMN_LABEL, sWalletLabel);
 
             // address
             itemWalletAddress->setText(COLUMN_ADDRESS, sWalletAddress);
         }
 
         CAmount nSum = 0;
         int nChildren = 0;
         for (const COutput &out : coins.second) {
             nSum += out.tx->tx->vout[out.i].nValue;
             nChildren++;
 
             CCoinControlWidgetItem *itemOutput;
             if (treeMode) {
                 itemOutput = new CCoinControlWidgetItem(itemWalletAddress);
             } else {
                 itemOutput = new CCoinControlWidgetItem(ui->treeWidget);
             }
             itemOutput->setFlags(flgCheckbox);
             itemOutput->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
 
             // address
             CTxDestination outputAddress;
             QString sAddress = "";
             if (ExtractDestination(out.tx->tx->vout[out.i].scriptPubKey,
                                    outputAddress)) {
                 sAddress = QString::fromStdString(
                     CBitcoinAddress(outputAddress).ToString());
 
                 // if listMode or change => show bitcoin address. In tree mode,
                 // address is not shown again for direct wallet address outputs
                 if (!treeMode || (!(sAddress == sWalletAddress))) {
                     itemOutput->setText(COLUMN_ADDRESS, sAddress);
                 }
             }
 
             // label
             if (!(sAddress == sWalletAddress)) {
                 // change tooltip from where the change comes from
                 itemOutput->setToolTip(COLUMN_LABEL, tr("change from %1 (%2)")
                                                          .arg(sWalletLabel)
                                                          .arg(sWalletAddress));
                 itemOutput->setText(COLUMN_LABEL, tr("(change)"));
             } else if (!treeMode) {
                 QString sLabel =
                     model->getAddressTableModel()->labelForAddress(sAddress);
                 if (sLabel.isEmpty()) {
                     sLabel = tr("(no label)");
                 }
                 itemOutput->setText(COLUMN_LABEL, sLabel);
             }
 
             // amount
             itemOutput->setText(
                 COLUMN_AMOUNT,
                 BitcoinUnits::format(nDisplayUnit,
                                      out.tx->tx->vout[out.i].nValue));
             // padding so that sorting works correctly
             itemOutput->setData(
                 COLUMN_AMOUNT, Qt::UserRole,
                 QVariant((qlonglong)out.tx->tx->vout[out.i].nValue));
 
             // date
             itemOutput->setText(COLUMN_DATE,
                                 GUIUtil::dateTimeStr(out.tx->GetTxTime()));
             itemOutput->setData(COLUMN_DATE, Qt::UserRole,
                                 QVariant((qlonglong)out.tx->GetTxTime()));
 
             // confirmations
             itemOutput->setText(COLUMN_CONFIRMATIONS,
                                 QString::number(out.nDepth));
             itemOutput->setData(COLUMN_CONFIRMATIONS, Qt::UserRole,
                                 QVariant((qlonglong)out.nDepth));
 
             // transaction hash
             uint256 txhash = out.tx->GetId();
             itemOutput->setText(COLUMN_TXHASH,
                                 QString::fromStdString(txhash.GetHex()));
 
             // vout index
             itemOutput->setText(COLUMN_VOUT_INDEX, QString::number(out.i));
 
             // disable locked coins
             if (model->isLockedCoin(txhash, out.i)) {
                 COutPoint outpt(txhash, out.i);
                 // just to be sure
                 coinControl->UnSelect(outpt);
                 itemOutput->setDisabled(true);
                 itemOutput->setIcon(
                     COLUMN_CHECKBOX,
                     platformStyle->SingleColorIcon(":/icons/lock_closed"));
             }
 
             // set checkbox
             if (coinControl->IsSelected(COutPoint(txhash, out.i))) {
                 itemOutput->setCheckState(COLUMN_CHECKBOX, Qt::Checked);
             }
         }
 
         // amount
         if (treeMode) {
             itemWalletAddress->setText(COLUMN_CHECKBOX,
                                        "(" + QString::number(nChildren) + ")");
             itemWalletAddress->setText(
                 COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, nSum));
             itemWalletAddress->setData(COLUMN_AMOUNT, Qt::UserRole,
                                        QVariant((qlonglong)nSum));
         }
     }
 
     // expand all partially selected
     if (treeMode) {
         for (int i = 0; i < ui->treeWidget->topLevelItemCount(); i++)
             if (ui->treeWidget->topLevelItem(i)->checkState(COLUMN_CHECKBOX) ==
                 Qt::PartiallyChecked)
                 ui->treeWidget->topLevelItem(i)->setExpanded(true);
     }
 
     // sort view
     sortView(sortColumn, sortOrder);
     ui->treeWidget->setEnabled(true);
 }
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index d08bfd9dd..b37a13e39 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -1,986 +1,986 @@
 // Copyright (c) 2011-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.
 
 #include "guiutil.h"
 
 #include "bitcoinaddressvalidator.h"
 #include "bitcoinunits.h"
 #include "qvalidatedlineedit.h"
 #include "walletmodel.h"
 
 #include "init.h"
 #include "policy/policy.h"
 #include "primitives/transaction.h"
 #include "protocol.h"
 #include "script/script.h"
 #include "script/standard.h"
 #include "util.h"
 
 #ifdef WIN32
 #ifdef _WIN32_WINNT
 #undef _WIN32_WINNT
 #endif
 #define _WIN32_WINNT 0x0501
 #ifdef _WIN32_IE
 #undef _WIN32_IE
 #endif
 #define _WIN32_IE 0x0501
 #define WIN32_LEAN_AND_MEAN 1
 #ifndef NOMINMAX
 #define NOMINMAX
 #endif
 #include "shellapi.h"
 #include "shlobj.h"
 #include "shlwapi.h"
 #endif
 
 #include <boost/filesystem.hpp>
 #include <boost/filesystem/fstream.hpp>
 #if BOOST_FILESYSTEM_VERSION >= 3
 #include <boost/filesystem/detail/utf8_codecvt_facet.hpp>
 #endif
 #include <boost/scoped_array.hpp>
 
 #include <QAbstractItemView>
 #include <QApplication>
 #include <QClipboard>
 #include <QDateTime>
 #include <QDesktopServices>
 #include <QDesktopWidget>
 #include <QDoubleValidator>
 #include <QFileDialog>
 #include <QFont>
 #include <QLineEdit>
 #include <QMouseEvent>
 #include <QSettings>
 #include <QTextDocument> // for Qt::mightBeRichText
 #include <QThread>
 
 #if QT_VERSION < 0x050000
 #include <QUrl>
 #else
 #include <QUrlQuery>
 #endif
 
 #if QT_VERSION >= 0x50200
 #include <QFontDatabase>
 #endif
 
 #if BOOST_FILESYSTEM_VERSION >= 3
 static boost::filesystem::detail::utf8_codecvt_facet utf8;
 #endif
 
 #if defined(Q_OS_MAC)
 extern double NSAppKitVersionNumber;
 #if !defined(NSAppKitVersionNumber10_8)
 #define NSAppKitVersionNumber10_8 1187
 #endif
 #if !defined(NSAppKitVersionNumber10_9)
 #define NSAppKitVersionNumber10_9 1265
 #endif
 #endif
 
 namespace GUIUtil {
 
 QString dateTimeStr(const QDateTime &date) {
     return date.date().toString(Qt::SystemLocaleShortDate) + QString(" ") +
            date.toString("hh:mm");
 }
 
 QString dateTimeStr(qint64 nTime) {
     return dateTimeStr(QDateTime::fromTime_t((qint32)nTime));
 }
 
 QFont fixedPitchFont() {
 #if QT_VERSION >= 0x50200
     return QFontDatabase::systemFont(QFontDatabase::FixedFont);
 #else
     QFont font("Monospace");
 #if QT_VERSION >= 0x040800
     font.setStyleHint(QFont::Monospace);
 #else
     font.setStyleHint(QFont::TypeWriter);
 #endif
     return font;
 #endif
 }
 
 // Just some dummy data to generate an convincing random-looking (but
 // consistent) address
 static const uint8_t dummydata[] = {
     0xeb, 0x15, 0x23, 0x1d, 0xfc, 0xeb, 0x60, 0x92, 0x58, 0x86, 0xb6, 0x7d,
     0x06, 0x52, 0x99, 0x92, 0x59, 0x15, 0xae, 0xb1, 0x72, 0xc0, 0x66, 0x47};
 
 // Generate a dummy address with invalid CRC, starting with the network prefix.
 static std::string DummyAddress(const CChainParams &params) {
-    std::vector<unsigned char> sourcedata =
+    std::vector<uint8_t> sourcedata =
         params.Base58Prefix(CChainParams::PUBKEY_ADDRESS);
     sourcedata.insert(sourcedata.end(), dummydata,
                       dummydata + sizeof(dummydata));
     for (int i = 0; i < 256; ++i) { // Try every trailing byte
         std::string s = EncodeBase58(sourcedata.data(),
                                      sourcedata.data() + sourcedata.size());
         if (!CBitcoinAddress(s).IsValid()) return s;
         sourcedata[sourcedata.size() - 1] += 1;
     }
     return "";
 }
 
 void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent) {
     parent->setFocusProxy(widget);
 
     widget->setFont(fixedPitchFont());
 #if QT_VERSION >= 0x040700
     // We don't want translators to use own addresses in translations
     // and this is the only place, where this address is supplied.
     widget->setPlaceholderText(
         QObject::tr("Enter a Bitcoin address (e.g. %1)")
             .arg(QString::fromStdString(DummyAddress(Params()))));
 #endif
     widget->setValidator(new BitcoinAddressEntryValidator(parent));
     widget->setCheckValidator(new BitcoinAddressCheckValidator(parent));
 }
 
 void setupAmountWidget(QLineEdit *widget, QWidget *parent) {
     QDoubleValidator *amountValidator = new QDoubleValidator(parent);
     amountValidator->setDecimals(8);
     amountValidator->setBottom(0.0);
     widget->setValidator(amountValidator);
     widget->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
 }
 
 bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out) {
     // return if URI is not valid or is no bitcoin: URI
     if (!uri.isValid() || uri.scheme() != QString("bitcoin")) return false;
 
     SendCoinsRecipient rv;
     rv.address = uri.path();
     // Trim any following forward slash which may have been added by the OS
     if (rv.address.endsWith("/")) {
         rv.address.truncate(rv.address.length() - 1);
     }
     rv.amount = 0;
 
 #if QT_VERSION < 0x050000
     QList<QPair<QString, QString>> items = uri.queryItems();
 #else
     QUrlQuery uriQuery(uri);
     QList<QPair<QString, QString>> items = uriQuery.queryItems();
 #endif
     for (QList<QPair<QString, QString>>::iterator i = items.begin();
          i != items.end(); i++) {
         bool fShouldReturnFalse = false;
         if (i->first.startsWith("req-")) {
             i->first.remove(0, 4);
             fShouldReturnFalse = true;
         }
 
         if (i->first == "label") {
             rv.label = i->second;
             fShouldReturnFalse = false;
         }
         if (i->first == "message") {
             rv.message = i->second;
             fShouldReturnFalse = false;
         } else if (i->first == "amount") {
             if (!i->second.isEmpty()) {
                 if (!BitcoinUnits::parse(BitcoinUnits::BCC, i->second,
                                          &rv.amount)) {
                     return false;
                 }
             }
             fShouldReturnFalse = false;
         }
 
         if (fShouldReturnFalse) {
             return false;
         }
     }
     if (out) {
         *out = rv;
     }
     return true;
 }
 
 bool parseBitcoinURI(QString uri, SendCoinsRecipient *out) {
     // Convert bitcoin:// to bitcoin:
     //
     //    Cannot handle this later, because bitcoin://
     //    will cause Qt to see the part after // as host,
     //    which will lower-case it (and thus invalidate the address).
     if (uri.startsWith("bitcoin://", Qt::CaseInsensitive)) {
         uri.replace(0, 10, "bitcoin:");
     }
     QUrl uriInstance(uri);
     return parseBitcoinURI(uriInstance, out);
 }
 
 QString formatBitcoinURI(const SendCoinsRecipient &info) {
     QString ret = QString("bitcoin:%1").arg(info.address);
     int paramCount = 0;
 
     if (info.amount) {
         ret +=
             QString("?amount=%1")
                 .arg(BitcoinUnits::format(BitcoinUnits::BCC, info.amount, false,
                                           BitcoinUnits::separatorNever));
         paramCount++;
     }
 
     if (!info.label.isEmpty()) {
         QString lbl(QUrl::toPercentEncoding(info.label));
         ret += QString("%1label=%2").arg(paramCount == 0 ? "?" : "&").arg(lbl);
         paramCount++;
     }
 
     if (!info.message.isEmpty()) {
         QString msg(QUrl::toPercentEncoding(info.message));
         ret +=
             QString("%1message=%2").arg(paramCount == 0 ? "?" : "&").arg(msg);
         paramCount++;
     }
 
     return ret;
 }
 
 bool isDust(const QString &address, const CAmount &amount) {
     CTxDestination dest = CBitcoinAddress(address.toStdString()).Get();
     CScript script = GetScriptForDestination(dest);
     CTxOut txOut(amount, script);
     return txOut.IsDust(dustRelayFee);
 }
 
 QString HtmlEscape(const QString &str, bool fMultiLine) {
 #if QT_VERSION < 0x050000
     QString escaped = Qt::escape(str);
 #else
     QString escaped = str.toHtmlEscaped();
 #endif
     if (fMultiLine) {
         escaped = escaped.replace("\n", "<br>\n");
     }
     return escaped;
 }
 
 QString HtmlEscape(const std::string &str, bool fMultiLine) {
     return HtmlEscape(QString::fromStdString(str), fMultiLine);
 }
 
 void copyEntryData(QAbstractItemView *view, int column, int role) {
     if (!view || !view->selectionModel()) return;
     QModelIndexList selection = view->selectionModel()->selectedRows(column);
 
     if (!selection.isEmpty()) {
         // Copy first item
         setClipboard(selection.at(0).data(role).toString());
     }
 }
 
 QList<QModelIndex> getEntryData(QAbstractItemView *view, int column) {
     if (!view || !view->selectionModel()) return QList<QModelIndex>();
     return view->selectionModel()->selectedRows(column);
 }
 
 QString getSaveFileName(QWidget *parent, const QString &caption,
                         const QString &dir, const QString &filter,
                         QString *selectedSuffixOut) {
     QString selectedFilter;
     QString myDir;
     // Default to user documents location
     if (dir.isEmpty()) {
 #if QT_VERSION < 0x050000
         myDir = QDesktopServices::storageLocation(
             QDesktopServices::DocumentsLocation);
 #else
         myDir =
             QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
 #endif
     } else {
         myDir = dir;
     }
     /* Directly convert path to native OS path separators */
     QString result = QDir::toNativeSeparators(QFileDialog::getSaveFileName(
         parent, caption, myDir, filter, &selectedFilter));
 
     /* Extract first suffix from filter pattern "Description (*.foo)" or
      * "Description (*.foo *.bar ...) */
     QRegExp filter_re(".* \\(\\*\\.(.*)[ \\)]");
     QString selectedSuffix;
     if (filter_re.exactMatch(selectedFilter)) {
         selectedSuffix = filter_re.cap(1);
     }
 
     /* Add suffix if needed */
     QFileInfo info(result);
     if (!result.isEmpty()) {
         if (info.suffix().isEmpty() && !selectedSuffix.isEmpty()) {
             /* No suffix specified, add selected suffix */
             if (!result.endsWith(".")) result.append(".");
             result.append(selectedSuffix);
         }
     }
 
     /* Return selected suffix if asked to */
     if (selectedSuffixOut) {
         *selectedSuffixOut = selectedSuffix;
     }
     return result;
 }
 
 QString getOpenFileName(QWidget *parent, const QString &caption,
                         const QString &dir, const QString &filter,
                         QString *selectedSuffixOut) {
     QString selectedFilter;
     QString myDir;
     if (dir.isEmpty()) // Default to user documents location
     {
 #if QT_VERSION < 0x050000
         myDir = QDesktopServices::storageLocation(
             QDesktopServices::DocumentsLocation);
 #else
         myDir =
             QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
 #endif
     } else {
         myDir = dir;
     }
     /* Directly convert path to native OS path separators */
     QString result = QDir::toNativeSeparators(QFileDialog::getOpenFileName(
         parent, caption, myDir, filter, &selectedFilter));
 
     if (selectedSuffixOut) {
         /* Extract first suffix from filter pattern "Description (*.foo)" or
          * "Description (*.foo *.bar ...) */
         QRegExp filter_re(".* \\(\\*\\.(.*)[ \\)]");
         QString selectedSuffix;
         if (filter_re.exactMatch(selectedFilter)) {
             selectedSuffix = filter_re.cap(1);
         }
         *selectedSuffixOut = selectedSuffix;
     }
     return result;
 }
 
 Qt::ConnectionType blockingGUIThreadConnection() {
     if (QThread::currentThread() != qApp->thread()) {
         return Qt::BlockingQueuedConnection;
     } else {
         return Qt::DirectConnection;
     }
 }
 
 bool checkPoint(const QPoint &p, const QWidget *w) {
     QWidget *atW = QApplication::widgetAt(w->mapToGlobal(p));
     if (!atW) return false;
     return atW->topLevelWidget() == w;
 }
 
 bool isObscured(QWidget *w) {
     return !(checkPoint(QPoint(0, 0), w) &&
              checkPoint(QPoint(w->width() - 1, 0), w) &&
              checkPoint(QPoint(0, w->height() - 1), w) &&
              checkPoint(QPoint(w->width() - 1, w->height() - 1), w) &&
              checkPoint(QPoint(w->width() / 2, w->height() / 2), w));
 }
 
 void openDebugLogfile() {
     boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
 
     /* Open debug.log with the associated application */
     if (boost::filesystem::exists(pathDebug))
         QDesktopServices::openUrl(
             QUrl::fromLocalFile(boostPathToQString(pathDebug)));
 }
 
 void SubstituteFonts(const QString &language) {
 #if defined(Q_OS_MAC)
 // Background:
 // OSX's default font changed in 10.9 and Qt is unable to find it with its
 // usual fallback methods when building against the 10.7 sdk or lower.
 // The 10.8 SDK added a function to let it find the correct fallback font.
 // If this fallback is not properly loaded, some characters may fail to
 // render correctly.
 //
 // The same thing happened with 10.10. .Helvetica Neue DeskInterface is now
 // default.
 //
 // Solution: If building with the 10.7 SDK or lower and the user's platform
 // is 10.9 or higher at runtime, substitute the correct font. This needs to
 // happen before the QApplication is created.
 #if defined(MAC_OS_X_VERSION_MAX_ALLOWED) &&                                   \
     MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_8
     if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_8) {
         if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_9)
             /* On a 10.9 - 10.9.x system */
             QFont::insertSubstitution(".Lucida Grande UI", "Lucida Grande");
         else {
             /* 10.10 or later system */
             if (language == "zh_CN" || language == "zh_TW" ||
                 language == "zh_HK") // traditional or simplified Chinese
                 QFont::insertSubstitution(".Helvetica Neue DeskInterface",
                                           "Heiti SC");
             else if (language == "ja") // Japanesee
                 QFont::insertSubstitution(".Helvetica Neue DeskInterface",
                                           "Songti SC");
             else
                 QFont::insertSubstitution(".Helvetica Neue DeskInterface",
                                           "Lucida Grande");
         }
     }
 #endif
 #endif
 }
 
 ToolTipToRichTextFilter::ToolTipToRichTextFilter(int _size_threshold,
                                                  QObject *parent)
     : QObject(parent), size_threshold(_size_threshold) {}
 
 bool ToolTipToRichTextFilter::eventFilter(QObject *obj, QEvent *evt) {
     if (evt->type() == QEvent::ToolTipChange) {
         QWidget *widget = static_cast<QWidget *>(obj);
         QString tooltip = widget->toolTip();
         if (tooltip.size() > size_threshold && !tooltip.startsWith("<qt") &&
             !Qt::mightBeRichText(tooltip)) {
             // Envelop with <qt></qt> to make sure Qt detects this as rich text
             // Escape the current message as HTML and replace \n by <br>
             tooltip = "<qt>" + HtmlEscape(tooltip, true) + "</qt>";
             widget->setToolTip(tooltip);
             return true;
         }
     }
     return QObject::eventFilter(obj, evt);
 }
 
 void TableViewLastColumnResizingFixer::connectViewHeadersSignals() {
     connect(tableView->horizontalHeader(),
             SIGNAL(sectionResized(int, int, int)), this,
             SLOT(on_sectionResized(int, int, int)));
     connect(tableView->horizontalHeader(), SIGNAL(geometriesChanged()), this,
             SLOT(on_geometriesChanged()));
 }
 
 // We need to disconnect these while handling the resize events, otherwise we
 // can enter infinite loops.
 void TableViewLastColumnResizingFixer::disconnectViewHeadersSignals() {
     disconnect(tableView->horizontalHeader(),
                SIGNAL(sectionResized(int, int, int)), this,
                SLOT(on_sectionResized(int, int, int)));
     disconnect(tableView->horizontalHeader(), SIGNAL(geometriesChanged()), this,
                SLOT(on_geometriesChanged()));
 }
 
 // Setup the resize mode, handles compatibility for Qt5 and below as the method
 // signatures changed.
 // Refactored here for readability.
 void TableViewLastColumnResizingFixer::setViewHeaderResizeMode(
     int logicalIndex, QHeaderView::ResizeMode resizeMode) {
 #if QT_VERSION < 0x050000
     tableView->horizontalHeader()->setResizeMode(logicalIndex, resizeMode);
 #else
     tableView->horizontalHeader()->setSectionResizeMode(logicalIndex,
                                                         resizeMode);
 #endif
 }
 
 void TableViewLastColumnResizingFixer::resizeColumn(int nColumnIndex,
                                                     int width) {
     tableView->setColumnWidth(nColumnIndex, width);
     tableView->horizontalHeader()->resizeSection(nColumnIndex, width);
 }
 
 int TableViewLastColumnResizingFixer::getColumnsWidth() {
     int nColumnsWidthSum = 0;
     for (int i = 0; i < columnCount; i++) {
         nColumnsWidthSum += tableView->horizontalHeader()->sectionSize(i);
     }
     return nColumnsWidthSum;
 }
 
 int TableViewLastColumnResizingFixer::getAvailableWidthForColumn(int column) {
     int nResult = lastColumnMinimumWidth;
     int nTableWidth = tableView->horizontalHeader()->width();
 
     if (nTableWidth > 0) {
         int nOtherColsWidth =
             getColumnsWidth() -
             tableView->horizontalHeader()->sectionSize(column);
         nResult = std::max(nResult, nTableWidth - nOtherColsWidth);
     }
 
     return nResult;
 }
 
 // Make sure we don't make the columns wider than the table's viewport width.
 void TableViewLastColumnResizingFixer::adjustTableColumnsWidth() {
     disconnectViewHeadersSignals();
     resizeColumn(lastColumnIndex, getAvailableWidthForColumn(lastColumnIndex));
     connectViewHeadersSignals();
 
     int nTableWidth = tableView->horizontalHeader()->width();
     int nColsWidth = getColumnsWidth();
     if (nColsWidth > nTableWidth) {
         resizeColumn(secondToLastColumnIndex,
                      getAvailableWidthForColumn(secondToLastColumnIndex));
     }
 }
 
 // Make column use all the space available, useful during window resizing.
 void TableViewLastColumnResizingFixer::stretchColumnWidth(int column) {
     disconnectViewHeadersSignals();
     resizeColumn(column, getAvailableWidthForColumn(column));
     connectViewHeadersSignals();
 }
 
 // When a section is resized this is a slot-proxy for ajustAmountColumnWidth().
 void TableViewLastColumnResizingFixer::on_sectionResized(int logicalIndex,
                                                          int oldSize,
                                                          int newSize) {
     adjustTableColumnsWidth();
     int remainingWidth = getAvailableWidthForColumn(logicalIndex);
     if (newSize > remainingWidth) {
         resizeColumn(logicalIndex, remainingWidth);
     }
 }
 
 // When the table's geometry is ready, we manually perform the stretch of the
 // "Message" column,
 // as the "Stretch" resize mode does not allow for interactive resizing.
 void TableViewLastColumnResizingFixer::on_geometriesChanged() {
     if ((getColumnsWidth() - this->tableView->horizontalHeader()->width()) !=
         0) {
         disconnectViewHeadersSignals();
         resizeColumn(secondToLastColumnIndex,
                      getAvailableWidthForColumn(secondToLastColumnIndex));
         connectViewHeadersSignals();
     }
 }
 
 /**
  * Initializes all internal variables and prepares the
  * the resize modes of the last 2 columns of the table and
  */
 TableViewLastColumnResizingFixer::TableViewLastColumnResizingFixer(
     QTableView *table, int lastColMinimumWidth, int allColsMinimumWidth,
     QObject *parent)
     : QObject(parent), tableView(table),
       lastColumnMinimumWidth(lastColMinimumWidth),
       allColumnsMinimumWidth(allColsMinimumWidth) {
     columnCount = tableView->horizontalHeader()->count();
     lastColumnIndex = columnCount - 1;
     secondToLastColumnIndex = columnCount - 2;
     tableView->horizontalHeader()->setMinimumSectionSize(
         allColumnsMinimumWidth);
     setViewHeaderResizeMode(secondToLastColumnIndex, QHeaderView::Interactive);
     setViewHeaderResizeMode(lastColumnIndex, QHeaderView::Interactive);
 }
 
 #ifdef WIN32
 static boost::filesystem::path StartupShortcutPath() {
     std::string chain = ChainNameFromCommandLine();
     if (chain == CBaseChainParams::MAIN)
         return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin.lnk";
     // Remove this special case when CBaseChainParams::TESTNET = "testnet4"
     if (chain == CBaseChainParams::TESTNET)
         return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin (testnet).lnk";
     return GetSpecialFolderPath(CSIDL_STARTUP) /
            strprintf("Bitcoin (%s).lnk", chain);
 }
 
 bool GetStartOnSystemStartup() {
     // check for Bitcoin*.lnk
     return boost::filesystem::exists(StartupShortcutPath());
 }
 
 bool SetStartOnSystemStartup(bool fAutoStart) {
     // If the shortcut exists already, remove it for updating
     boost::filesystem::remove(StartupShortcutPath());
 
     if (fAutoStart) {
         CoInitialize(nullptr);
 
         // Get a pointer to the IShellLink interface.
         IShellLink *psl = nullptr;
         HRESULT hres =
             CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER,
                              IID_IShellLink, reinterpret_cast<void **>(&psl));
 
         if (SUCCEEDED(hres)) {
             // Get the current executable path
             TCHAR pszExePath[MAX_PATH];
             GetModuleFileName(nullptr, pszExePath, sizeof(pszExePath));
 
             // Start client minimized
             QString strArgs = "-min";
             // Set -testnet /-regtest options
             strArgs += QString::fromStdString(strprintf(
                 " -testnet=%d -regtest=%d", GetBoolArg("-testnet", false),
                 GetBoolArg("-regtest", false)));
 
 #ifdef UNICODE
             boost::scoped_array<TCHAR> args(new TCHAR[strArgs.length() + 1]);
             // Convert the QString to TCHAR*
             strArgs.toWCharArray(args.get());
             // Add missing '\0'-termination to string
             args[strArgs.length()] = '\0';
 #endif
 
             // Set the path to the shortcut target
             psl->SetPath(pszExePath);
             PathRemoveFileSpec(pszExePath);
             psl->SetWorkingDirectory(pszExePath);
             psl->SetShowCmd(SW_SHOWMINNOACTIVE);
 #ifndef UNICODE
             psl->SetArguments(strArgs.toStdString().c_str());
 #else
             psl->SetArguments(args.get());
 #endif
 
             // Query IShellLink for the IPersistFile interface for
             // saving the shortcut in persistent storage.
             IPersistFile *ppf = nullptr;
             hres = psl->QueryInterface(IID_IPersistFile,
                                        reinterpret_cast<void **>(&ppf));
             if (SUCCEEDED(hres)) {
                 WCHAR pwsz[MAX_PATH];
                 // Ensure that the string is ANSI.
                 MultiByteToWideChar(CP_ACP, 0,
                                     StartupShortcutPath().string().c_str(), -1,
                                     pwsz, MAX_PATH);
                 // Save the link by calling IPersistFile::Save.
                 hres = ppf->Save(pwsz, TRUE);
                 ppf->Release();
                 psl->Release();
                 CoUninitialize();
                 return true;
             }
             psl->Release();
         }
         CoUninitialize();
         return false;
     }
     return true;
 }
 #elif defined(Q_OS_LINUX)
 
 // Follow the Desktop Application Autostart Spec:
 // http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
 
 static boost::filesystem::path GetAutostartDir() {
     namespace fs = boost::filesystem;
 
     char *pszConfigHome = getenv("XDG_CONFIG_HOME");
     if (pszConfigHome) return fs::path(pszConfigHome) / "autostart";
     char *pszHome = getenv("HOME");
     if (pszHome) return fs::path(pszHome) / ".config" / "autostart";
     return fs::path();
 }
 
 static boost::filesystem::path GetAutostartFilePath() {
     std::string chain = ChainNameFromCommandLine();
     if (chain == CBaseChainParams::MAIN)
         return GetAutostartDir() / "bitcoin.desktop";
     return GetAutostartDir() / strprintf("bitcoin-%s.lnk", chain);
 }
 
 bool GetStartOnSystemStartup() {
     boost::filesystem::ifstream optionFile(GetAutostartFilePath());
     if (!optionFile.good()) return false;
     // Scan through file for "Hidden=true":
     std::string line;
     while (!optionFile.eof()) {
         getline(optionFile, line);
         if (line.find("Hidden") != std::string::npos &&
             line.find("true") != std::string::npos)
             return false;
     }
     optionFile.close();
 
     return true;
 }
 
 bool SetStartOnSystemStartup(bool fAutoStart) {
     if (!fAutoStart)
         boost::filesystem::remove(GetAutostartFilePath());
     else {
         char pszExePath[MAX_PATH + 1];
         memset(pszExePath, 0, sizeof(pszExePath));
         if (readlink("/proc/self/exe", pszExePath, sizeof(pszExePath) - 1) ==
             -1)
             return false;
 
         boost::filesystem::create_directories(GetAutostartDir());
 
         boost::filesystem::ofstream optionFile(
             GetAutostartFilePath(), std::ios_base::out | std::ios_base::trunc);
         if (!optionFile.good()) return false;
         std::string chain = ChainNameFromCommandLine();
         // Write a bitcoin.desktop file to the autostart directory:
         optionFile << "[Desktop Entry]\n";
         optionFile << "Type=Application\n";
         if (chain == CBaseChainParams::MAIN)
             optionFile << "Name=Bitcoin\n";
         else
             optionFile << strprintf("Name=Bitcoin (%s)\n", chain);
         optionFile << "Exec=" << pszExePath
                    << strprintf(" -min -testnet=%d -regtest=%d\n",
                                 GetBoolArg("-testnet", false),
                                 GetBoolArg("-regtest", false));
         optionFile << "Terminal=false\n";
         optionFile << "Hidden=false\n";
         optionFile.close();
     }
     return true;
 }
 
 #elif defined(Q_OS_MAC)
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
 // based on:
 // https://github.com/Mozketo/LaunchAtLoginController/blob/master/LaunchAtLoginController.m
 
 #include <CoreFoundation/CoreFoundation.h>
 #include <CoreServices/CoreServices.h>
 
 // NB: caller must release returned ref if it's not NULL
 LSSharedFileListItemRef findStartupItemInList(LSSharedFileListRef list,
                                               CFURLRef findUrl);
 LSSharedFileListItemRef findStartupItemInList(LSSharedFileListRef list,
                                               CFURLRef findUrl) {
     LSSharedFileListItemRef foundItem = nullptr;
     // loop through the list of startup items and try to find the bitcoin app
     CFArrayRef listSnapshot = LSSharedFileListCopySnapshot(list, nullptr);
     for (int i = 0; !foundItem && i < CFArrayGetCount(listSnapshot); ++i) {
         LSSharedFileListItemRef item =
             (LSSharedFileListItemRef)CFArrayGetValueAtIndex(listSnapshot, i);
         UInt32 resolutionFlags = kLSSharedFileListNoUserInteraction |
                                  kLSSharedFileListDoNotMountVolumes;
         CFURLRef currentItemURL = nullptr;
 
 #if defined(MAC_OS_X_VERSION_MAX_ALLOWED) &&                                   \
     MAC_OS_X_VERSION_MAX_ALLOWED >= 10100
         if (&LSSharedFileListItemCopyResolvedURL)
             currentItemURL = LSSharedFileListItemCopyResolvedURL(
                 item, resolutionFlags, nullptr);
 #if defined(MAC_OS_X_VERSION_MIN_REQUIRED) &&                                  \
     MAC_OS_X_VERSION_MIN_REQUIRED < 10100
         else
             LSSharedFileListItemResolve(item, resolutionFlags, &currentItemURL,
                                         nullptr);
 #endif
 #else
         LSSharedFileListItemResolve(item, resolutionFlags, &currentItemURL,
                                     nullptr);
 #endif
 
         if (currentItemURL && CFEqual(currentItemURL, findUrl)) {
             // found
             CFRetain(foundItem = item);
         }
         if (currentItemURL) {
             CFRelease(currentItemURL);
         }
     }
     CFRelease(listSnapshot);
     return foundItem;
 }
 
 bool GetStartOnSystemStartup() {
     CFURLRef bitcoinAppUrl = CFBundleCopyBundleURL(CFBundleGetMainBundle());
     LSSharedFileListRef loginItems = LSSharedFileListCreate(
         nullptr, kLSSharedFileListSessionLoginItems, nullptr);
     LSSharedFileListItemRef foundItem =
         findStartupItemInList(loginItems, bitcoinAppUrl);
     // findStartupItemInList retains the item it returned, need to release
     if (foundItem) {
         CFRelease(foundItem);
     }
     CFRelease(loginItems);
     CFRelease(bitcoinAppUrl);
     return foundItem;
 }
 
 bool SetStartOnSystemStartup(bool fAutoStart) {
     CFURLRef bitcoinAppUrl = CFBundleCopyBundleURL(CFBundleGetMainBundle());
     LSSharedFileListRef loginItems = LSSharedFileListCreate(
         nullptr, kLSSharedFileListSessionLoginItems, nullptr);
     LSSharedFileListItemRef foundItem =
         findStartupItemInList(loginItems, bitcoinAppUrl);
 
     if (fAutoStart && !foundItem) {
         // add bitcoin app to startup item list
         LSSharedFileListInsertItemURL(loginItems,
                                       kLSSharedFileListItemBeforeFirst, nullptr,
                                       nullptr, bitcoinAppUrl, nullptr, nullptr);
     } else if (!fAutoStart && foundItem) {
         // remove item
         LSSharedFileListItemRemove(loginItems, foundItem);
     }
     // findStartupItemInList retains the item it returned, need to release
     if (foundItem) {
         CFRelease(foundItem);
     }
     CFRelease(loginItems);
     CFRelease(bitcoinAppUrl);
     return true;
 }
 #pragma GCC diagnostic pop
 #else
 
 bool GetStartOnSystemStartup() {
     return false;
 }
 bool SetStartOnSystemStartup(bool fAutoStart) {
     return false;
 }
 
 #endif
 
 void saveWindowGeometry(const QString &strSetting, QWidget *parent) {
     QSettings settings;
     settings.setValue(strSetting + "Pos", parent->pos());
     settings.setValue(strSetting + "Size", parent->size());
 }
 
 void restoreWindowGeometry(const QString &strSetting, const QSize &defaultSize,
                            QWidget *parent) {
     QSettings settings;
     QPoint pos = settings.value(strSetting + "Pos").toPoint();
     QSize size = settings.value(strSetting + "Size", defaultSize).toSize();
 
     if (!pos.x() && !pos.y()) {
         QRect screen = QApplication::desktop()->screenGeometry();
         pos.setX((screen.width() - size.width()) / 2);
         pos.setY((screen.height() - size.height()) / 2);
     }
 
     parent->resize(size);
     parent->move(pos);
 }
 
 void setClipboard(const QString &str) {
     QApplication::clipboard()->setText(str, QClipboard::Clipboard);
     QApplication::clipboard()->setText(str, QClipboard::Selection);
 }
 
 #if BOOST_FILESYSTEM_VERSION >= 3
 boost::filesystem::path qstringToBoostPath(const QString &path) {
     return boost::filesystem::path(path.toStdString(), utf8);
 }
 
 QString boostPathToQString(const boost::filesystem::path &path) {
     return QString::fromStdString(path.string(utf8));
 }
 #else
 #warning Conversion between boost path and QString can use invalid character encoding with boost_filesystem v2 and older
 boost::filesystem::path qstringToBoostPath(const QString &path) {
     return boost::filesystem::path(path.toStdString());
 }
 
 QString boostPathToQString(const boost::filesystem::path &path) {
     return QString::fromStdString(path.string());
 }
 #endif
 
 QString formatDurationStr(int secs) {
     QStringList strList;
     int days = secs / 86400;
     int hours = (secs % 86400) / 3600;
     int mins = (secs % 3600) / 60;
     int seconds = secs % 60;
 
     if (days) strList.append(QString(QObject::tr("%1 d")).arg(days));
     if (hours) strList.append(QString(QObject::tr("%1 h")).arg(hours));
     if (mins) strList.append(QString(QObject::tr("%1 m")).arg(mins));
     if (seconds || (!days && !hours && !mins))
         strList.append(QString(QObject::tr("%1 s")).arg(seconds));
 
     return strList.join(" ");
 }
 
 QString formatServicesStr(quint64 mask) {
     QStringList strList;
 
     // Just scan the last 8 bits for now.
     for (int i = 0; i < 8; i++) {
         uint64_t check = 1 << i;
         if (mask & check) {
             switch (check) {
                 case NODE_NETWORK:
                     strList.append("NETWORK");
                     break;
                 case NODE_GETUTXO:
                     strList.append("GETUTXO");
                     break;
                 case NODE_BLOOM:
                     strList.append("BLOOM");
                     break;
                 case NODE_XTHIN:
                     strList.append("XTHIN");
                     break;
                 case NODE_BITCOIN_CASH:
                     strList.append("CASH");
                     break;
                 default:
                     strList.append(QString("%1[%2]").arg("UNKNOWN").arg(check));
             }
         }
     }
 
     if (strList.size())
         return strList.join(" & ");
     else
         return QObject::tr("None");
 }
 
 QString formatPingTime(double dPingTime) {
     return (dPingTime == std::numeric_limits<int64_t>::max() / 1e6 ||
             dPingTime == 0)
                ? QObject::tr("N/A")
                : QString(QObject::tr("%1 ms"))
                      .arg(QString::number((int)(dPingTime * 1000), 10));
 }
 
 QString formatTimeOffset(int64_t nTimeOffset) {
     return QString(QObject::tr("%1 s"))
         .arg(QString::number((int)nTimeOffset, 10));
 }
 
 QString formatNiceTimeOffset(qint64 secs) {
     // Represent time from last generated block in human readable text
     QString timeBehindText;
     const int HOUR_IN_SECONDS = 60 * 60;
     const int DAY_IN_SECONDS = 24 * 60 * 60;
     const int WEEK_IN_SECONDS = 7 * 24 * 60 * 60;
     // Average length of year in Gregorian calendar
     const int YEAR_IN_SECONDS = 31556952;
     if (secs < 60) {
         timeBehindText = QObject::tr("%n second(s)", "", secs);
     } else if (secs < 2 * HOUR_IN_SECONDS) {
         timeBehindText = QObject::tr("%n minute(s)", "", secs / 60);
     } else if (secs < 2 * DAY_IN_SECONDS) {
         timeBehindText = QObject::tr("%n hour(s)", "", secs / HOUR_IN_SECONDS);
     } else if (secs < 2 * WEEK_IN_SECONDS) {
         timeBehindText = QObject::tr("%n day(s)", "", secs / DAY_IN_SECONDS);
     } else if (secs < YEAR_IN_SECONDS) {
         timeBehindText = QObject::tr("%n week(s)", "", secs / WEEK_IN_SECONDS);
     } else {
         qint64 years = secs / YEAR_IN_SECONDS;
         qint64 remainder = secs % YEAR_IN_SECONDS;
         timeBehindText = QObject::tr("%1 and %2")
                              .arg(QObject::tr("%n year(s)", "", years))
                              .arg(QObject::tr("%n week(s)", "",
                                               remainder / WEEK_IN_SECONDS));
     }
     return timeBehindText;
 }
 
 void ClickableLabel::mouseReleaseEvent(QMouseEvent *event) {
     Q_EMIT clicked(event->pos());
 }
 
 void ClickableProgressBar::mouseReleaseEvent(QMouseEvent *event) {
     Q_EMIT clicked(event->pos());
 }
 
 } // namespace GUIUtil
diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp
index 933cdf62e..75e2e2a97 100644
--- a/src/qt/paymentrequestplus.cpp
+++ b/src/qt/paymentrequestplus.cpp
@@ -1,233 +1,232 @@
 // Copyright (c) 2011-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.
 
 //
 // Wraps dumb protocol buffer paymentRequest with some extra methods
 //
 
 #include "paymentrequestplus.h"
 
 #include "util.h"
 
 #include <stdexcept>
 
 #include <openssl/x509_vfy.h>
 
 #include <QDateTime>
 #include <QDebug>
 #include <QSslCertificate>
 
 class SSLVerifyError : public std::runtime_error {
 public:
     SSLVerifyError(std::string err) : std::runtime_error(err) {}
 };
 
 bool PaymentRequestPlus::parse(const QByteArray &data) {
     bool parseOK = paymentRequest.ParseFromArray(data.data(), data.size());
     if (!parseOK) {
         qWarning()
             << "PaymentRequestPlus::parse: Error parsing payment request";
         return false;
     }
     if (paymentRequest.payment_details_version() > 1) {
         qWarning() << "PaymentRequestPlus::parse: Received up-version payment "
                       "details, version="
                    << paymentRequest.payment_details_version();
         return false;
     }
 
     parseOK =
         details.ParseFromString(paymentRequest.serialized_payment_details());
     if (!parseOK) {
         qWarning()
             << "PaymentRequestPlus::parse: Error parsing payment details";
         paymentRequest.Clear();
         return false;
     }
     return true;
 }
 
 bool PaymentRequestPlus::SerializeToString(std::string *output) const {
     return paymentRequest.SerializeToString(output);
 }
 
 bool PaymentRequestPlus::IsInitialized() const {
     return paymentRequest.IsInitialized();
 }
 
 bool PaymentRequestPlus::getMerchant(X509_STORE *certStore,
                                      QString &merchant) const {
     merchant.clear();
 
     if (!IsInitialized()) return false;
 
     // One day we'll support more PKI types, but just x509 for now:
     const EVP_MD *digestAlgorithm = nullptr;
     if (paymentRequest.pki_type() == "x509+sha256") {
         digestAlgorithm = EVP_sha256();
     } else if (paymentRequest.pki_type() == "x509+sha1") {
         digestAlgorithm = EVP_sha1();
     } else if (paymentRequest.pki_type() == "none") {
         qWarning() << "PaymentRequestPlus::getMerchant: Payment request: "
                       "pki_type == none";
         return false;
     } else {
         qWarning() << "PaymentRequestPlus::getMerchant: Payment request: "
                       "unknown pki_type "
                    << QString::fromStdString(paymentRequest.pki_type());
         return false;
     }
 
     payments::X509Certificates certChain;
     if (!certChain.ParseFromString(paymentRequest.pki_data())) {
         qWarning() << "PaymentRequestPlus::getMerchant: Payment request: error "
                       "parsing pki_data";
         return false;
     }
 
     std::vector<X509 *> certs;
     const QDateTime currentTime = QDateTime::currentDateTime();
     for (int i = 0; i < certChain.certificate_size(); i++) {
         QByteArray certData(certChain.certificate(i).data(),
                             certChain.certificate(i).size());
         QSslCertificate qCert(certData, QSsl::Der);
         if (currentTime < qCert.effectiveDate() ||
             currentTime > qCert.expiryDate()) {
             qWarning() << "PaymentRequestPlus::getMerchant: Payment request: "
                           "certificate expired or not yet active: "
                        << qCert;
             return false;
         }
 #if QT_VERSION >= 0x050000
         if (qCert.isBlacklisted()) {
             qWarning() << "PaymentRequestPlus::getMerchant: Payment request: "
                           "certificate blacklisted: "
                        << qCert;
             return false;
         }
 #endif
-        const unsigned char *data =
-            (const unsigned char *)certChain.certificate(i).data();
+        const uint8_t *data = (const uint8_t *)certChain.certificate(i).data();
         X509 *cert = d2i_X509(nullptr, &data, certChain.certificate(i).size());
         if (cert) certs.push_back(cert);
     }
     if (certs.empty()) {
         qWarning() << "PaymentRequestPlus::getMerchant: Payment request: empty "
                       "certificate chain";
         return false;
     }
 
     // The first cert is the signing cert, the rest are untrusted certs that
     // chain to a valid root authority. OpenSSL needs them separately.
     STACK_OF(X509) *chain = sk_X509_new_null();
     for (int i = certs.size() - 1; i > 0; i--) {
         sk_X509_push(chain, certs[i]);
     }
     X509 *signing_cert = certs[0];
 
     // Now create a "store context", which is a single use object for checking,
     // load the signing cert into it and verify.
     X509_STORE_CTX *store_ctx = X509_STORE_CTX_new();
     if (!store_ctx) {
         qWarning() << "PaymentRequestPlus::getMerchant: Payment request: error "
                       "creating X509_STORE_CTX";
         return false;
     }
 
     char *website = nullptr;
     bool fResult = true;
     try {
         if (!X509_STORE_CTX_init(store_ctx, certStore, signing_cert, chain)) {
             int error = X509_STORE_CTX_get_error(store_ctx);
             throw SSLVerifyError(X509_verify_cert_error_string(error));
         }
 
         // Now do the verification!
         int result = X509_verify_cert(store_ctx);
         if (result != 1) {
             int error = X509_STORE_CTX_get_error(store_ctx);
             // For testing payment requests, we allow self signed root certs!
             // This option is just shown in the UI options, if -help-debug is
             // enabled.
             if (!(error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT &&
                   GetBoolArg("-allowselfsignedrootcertificates",
                              DEFAULT_SELFSIGNED_ROOTCERTS))) {
                 throw SSLVerifyError(X509_verify_cert_error_string(error));
             } else {
                 qDebug() << "PaymentRequestPlus::getMerchant: Allowing self "
                             "signed root certificate, because "
                             "-allowselfsignedrootcertificates is true.";
             }
         }
         X509_NAME *certname = X509_get_subject_name(signing_cert);
 
         // Valid cert; check signature:
         // Copy
         payments::PaymentRequest rcopy(paymentRequest);
         rcopy.set_signature(std::string(""));
         // Everything but the signature
         std::string data_to_verify;
         rcopy.SerializeToString(&data_to_verify);
 
 #if HAVE_DECL_EVP_MD_CTX_NEW
         EVP_MD_CTX *ctx = EVP_MD_CTX_new();
         if (!ctx) throw SSLVerifyError("Error allocating OpenSSL context.");
 #else
         EVP_MD_CTX _ctx;
         EVP_MD_CTX *ctx;
         ctx = &_ctx;
 #endif
         EVP_PKEY *pubkey = X509_get_pubkey(signing_cert);
         EVP_MD_CTX_init(ctx);
         if (!EVP_VerifyInit_ex(ctx, digestAlgorithm, nullptr) ||
             !EVP_VerifyUpdate(ctx, data_to_verify.data(),
                               data_to_verify.size()) ||
             !EVP_VerifyFinal(
-                ctx, (const unsigned char *)paymentRequest.signature().data(),
+                ctx, (const uint8_t *)paymentRequest.signature().data(),
                 (unsigned int)paymentRequest.signature().size(), pubkey)) {
             throw SSLVerifyError("Bad signature, invalid payment request.");
         }
 #if HAVE_DECL_EVP_MD_CTX_NEW
         EVP_MD_CTX_free(ctx);
 #endif
 
         // OpenSSL API for getting human printable strings from certs is
         // baroque.
         int textlen =
             X509_NAME_get_text_by_NID(certname, NID_commonName, nullptr, 0);
         website = new char[textlen + 1];
         if (X509_NAME_get_text_by_NID(certname, NID_commonName, website,
                                       textlen + 1) == textlen &&
             textlen > 0) {
             merchant = website;
         } else {
             throw SSLVerifyError("Bad certificate, missing common name.");
         }
         // TODO: detect EV certificates and set merchant = business name instead
         // of unfriendly NID_commonName ?
     } catch (const SSLVerifyError &err) {
         fResult = false;
         qWarning() << "PaymentRequestPlus::getMerchant: SSL error: "
                    << err.what();
     }
 
     if (website) delete[] website;
     X509_STORE_CTX_free(store_ctx);
     for (unsigned int i = 0; i < certs.size(); i++)
         X509_free(certs[i]);
 
     return fResult;
 }
 
 QList<std::pair<CScript, CAmount>> PaymentRequestPlus::getPayTo() const {
     QList<std::pair<CScript, CAmount>> result;
     for (int i = 0; i < details.outputs_size(); i++) {
-        const unsigned char *scriptStr =
-            (const unsigned char *)details.outputs(i).script().data();
+        const uint8_t *scriptStr =
+            (const uint8_t *)details.outputs(i).script().data();
         CScript s(scriptStr, scriptStr + details.outputs(i).script().size());
 
         result.append(std::make_pair(s, details.outputs(i).amount()));
     }
     return result;
 }
diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp
index 0da6da13c..914c725a4 100644
--- a/src/qt/paymentserver.cpp
+++ b/src/qt/paymentserver.cpp
@@ -1,817 +1,817 @@
 // Copyright (c) 2011-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.
 
 #include "paymentserver.h"
 
 #include "bitcoinunits.h"
 #include "guiutil.h"
 #include "optionsmodel.h"
 
 #include "base58.h"
 #include "chainparams.h"
 #include "policy/policy.h"
 #include "ui_interface.h"
 #include "util.h"
 #include "wallet/wallet.h"
 
 #include <cstdlib>
 
 #include <openssl/x509_vfy.h>
 
 #include <QApplication>
 #include <QByteArray>
 #include <QDataStream>
 #include <QDateTime>
 #include <QDebug>
 #include <QFile>
 #include <QFileOpenEvent>
 #include <QHash>
 #include <QList>
 #include <QLocalServer>
 #include <QLocalSocket>
 #include <QNetworkAccessManager>
 #include <QNetworkProxy>
 #include <QNetworkReply>
 #include <QNetworkRequest>
 #include <QSslCertificate>
 #include <QSslError>
 #include <QSslSocket>
 #include <QStringList>
 #include <QTextDocument>
 
 #if QT_VERSION < 0x050000
 #include <QUrl>
 #else
 #include <QUrlQuery>
 #endif
 
 const int BITCOIN_IPC_CONNECT_TIMEOUT = 1000; // milliseconds
 const QString BITCOIN_IPC_PREFIX("bitcoin:");
 // BIP70 payment protocol messages
 const char *BIP70_MESSAGE_PAYMENTACK = "PaymentACK";
 const char *BIP70_MESSAGE_PAYMENTREQUEST = "PaymentRequest";
 // BIP71 payment protocol media types
 const char *BIP71_MIMETYPE_PAYMENT = "application/bitcoin-payment";
 const char *BIP71_MIMETYPE_PAYMENTACK = "application/bitcoin-paymentack";
 const char *BIP71_MIMETYPE_PAYMENTREQUEST =
     "application/bitcoin-paymentrequest";
 
 struct X509StoreDeleter {
     void operator()(X509_STORE *b) { X509_STORE_free(b); }
 };
 
 struct X509Deleter {
     void operator()(X509 *b) { X509_free(b); }
 };
 
 namespace // Anon namespace
 {
 std::unique_ptr<X509_STORE, X509StoreDeleter> certStore;
 }
 
 //
 // Create a name that is unique for:
 //  testnet / non-testnet
 //  data directory
 //
 static QString ipcServerName() {
     QString name("BitcoinQt");
 
     // Append a simple hash of the datadir
     // Note that GetDataDir(true) returns a different path for -testnet versus
     // main net
     QString ddir(GUIUtil::boostPathToQString(GetDataDir(true)));
     name.append(QString::number(qHash(ddir)));
 
     return name;
 }
 
 //
 // We store payment URIs and requests received before the main GUI window is up
 // and ready to ask the user to send payment.
 //
 static QList<QString> savedPaymentRequests;
 
 static void ReportInvalidCertificate(const QSslCertificate &cert) {
 #if QT_VERSION < 0x050000
     qDebug() << QString("%1: Payment server found an invalid certificate: ")
                     .arg(__func__)
              << cert.serialNumber()
              << cert.subjectInfo(QSslCertificate::CommonName)
              << cert.subjectInfo(QSslCertificate::OrganizationalUnitName);
 #else
     qDebug() << QString("%1: Payment server found an invalid certificate: ")
                     .arg(__func__)
              << cert.serialNumber()
              << cert.subjectInfo(QSslCertificate::CommonName)
              << cert.subjectInfo(QSslCertificate::DistinguishedNameQualifier)
              << cert.subjectInfo(QSslCertificate::OrganizationalUnitName);
 #endif
 }
 
 //
 // Load OpenSSL's list of root certificate authorities
 //
 void PaymentServer::LoadRootCAs(X509_STORE *_store) {
     // Unit tests mostly use this, to pass in fake root CAs:
     if (_store) {
         certStore.reset(_store);
         return;
     }
 
     // Normal execution, use either -rootcertificates or system certs:
     certStore.reset(X509_STORE_new());
 
     // Note: use "-system-" default here so that users can pass
     // -rootcertificates="" and get 'I don't like X.509 certificates, don't
     // trust anybody' behavior:
     QString certFile =
         QString::fromStdString(GetArg("-rootcertificates", "-system-"));
 
     // Empty store
     if (certFile.isEmpty()) {
         qDebug() << QString("PaymentServer::%1: Payment request authentication "
                             "via X.509 certificates disabled.")
                         .arg(__func__);
         return;
     }
 
     QList<QSslCertificate> certList;
 
     if (certFile != "-system-") {
         qDebug() << QString("PaymentServer::%1: Using \"%2\" as trusted root "
                             "certificate.")
                         .arg(__func__)
                         .arg(certFile);
 
         certList = QSslCertificate::fromPath(certFile);
         // Use those certificates when fetching payment requests, too:
         QSslSocket::setDefaultCaCertificates(certList);
     } else
         certList = QSslSocket::systemCaCertificates();
 
     int nRootCerts = 0;
     const QDateTime currentTime = QDateTime::currentDateTime();
 
     for (const QSslCertificate &cert : certList) {
         // Don't log nullptr certificates
         if (cert.isNull()) continue;
 
         // Not yet active/valid, or expired certificate
         if (currentTime < cert.effectiveDate() ||
             currentTime > cert.expiryDate()) {
             ReportInvalidCertificate(cert);
             continue;
         }
 
 #if QT_VERSION >= 0x050000
         // Blacklisted certificate
         if (cert.isBlacklisted()) {
             ReportInvalidCertificate(cert);
             continue;
         }
 #endif
         QByteArray certData = cert.toDer();
-        const unsigned char *data = (const unsigned char *)certData.data();
+        const uint8_t *data = (const uint8_t *)certData.data();
 
         std::unique_ptr<X509, X509Deleter> x509(
             d2i_X509(0, &data, certData.size()));
         if (x509 && X509_STORE_add_cert(certStore.get(), x509.get())) {
             // Note: X509_STORE increases the reference count to the X509
             // object, we still have to release our reference to it.
             ++nRootCerts;
         } else {
             ReportInvalidCertificate(cert);
             continue;
         }
     }
     qWarning() << "PaymentServer::LoadRootCAs: Loaded " << nRootCerts
                << " root certificates";
 
     // Project for another day:
     // Fetch certificate revocation lists, and add them to certStore.
     // Issues to consider:
     //   performance (start a thread to fetch in background?)
     //   privacy (fetch through tor/proxy so IP address isn't revealed)
     //   would it be easier to just use a compiled-in blacklist?
     //    or use Qt's blacklist?
     //   "certificate stapling" with server-side caching is more efficient
 }
 
 //
 // Sending to the server is done synchronously, at startup.
 // If the server isn't already running, startup continues, and the items in
 // savedPaymentRequest will be handled when uiReady() is called.
 //
 // Warning: ipcSendCommandLine() is called early in init, so don't use "Q_EMIT
 // message()", but "QMessageBox::"!
 //
 void PaymentServer::ipcParseCommandLine(int argc, char *argv[]) {
     for (int i = 1; i < argc; i++) {
         QString arg(argv[i]);
         if (arg.startsWith("-")) continue;
 
         // If the bitcoin: URI contains a payment request, we are not able to
         // detect the network as that would require fetching and parsing the
         // payment request. That means clicking such an URI which contains a
         // testnet payment request will start a mainnet instance and throw a
         // "wrong network" error.
         if (arg.startsWith(BITCOIN_IPC_PREFIX,
                            Qt::CaseInsensitive)) // bitcoin: URI
         {
             savedPaymentRequests.append(arg);
 
             SendCoinsRecipient r;
             if (GUIUtil::parseBitcoinURI(arg, &r) && !r.address.isEmpty()) {
                 CBitcoinAddress address(r.address.toStdString());
 
                 if (address.IsValid(Params(CBaseChainParams::MAIN))) {
                     SelectParams(CBaseChainParams::MAIN);
                 } else if (address.IsValid(Params(CBaseChainParams::TESTNET))) {
                     SelectParams(CBaseChainParams::TESTNET);
                 }
             }
         } else if (QFile::exists(arg)) {
             // Filename
             savedPaymentRequests.append(arg);
 
             PaymentRequestPlus request;
             if (readPaymentRequestFromFile(arg, request)) {
                 if (request.getDetails().network() == "main") {
                     SelectParams(CBaseChainParams::MAIN);
                 } else if (request.getDetails().network() == "test") {
                     SelectParams(CBaseChainParams::TESTNET);
                 }
             }
         } else {
             // Printing to debug.log is about the best we can do here, the GUI
             // hasn't started yet so we can't pop up a message box.
             qWarning() << "PaymentServer::ipcSendCommandLine: Payment request "
                           "file does not exist: "
                        << arg;
         }
     }
 }
 
 //
 // Sending to the server is done synchronously, at startup.
 // If the server isn't already running, startup continues, and the items in
 // savedPaymentRequest will be handled when uiReady() is called.
 //
 bool PaymentServer::ipcSendCommandLine() {
     bool fResult = false;
     for (const QString &r : savedPaymentRequests) {
         QLocalSocket *socket = new QLocalSocket();
         socket->connectToServer(ipcServerName(), QIODevice::WriteOnly);
         if (!socket->waitForConnected(BITCOIN_IPC_CONNECT_TIMEOUT)) {
             delete socket;
             socket = nullptr;
             return false;
         }
 
         QByteArray block;
         QDataStream out(&block, QIODevice::WriteOnly);
         out.setVersion(QDataStream::Qt_4_0);
         out << r;
         out.device()->seek(0);
 
         socket->write(block);
         socket->flush();
         socket->waitForBytesWritten(BITCOIN_IPC_CONNECT_TIMEOUT);
         socket->disconnectFromServer();
 
         delete socket;
         socket = nullptr;
         fResult = true;
     }
 
     return fResult;
 }
 
 PaymentServer::PaymentServer(QObject *parent, bool startLocalServer)
     : QObject(parent), saveURIs(true), uriServer(0), netManager(0),
       optionsModel(0) {
     // Verify that the version of the library that we linked against is
     // compatible with the version of the headers we compiled against.
     GOOGLE_PROTOBUF_VERIFY_VERSION;
 
     // Install global event filter to catch QFileOpenEvents
     // on Mac: sent when you click bitcoin: links
     // other OSes: helpful when dealing with payment request files
     if (parent) parent->installEventFilter(this);
 
     QString name = ipcServerName();
 
     // Clean up old socket leftover from a crash:
     QLocalServer::removeServer(name);
 
     if (startLocalServer) {
         uriServer = new QLocalServer(this);
 
         if (!uriServer->listen(name)) {
             // constructor is called early in init, so don't use "Q_EMIT
             // message()" here
             QMessageBox::critical(
                 0, tr("Payment request error"),
                 tr("Cannot start bitcoin: click-to-pay handler"));
         } else {
             connect(uriServer, SIGNAL(newConnection()), this,
                     SLOT(handleURIConnection()));
             connect(this, SIGNAL(receivedPaymentACK(QString)), this,
                     SLOT(handlePaymentACK(QString)));
         }
     }
 }
 
 PaymentServer::~PaymentServer() {
     google::protobuf::ShutdownProtobufLibrary();
 }
 
 //
 // OSX-specific way of handling bitcoin: URIs and PaymentRequest mime types.
 // Also used by paymentservertests.cpp and when opening a payment request file
 // via "Open URI..." menu entry.
 //
 bool PaymentServer::eventFilter(QObject *object, QEvent *event) {
     if (event->type() == QEvent::FileOpen) {
         QFileOpenEvent *fileEvent = static_cast<QFileOpenEvent *>(event);
         if (!fileEvent->file().isEmpty())
             handleURIOrFile(fileEvent->file());
         else if (!fileEvent->url().isEmpty())
             handleURIOrFile(fileEvent->url().toString());
 
         return true;
     }
 
     return QObject::eventFilter(object, event);
 }
 
 void PaymentServer::initNetManager() {
     if (!optionsModel) return;
     if (netManager != nullptr) delete netManager;
 
     // netManager is used to fetch paymentrequests given in bitcoin: URIs
     netManager = new QNetworkAccessManager(this);
 
     QNetworkProxy proxy;
 
     // Query active SOCKS5 proxy
     if (optionsModel->getProxySettings(proxy)) {
         netManager->setProxy(proxy);
 
         qDebug() << "PaymentServer::initNetManager: Using SOCKS5 proxy"
                  << proxy.hostName() << ":" << proxy.port();
     } else
         qDebug()
             << "PaymentServer::initNetManager: No active proxy server found.";
 
     connect(netManager, SIGNAL(finished(QNetworkReply *)), this,
             SLOT(netRequestFinished(QNetworkReply *)));
     connect(netManager,
             SIGNAL(sslErrors(QNetworkReply *, const QList<QSslError> &)), this,
             SLOT(reportSslErrors(QNetworkReply *, const QList<QSslError> &)));
 }
 
 void PaymentServer::uiReady() {
     initNetManager();
 
     saveURIs = false;
     for (const QString &s : savedPaymentRequests) {
         handleURIOrFile(s);
     }
     savedPaymentRequests.clear();
 }
 
 void PaymentServer::handleURIOrFile(const QString &s) {
     if (saveURIs) {
         savedPaymentRequests.append(s);
         return;
     }
 
     // bitcoin: URI
     if (s.startsWith(BITCOIN_IPC_PREFIX, Qt::CaseInsensitive)) {
 #if QT_VERSION < 0x050000
         QUrl uri(s);
 #else
         QUrlQuery uri((QUrl(s)));
 #endif
         if (uri.hasQueryItem("r")) {
             // payment request URI
             QByteArray temp;
             temp.append(uri.queryItemValue("r"));
             QString decoded = QUrl::fromPercentEncoding(temp);
             QUrl fetchUrl(decoded, QUrl::StrictMode);
 
             if (fetchUrl.isValid()) {
                 qDebug() << "PaymentServer::handleURIOrFile: fetchRequest("
                          << fetchUrl << ")";
                 fetchRequest(fetchUrl);
             } else {
                 qWarning() << "PaymentServer::handleURIOrFile: Invalid URL: "
                            << fetchUrl;
                 Q_EMIT message(tr("URI handling"),
                                tr("Payment request fetch URL is invalid: %1")
                                    .arg(fetchUrl.toString()),
                                CClientUIInterface::ICON_WARNING);
             }
 
             return;
         } else {
             // normal URI
             SendCoinsRecipient recipient;
             if (GUIUtil::parseBitcoinURI(s, &recipient)) {
                 CBitcoinAddress address(recipient.address.toStdString());
                 if (!address.IsValid()) {
                     Q_EMIT message(
                         tr("URI handling"),
                         tr("Invalid payment address %1").arg(recipient.address),
                         CClientUIInterface::MSG_ERROR);
                 } else
                     Q_EMIT receivedPaymentRequest(recipient);
             } else
                 Q_EMIT message(
                     tr("URI handling"),
                     tr("URI cannot be parsed! This can be caused by an invalid "
                        "Bitcoin address or malformed URI parameters."),
                     CClientUIInterface::ICON_WARNING);
 
             return;
         }
     }
 
     // payment request file
     if (QFile::exists(s)) {
         PaymentRequestPlus request;
         SendCoinsRecipient recipient;
         if (!readPaymentRequestFromFile(s, request)) {
             Q_EMIT message(tr("Payment request file handling"),
                            tr("Payment request file cannot be read! This can "
                               "be caused by an invalid payment request file."),
                            CClientUIInterface::ICON_WARNING);
         } else if (processPaymentRequest(request, recipient))
             Q_EMIT receivedPaymentRequest(recipient);
 
         return;
     }
 }
 
 void PaymentServer::handleURIConnection() {
     QLocalSocket *clientConnection = uriServer->nextPendingConnection();
 
     while (clientConnection->bytesAvailable() < (int)sizeof(quint32))
         clientConnection->waitForReadyRead();
 
     connect(clientConnection, SIGNAL(disconnected()), clientConnection,
             SLOT(deleteLater()));
 
     QDataStream in(clientConnection);
     in.setVersion(QDataStream::Qt_4_0);
     if (clientConnection->bytesAvailable() < (int)sizeof(quint16)) {
         return;
     }
     QString msg;
     in >> msg;
 
     handleURIOrFile(msg);
 }
 
 //
 // Warning: readPaymentRequestFromFile() is used in ipcSendCommandLine()
 // so don't use "Q_EMIT message()", but "QMessageBox::"!
 //
 bool PaymentServer::readPaymentRequestFromFile(const QString &filename,
                                                PaymentRequestPlus &request) {
     QFile f(filename);
     if (!f.open(QIODevice::ReadOnly)) {
         qWarning() << QString("PaymentServer::%1: Failed to open %2")
                           .arg(__func__)
                           .arg(filename);
         return false;
     }
 
     // BIP70 DoS protection
     if (!verifySize(f.size())) {
         return false;
     }
 
     QByteArray data = f.readAll();
 
     return request.parse(data);
 }
 
 bool PaymentServer::processPaymentRequest(const PaymentRequestPlus &request,
                                           SendCoinsRecipient &recipient) {
     if (!optionsModel) return false;
 
     if (request.IsInitialized()) {
         // Payment request network matches client network?
         if (!verifyNetwork(request.getDetails())) {
             Q_EMIT message(
                 tr("Payment request rejected"),
                 tr("Payment request network doesn't match client network."),
                 CClientUIInterface::MSG_ERROR);
 
             return false;
         }
 
         // Make sure any payment requests involved are still valid.
         // This is re-checked just before sending coins in
         // WalletModel::sendCoins().
         if (verifyExpired(request.getDetails())) {
             Q_EMIT message(tr("Payment request rejected"),
                            tr("Payment request expired."),
                            CClientUIInterface::MSG_ERROR);
 
             return false;
         }
     } else {
         Q_EMIT message(tr("Payment request error"),
                        tr("Payment request is not initialized."),
                        CClientUIInterface::MSG_ERROR);
 
         return false;
     }
 
     recipient.paymentRequest = request;
     recipient.message = GUIUtil::HtmlEscape(request.getDetails().memo());
 
     request.getMerchant(certStore.get(), recipient.authenticatedMerchant);
 
     QList<std::pair<CScript, CAmount>> sendingTos = request.getPayTo();
     QStringList addresses;
 
     for (const std::pair<CScript, CAmount> &sendingTo : sendingTos) {
         // Extract and check destination addresses
         CTxDestination dest;
         if (ExtractDestination(sendingTo.first, dest)) {
             // Append destination address
             addresses.append(
                 QString::fromStdString(CBitcoinAddress(dest).ToString()));
         } else if (!recipient.authenticatedMerchant.isEmpty()) {
             // Unauthenticated payment requests to custom bitcoin addresses are
             // not supported (there is no good way to tell the user where they
             // are paying in a way they'd have a chance of understanding).
             Q_EMIT message(tr("Payment request rejected"),
                            tr("Unverified payment requests to custom payment "
                               "scripts are unsupported."),
                            CClientUIInterface::MSG_ERROR);
             return false;
         }
 
         // Bitcoin amounts are stored as (optional) uint64 in the protobuf
         // messages (see paymentrequest.proto), but CAmount is defined as
         // int64_t. Because of that we need to verify that amounts are in a
         // valid range and no overflow has happened.
         if (!verifyAmount(sendingTo.second)) {
             Q_EMIT message(tr("Payment request rejected"),
                            tr("Invalid payment request."),
                            CClientUIInterface::MSG_ERROR);
             return false;
         }
 
         // Extract and check amounts
         CTxOut txOut(sendingTo.second, sendingTo.first);
         if (txOut.IsDust(dustRelayFee)) {
             Q_EMIT message(
                 tr("Payment request error"),
                 tr("Requested payment amount of %1 is too small (considered "
                    "dust).")
                     .arg(BitcoinUnits::formatWithUnit(
                         optionsModel->getDisplayUnit(), sendingTo.second)),
                 CClientUIInterface::MSG_ERROR);
 
             return false;
         }
 
         recipient.amount += sendingTo.second;
         // Also verify that the final amount is still in a valid range after
         // adding additional amounts.
         if (!verifyAmount(recipient.amount)) {
             Q_EMIT message(tr("Payment request rejected"),
                            tr("Invalid payment request."),
                            CClientUIInterface::MSG_ERROR);
             return false;
         }
     }
     // Store addresses and format them to fit nicely into the GUI
     recipient.address = addresses.join("<br />");
 
     if (!recipient.authenticatedMerchant.isEmpty()) {
         qDebug() << "PaymentServer::processPaymentRequest: Secure payment "
                     "request from "
                  << recipient.authenticatedMerchant;
     } else {
         qDebug() << "PaymentServer::processPaymentRequest: Insecure payment "
                     "request to "
                  << addresses.join(", ");
     }
 
     return true;
 }
 
 void PaymentServer::fetchRequest(const QUrl &url) {
     QNetworkRequest netRequest;
     netRequest.setAttribute(QNetworkRequest::User,
                             BIP70_MESSAGE_PAYMENTREQUEST);
     netRequest.setUrl(url);
     netRequest.setRawHeader("User-Agent", CLIENT_NAME.c_str());
     netRequest.setRawHeader("Accept", BIP71_MIMETYPE_PAYMENTREQUEST);
     netManager->get(netRequest);
 }
 
 void PaymentServer::fetchPaymentACK(CWallet *wallet,
                                     SendCoinsRecipient recipient,
                                     QByteArray transaction) {
     const payments::PaymentDetails &details =
         recipient.paymentRequest.getDetails();
     if (!details.has_payment_url()) return;
 
     QNetworkRequest netRequest;
     netRequest.setAttribute(QNetworkRequest::User, BIP70_MESSAGE_PAYMENTACK);
     netRequest.setUrl(QString::fromStdString(details.payment_url()));
     netRequest.setHeader(QNetworkRequest::ContentTypeHeader,
                          BIP71_MIMETYPE_PAYMENT);
     netRequest.setRawHeader("User-Agent", CLIENT_NAME.c_str());
     netRequest.setRawHeader("Accept", BIP71_MIMETYPE_PAYMENTACK);
 
     payments::Payment payment;
     payment.set_merchant_data(details.merchant_data());
     payment.add_transactions(transaction.data(), transaction.size());
 
     // Create a new refund address, or re-use:
     QString account = tr("Refund from %1").arg(recipient.authenticatedMerchant);
     std::string strAccount = account.toStdString();
     std::set<CTxDestination> refundAddresses =
         wallet->GetAccountAddresses(strAccount);
     if (!refundAddresses.empty()) {
         CScript s = GetScriptForDestination(*refundAddresses.begin());
         payments::Output *refund_to = payment.add_refund_to();
         refund_to->set_script(&s[0], s.size());
     } else {
         CPubKey newKey;
         if (wallet->GetKeyFromPool(newKey)) {
             CKeyID keyID = newKey.GetID();
             wallet->SetAddressBook(keyID, strAccount, "refund");
 
             CScript s = GetScriptForDestination(keyID);
             payments::Output *refund_to = payment.add_refund_to();
             refund_to->set_script(&s[0], s.size());
         } else {
             // This should never happen, because sending coins should have just
             // unlocked the wallet and refilled the keypool.
             qWarning() << "PaymentServer::fetchPaymentACK: Error getting "
                           "refund key, refund_to not set";
         }
     }
 
     int length = payment.ByteSize();
     netRequest.setHeader(QNetworkRequest::ContentLengthHeader, length);
     QByteArray serData(length, '\0');
     if (payment.SerializeToArray(serData.data(), length)) {
         netManager->post(netRequest, serData);
     } else {
         // This should never happen, either.
         qWarning() << "PaymentServer::fetchPaymentACK: Error serializing "
                       "payment message";
     }
 }
 
 void PaymentServer::netRequestFinished(QNetworkReply *reply) {
     reply->deleteLater();
 
     // BIP70 DoS protection
     if (!verifySize(reply->size())) {
         Q_EMIT message(
             tr("Payment request rejected"),
             tr("Payment request %1 is too large (%2 bytes, allowed %3 bytes).")
                 .arg(reply->request().url().toString())
                 .arg(reply->size())
                 .arg(BIP70_MAX_PAYMENTREQUEST_SIZE),
             CClientUIInterface::MSG_ERROR);
         return;
     }
 
     if (reply->error() != QNetworkReply::NoError) {
         QString msg = tr("Error communicating with %1: %2")
                           .arg(reply->request().url().toString())
                           .arg(reply->errorString());
 
         qWarning() << "PaymentServer::netRequestFinished: " << msg;
         Q_EMIT message(tr("Payment request error"), msg,
                        CClientUIInterface::MSG_ERROR);
         return;
     }
 
     QByteArray data = reply->readAll();
 
     QString requestType =
         reply->request().attribute(QNetworkRequest::User).toString();
     if (requestType == BIP70_MESSAGE_PAYMENTREQUEST) {
         PaymentRequestPlus request;
         SendCoinsRecipient recipient;
         if (!request.parse(data)) {
             qWarning() << "PaymentServer::netRequestFinished: Error parsing "
                           "payment request";
             Q_EMIT message(tr("Payment request error"),
                            tr("Payment request cannot be parsed!"),
                            CClientUIInterface::MSG_ERROR);
         } else if (processPaymentRequest(request, recipient))
             Q_EMIT receivedPaymentRequest(recipient);
 
         return;
     } else if (requestType == BIP70_MESSAGE_PAYMENTACK) {
         payments::PaymentACK paymentACK;
         if (!paymentACK.ParseFromArray(data.data(), data.size())) {
             QString msg = tr("Bad response from server %1")
                               .arg(reply->request().url().toString());
 
             qWarning() << "PaymentServer::netRequestFinished: " << msg;
             Q_EMIT message(tr("Payment request error"), msg,
                            CClientUIInterface::MSG_ERROR);
         } else {
             Q_EMIT receivedPaymentACK(GUIUtil::HtmlEscape(paymentACK.memo()));
         }
     }
 }
 
 void PaymentServer::reportSslErrors(QNetworkReply *reply,
                                     const QList<QSslError> &errs) {
     Q_UNUSED(reply);
 
     QString errString;
     for (const QSslError &err : errs) {
         qWarning() << "PaymentServer::reportSslErrors: " << err;
         errString += err.errorString() + "\n";
     }
     Q_EMIT message(tr("Network request error"), errString,
                    CClientUIInterface::MSG_ERROR);
 }
 
 void PaymentServer::setOptionsModel(OptionsModel *_optionsModel) {
     this->optionsModel = _optionsModel;
 }
 
 void PaymentServer::handlePaymentACK(const QString &paymentACKMsg) {
     // currently we don't further process or store the paymentACK message
     Q_EMIT message(tr("Payment acknowledged"), paymentACKMsg,
                    CClientUIInterface::ICON_INFORMATION |
                        CClientUIInterface::MODAL);
 }
 
 bool PaymentServer::verifyNetwork(
     const payments::PaymentDetails &requestDetails) {
     bool fVerified = requestDetails.network() == Params().NetworkIDString();
     if (!fVerified) {
         qWarning() << QString("PaymentServer::%1: Payment request network "
                               "\"%2\" doesn't match client network \"%3\".")
                           .arg(__func__)
                           .arg(QString::fromStdString(requestDetails.network()))
                           .arg(QString::fromStdString(
                               Params().NetworkIDString()));
     }
     return fVerified;
 }
 
 bool PaymentServer::verifyExpired(
     const payments::PaymentDetails &requestDetails) {
     bool fVerified = (requestDetails.has_expires() &&
                       (int64_t)requestDetails.expires() < GetTime());
     if (fVerified) {
         const QString requestExpires = QString::fromStdString(DateTimeStrFormat(
             "%Y-%m-%d %H:%M:%S", (int64_t)requestDetails.expires()));
         qWarning() << QString(
                           "PaymentServer::%1: Payment request expired \"%2\".")
                           .arg(__func__)
                           .arg(requestExpires);
     }
     return fVerified;
 }
 
 bool PaymentServer::verifySize(qint64 requestSize) {
     bool fVerified = (requestSize <= BIP70_MAX_PAYMENTREQUEST_SIZE);
     if (!fVerified) {
         qWarning() << QString("PaymentServer::%1: Payment request too large "
                               "(%2 bytes, allowed %3 bytes).")
                           .arg(__func__)
                           .arg(requestSize)
                           .arg(BIP70_MAX_PAYMENTREQUEST_SIZE);
     }
     return fVerified;
 }
 
 bool PaymentServer::verifyAmount(const CAmount &requestAmount) {
     bool fVerified = MoneyRange(requestAmount);
     if (!fVerified) {
         qWarning() << QString("PaymentServer::%1: Payment request amount out "
                               "of allowed range (%2, allowed 0 - %3).")
                           .arg(__func__)
                           .arg(requestAmount)
                           .arg(MAX_MONEY);
     }
     return fVerified;
 }
 
 X509_STORE *PaymentServer::getCertStore() {
     return certStore.get();
 }
diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp
index 34b8fe9cb..99218c9ca 100644
--- a/src/qt/receiverequestdialog.cpp
+++ b/src/qt/receiverequestdialog.cpp
@@ -1,193 +1,193 @@
 // Copyright (c) 2011-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.
 
 #include "receiverequestdialog.h"
 #include "ui_receiverequestdialog.h"
 
 #include "bitcoinunits.h"
 #include "guiconstants.h"
 #include "guiutil.h"
 #include "optionsmodel.h"
 #include "walletmodel.h"
 
 #include <QClipboard>
 #include <QDrag>
 #include <QMenu>
 #include <QMimeData>
 #include <QMouseEvent>
 #include <QPixmap>
 #if QT_VERSION < 0x050000
 #include <QUrl>
 #endif
 
 #if defined(HAVE_CONFIG_H)
 #include "config/bitcoin-config.h" /* for USE_QRCODE */
 #endif
 
 #ifdef USE_QRCODE
 #include <qrencode.h>
 #endif
 
 QRImageWidget::QRImageWidget(QWidget *parent) : QLabel(parent), contextMenu(0) {
     contextMenu = new QMenu(this);
     QAction *saveImageAction = new QAction(tr("&Save Image..."), this);
     connect(saveImageAction, SIGNAL(triggered()), this, SLOT(saveImage()));
     contextMenu->addAction(saveImageAction);
     QAction *copyImageAction = new QAction(tr("&Copy Image"), this);
     connect(copyImageAction, SIGNAL(triggered()), this, SLOT(copyImage()));
     contextMenu->addAction(copyImageAction);
 }
 
 QImage QRImageWidget::exportImage() {
     if (!pixmap()) return QImage();
     return pixmap()->toImage();
 }
 
 void QRImageWidget::mousePressEvent(QMouseEvent *event) {
     if (event->button() == Qt::LeftButton && pixmap()) {
         event->accept();
         QMimeData *mimeData = new QMimeData;
         mimeData->setImageData(exportImage());
 
         QDrag *drag = new QDrag(this);
         drag->setMimeData(mimeData);
         drag->exec();
     } else {
         QLabel::mousePressEvent(event);
     }
 }
 
 void QRImageWidget::saveImage() {
     if (!pixmap()) return;
     QString fn = GUIUtil::getSaveFileName(this, tr("Save QR Code"), QString(),
                                           tr("PNG Image (*.png)"), nullptr);
     if (!fn.isEmpty()) {
         exportImage().save(fn);
     }
 }
 
 void QRImageWidget::copyImage() {
     if (!pixmap()) return;
     QApplication::clipboard()->setImage(exportImage());
 }
 
 void QRImageWidget::contextMenuEvent(QContextMenuEvent *event) {
     if (!pixmap()) return;
     contextMenu->exec(event->globalPos());
 }
 
 ReceiveRequestDialog::ReceiveRequestDialog(QWidget *parent)
     : QDialog(parent), ui(new Ui::ReceiveRequestDialog), model(0) {
     ui->setupUi(this);
 
 #ifndef USE_QRCODE
     ui->btnSaveAs->setVisible(false);
     ui->lblQRCode->setVisible(false);
 #endif
 
     connect(ui->btnSaveAs, SIGNAL(clicked()), ui->lblQRCode, SLOT(saveImage()));
 }
 
 ReceiveRequestDialog::~ReceiveRequestDialog() {
     delete ui;
 }
 
 void ReceiveRequestDialog::setModel(OptionsModel *_model) {
     this->model = _model;
 
     if (_model)
         connect(_model, SIGNAL(displayUnitChanged(int)), this, SLOT(update()));
 
     // update the display unit if necessary
     update();
 }
 
 void ReceiveRequestDialog::setInfo(const SendCoinsRecipient &_info) {
     this->info = _info;
     update();
 }
 
 void ReceiveRequestDialog::update() {
     if (!model) return;
     QString target = info.label;
     if (target.isEmpty()) target = info.address;
     setWindowTitle(tr("Request payment to %1").arg(target));
 
     QString uri = GUIUtil::formatBitcoinURI(info);
     ui->btnSaveAs->setEnabled(false);
     QString html;
     html += "<html><font face='verdana, arial, helvetica, sans-serif'>";
     html += "<b>" + tr("Payment information") + "</b><br>";
     html += "<b>" + tr("URI") + "</b>: ";
     html += "<a href=\"" + uri + "\">" + GUIUtil::HtmlEscape(uri) + "</a><br>";
     html += "<b>" + tr("Address") + "</b>: " +
             GUIUtil::HtmlEscape(info.address) + "<br>";
     if (info.amount)
         html += "<b>" + tr("Amount") + "</b>: " +
                 BitcoinUnits::formatHtmlWithUnit(model->getDisplayUnit(),
                                                  info.amount) +
                 "<br>";
     if (!info.label.isEmpty())
         html += "<b>" + tr("Label") + "</b>: " +
                 GUIUtil::HtmlEscape(info.label) + "<br>";
     if (!info.message.isEmpty())
         html += "<b>" + tr("Message") + "</b>: " +
                 GUIUtil::HtmlEscape(info.message) + "<br>";
     ui->outUri->setText(html);
 
 #ifdef USE_QRCODE
     ui->lblQRCode->setText("");
     if (!uri.isEmpty()) {
         // limit URI length
         if (uri.length() > MAX_URI_LENGTH) {
             ui->lblQRCode->setText(tr("Resulting URI too long, try to reduce "
                                       "the text for label / message."));
         } else {
             QRcode *code = QRcode_encodeString(uri.toUtf8().constData(), 0,
                                                QR_ECLEVEL_L, QR_MODE_8, 1);
             if (!code) {
                 ui->lblQRCode->setText(tr("Error encoding URI into QR Code."));
                 return;
             }
             QImage qrImage =
                 QImage(code->width + 8, code->width + 8, QImage::Format_RGB32);
             qrImage.fill(0xffffff);
-            unsigned char *p = code->data;
+            uint8_t *p = code->data;
             for (int y = 0; y < code->width; y++) {
                 for (int x = 0; x < code->width; x++) {
                     qrImage.setPixel(x + 4, y + 4, ((*p & 1) ? 0x0 : 0xffffff));
                     p++;
                 }
             }
             QRcode_free(code);
 
             QImage qrAddrImage =
                 QImage(QR_IMAGE_SIZE, QR_IMAGE_SIZE + 20, QImage::Format_RGB32);
             qrAddrImage.fill(0xffffff);
             QPainter painter(&qrAddrImage);
             painter.drawImage(0, 0,
                               qrImage.scaled(QR_IMAGE_SIZE, QR_IMAGE_SIZE));
             QFont font = GUIUtil::fixedPitchFont();
             font.setPixelSize(12);
             painter.setFont(font);
             QRect paddedRect = qrAddrImage.rect();
             paddedRect.setHeight(QR_IMAGE_SIZE + 12);
             painter.drawText(paddedRect, Qt::AlignBottom | Qt::AlignCenter,
                              info.address);
             painter.end();
 
             ui->lblQRCode->setPixmap(QPixmap::fromImage(qrAddrImage));
             ui->btnSaveAs->setEnabled(true);
         }
     }
 #endif
 }
 
 void ReceiveRequestDialog::on_btnCopyURI_clicked() {
     GUIUtil::setClipboard(GUIUtil::formatBitcoinURI(info));
 }
 
 void ReceiveRequestDialog::on_btnCopyAddress_clicked() {
     GUIUtil::setClipboard(info.address);
 }
diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp
index 2a43f8f72..c16a5adef 100644
--- a/src/qt/signverifymessagedialog.cpp
+++ b/src/qt/signverifymessagedialog.cpp
@@ -1,279 +1,279 @@
 // Copyright (c) 2011-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.
 
 #include "signverifymessagedialog.h"
 #include "ui_signverifymessagedialog.h"
 
 #include "addressbookpage.h"
 #include "guiutil.h"
 #include "platformstyle.h"
 #include "walletmodel.h"
 
 #include "base58.h"
 #include "init.h"
 #include "validation.h" // For strMessageMagic
 #include "wallet/wallet.h"
 
 #include <string>
 #include <vector>
 
 #include <QClipboard>
 
 SignVerifyMessageDialog::SignVerifyMessageDialog(
     const PlatformStyle *_platformStyle, QWidget *parent)
     : QDialog(parent), ui(new Ui::SignVerifyMessageDialog), model(0),
       platformStyle(_platformStyle) {
     ui->setupUi(this);
 
     ui->addressBookButton_SM->setIcon(
         platformStyle->SingleColorIcon(":/icons/address-book"));
     ui->pasteButton_SM->setIcon(
         platformStyle->SingleColorIcon(":/icons/editpaste"));
     ui->copySignatureButton_SM->setIcon(
         platformStyle->SingleColorIcon(":/icons/editcopy"));
     ui->signMessageButton_SM->setIcon(
         platformStyle->SingleColorIcon(":/icons/edit"));
     ui->clearButton_SM->setIcon(
         platformStyle->SingleColorIcon(":/icons/remove"));
     ui->addressBookButton_VM->setIcon(
         platformStyle->SingleColorIcon(":/icons/address-book"));
     ui->verifyMessageButton_VM->setIcon(
         platformStyle->SingleColorIcon(":/icons/transaction_0"));
     ui->clearButton_VM->setIcon(
         platformStyle->SingleColorIcon(":/icons/remove"));
 
 #if QT_VERSION >= 0x040700
     ui->signatureOut_SM->setPlaceholderText(
         tr("Click \"Sign Message\" to generate signature"));
 #endif
 
     GUIUtil::setupAddressWidget(ui->addressIn_SM, this);
     GUIUtil::setupAddressWidget(ui->addressIn_VM, this);
 
     ui->addressIn_SM->installEventFilter(this);
     ui->messageIn_SM->installEventFilter(this);
     ui->signatureOut_SM->installEventFilter(this);
     ui->addressIn_VM->installEventFilter(this);
     ui->messageIn_VM->installEventFilter(this);
     ui->signatureIn_VM->installEventFilter(this);
 
     ui->signatureOut_SM->setFont(GUIUtil::fixedPitchFont());
     ui->signatureIn_VM->setFont(GUIUtil::fixedPitchFont());
 }
 
 SignVerifyMessageDialog::~SignVerifyMessageDialog() {
     delete ui;
 }
 
 void SignVerifyMessageDialog::setModel(WalletModel *_model) {
     this->model = _model;
 }
 
 void SignVerifyMessageDialog::setAddress_SM(const QString &address) {
     ui->addressIn_SM->setText(address);
     ui->messageIn_SM->setFocus();
 }
 
 void SignVerifyMessageDialog::setAddress_VM(const QString &address) {
     ui->addressIn_VM->setText(address);
     ui->messageIn_VM->setFocus();
 }
 
 void SignVerifyMessageDialog::showTab_SM(bool fShow) {
     ui->tabWidget->setCurrentIndex(0);
     if (fShow) this->show();
 }
 
 void SignVerifyMessageDialog::showTab_VM(bool fShow) {
     ui->tabWidget->setCurrentIndex(1);
     if (fShow) this->show();
 }
 
 void SignVerifyMessageDialog::on_addressBookButton_SM_clicked() {
     if (model && model->getAddressTableModel()) {
         AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection,
                             AddressBookPage::ReceivingTab, this);
         dlg.setModel(model->getAddressTableModel());
         if (dlg.exec()) {
             setAddress_SM(dlg.getReturnValue());
         }
     }
 }
 
 void SignVerifyMessageDialog::on_pasteButton_SM_clicked() {
     setAddress_SM(QApplication::clipboard()->text());
 }
 
 void SignVerifyMessageDialog::on_signMessageButton_SM_clicked() {
     if (!model) return;
 
     /* Clear old signature to ensure users don't get confused on error with an
      * old signature displayed */
     ui->signatureOut_SM->clear();
 
     CBitcoinAddress addr(ui->addressIn_SM->text().toStdString());
     if (!addr.IsValid()) {
         ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
         ui->statusLabel_SM->setText(
             tr("The entered address is invalid.") + QString(" ") +
             tr("Please check the address and try again."));
         return;
     }
     CKeyID keyID;
     if (!addr.GetKeyID(keyID)) {
         ui->addressIn_SM->setValid(false);
         ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
         ui->statusLabel_SM->setText(
             tr("The entered address does not refer to a key.") + QString(" ") +
             tr("Please check the address and try again."));
         return;
     }
 
     WalletModel::UnlockContext ctx(model->requestUnlock());
     if (!ctx.isValid()) {
         ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
         ui->statusLabel_SM->setText(tr("Wallet unlock was cancelled."));
         return;
     }
 
     CKey key;
     if (!model->getPrivKey(keyID, key)) {
         ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
         ui->statusLabel_SM->setText(
             tr("Private key for the entered address is not available."));
         return;
     }
 
     CHashWriter ss(SER_GETHASH, 0);
     ss << strMessageMagic;
     ss << ui->messageIn_SM->document()->toPlainText().toStdString();
 
-    std::vector<unsigned char> vchSig;
+    std::vector<uint8_t> vchSig;
     if (!key.SignCompact(ss.GetHash(), vchSig)) {
         ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
         ui->statusLabel_SM->setText(QString("<nobr>") +
                                     tr("Message signing failed.") +
                                     QString("</nobr>"));
         return;
     }
 
     ui->statusLabel_SM->setStyleSheet("QLabel { color: green; }");
     ui->statusLabel_SM->setText(QString("<nobr>") + tr("Message signed.") +
                                 QString("</nobr>"));
 
     ui->signatureOut_SM->setText(
         QString::fromStdString(EncodeBase64(&vchSig[0], vchSig.size())));
 }
 
 void SignVerifyMessageDialog::on_copySignatureButton_SM_clicked() {
     GUIUtil::setClipboard(ui->signatureOut_SM->text());
 }
 
 void SignVerifyMessageDialog::on_clearButton_SM_clicked() {
     ui->addressIn_SM->clear();
     ui->messageIn_SM->clear();
     ui->signatureOut_SM->clear();
     ui->statusLabel_SM->clear();
 
     ui->addressIn_SM->setFocus();
 }
 
 void SignVerifyMessageDialog::on_addressBookButton_VM_clicked() {
     if (model && model->getAddressTableModel()) {
         AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection,
                             AddressBookPage::SendingTab, this);
         dlg.setModel(model->getAddressTableModel());
         if (dlg.exec()) {
             setAddress_VM(dlg.getReturnValue());
         }
     }
 }
 
 void SignVerifyMessageDialog::on_verifyMessageButton_VM_clicked() {
     CBitcoinAddress addr(ui->addressIn_VM->text().toStdString());
     if (!addr.IsValid()) {
         ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
         ui->statusLabel_VM->setText(
             tr("The entered address is invalid.") + QString(" ") +
             tr("Please check the address and try again."));
         return;
     }
     CKeyID keyID;
     if (!addr.GetKeyID(keyID)) {
         ui->addressIn_VM->setValid(false);
         ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
         ui->statusLabel_VM->setText(
             tr("The entered address does not refer to a key.") + QString(" ") +
             tr("Please check the address and try again."));
         return;
     }
 
     bool fInvalid = false;
-    std::vector<unsigned char> vchSig = DecodeBase64(
+    std::vector<uint8_t> vchSig = DecodeBase64(
         ui->signatureIn_VM->text().toStdString().c_str(), &fInvalid);
 
     if (fInvalid) {
         ui->signatureIn_VM->setValid(false);
         ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
         ui->statusLabel_VM->setText(
             tr("The signature could not be decoded.") + QString(" ") +
             tr("Please check the signature and try again."));
         return;
     }
 
     CHashWriter ss(SER_GETHASH, 0);
     ss << strMessageMagic;
     ss << ui->messageIn_VM->document()->toPlainText().toStdString();
 
     CPubKey pubkey;
     if (!pubkey.RecoverCompact(ss.GetHash(), vchSig)) {
         ui->signatureIn_VM->setValid(false);
         ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
         ui->statusLabel_VM->setText(
             tr("The signature did not match the message digest.") +
             QString(" ") + tr("Please check the signature and try again."));
         return;
     }
 
     if (!(CBitcoinAddress(pubkey.GetID()) == addr)) {
         ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
         ui->statusLabel_VM->setText(QString("<nobr>") +
                                     tr("Message verification failed.") +
                                     QString("</nobr>"));
         return;
     }
 
     ui->statusLabel_VM->setStyleSheet("QLabel { color: green; }");
     ui->statusLabel_VM->setText(QString("<nobr>") + tr("Message verified.") +
                                 QString("</nobr>"));
 }
 
 void SignVerifyMessageDialog::on_clearButton_VM_clicked() {
     ui->addressIn_VM->clear();
     ui->signatureIn_VM->clear();
     ui->messageIn_VM->clear();
     ui->statusLabel_VM->clear();
 
     ui->addressIn_VM->setFocus();
 }
 
 bool SignVerifyMessageDialog::eventFilter(QObject *object, QEvent *event) {
     if (event->type() == QEvent::MouseButtonPress ||
         event->type() == QEvent::FocusIn) {
         if (ui->tabWidget->currentIndex() == 0) {
             /* Clear status message on focus change */
             ui->statusLabel_SM->clear();
 
             /* Select generated signature */
             if (object == ui->signatureOut_SM) {
                 ui->signatureOut_SM->selectAll();
                 return true;
             }
         } else if (ui->tabWidget->currentIndex() == 1) {
             /* Clear status message on focus change */
             ui->statusLabel_VM->clear();
         }
     }
     return QDialog::eventFilter(object, event);
 }
diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp
index 2f337f947..c50933b6f 100644
--- a/src/qt/test/paymentservertests.cpp
+++ b/src/qt/test/paymentservertests.cpp
@@ -1,219 +1,219 @@
 // Copyright (c) 2009-2015 The Bitcoin Core developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #include "paymentservertests.h"
 
 #include "optionsmodel.h"
 #include "paymentrequestdata.h"
 
 #include "amount.h"
 #include "random.h"
 #include "script/script.h"
 #include "script/standard.h"
 #include "util.h"
 #include "utilstrencodings.h"
 
 #include <openssl/x509.h>
 #include <openssl/x509_vfy.h>
 
 #include <QFileOpenEvent>
 #include <QTemporaryFile>
 
 X509 *parse_b64der_cert(const char *cert_data) {
-    std::vector<unsigned char> data = DecodeBase64(cert_data);
+    std::vector<uint8_t> data = DecodeBase64(cert_data);
     assert(data.size() > 0);
-    const unsigned char *dptr = &data[0];
+    const uint8_t *dptr = &data[0];
     X509 *cert = d2i_X509(nullptr, &dptr, data.size());
     assert(cert);
     return cert;
 }
 
 //
 // Test payment request handling
 //
 
 static SendCoinsRecipient handleRequest(PaymentServer *server,
-                                        std::vector<unsigned char> &data) {
+                                        std::vector<uint8_t> &data) {
     RecipientCatcher sigCatcher;
     QObject::connect(server, SIGNAL(receivedPaymentRequest(SendCoinsRecipient)),
                      &sigCatcher, SLOT(getRecipient(SendCoinsRecipient)));
 
     // Write data to a temp file:
     QTemporaryFile f;
     f.open();
     f.write((const char *)&data[0], data.size());
     f.close();
 
     // Create a QObject, install event filter from PaymentServer and send a file
     // open event to the object
     QObject object;
     object.installEventFilter(server);
     QFileOpenEvent event(f.fileName());
     // If sending the event fails, this will cause sigCatcher to be empty, which
     // will lead to a test failure anyway.
     QCoreApplication::sendEvent(&object, &event);
 
     QObject::disconnect(server,
                         SIGNAL(receivedPaymentRequest(SendCoinsRecipient)),
                         &sigCatcher, SLOT(getRecipient(SendCoinsRecipient)));
 
     // Return results from sigCatcher
     return sigCatcher.recipient;
 }
 
 void PaymentServerTests::paymentServerTests() {
     SelectParams(CBaseChainParams::MAIN);
     OptionsModel optionsModel;
     PaymentServer *server = new PaymentServer(nullptr, false);
     X509_STORE *caStore = X509_STORE_new();
     X509_STORE_add_cert(caStore, parse_b64der_cert(caCert1_BASE64));
     PaymentServer::LoadRootCAs(caStore);
     server->setOptionsModel(&optionsModel);
     server->uiReady();
 
-    std::vector<unsigned char> data;
+    std::vector<uint8_t> data;
     SendCoinsRecipient r;
     QString merchant;
 
     // Now feed PaymentRequests to server, and observe signals it produces
 
     // This payment request validates directly against the caCert1 certificate
     // authority:
     data = DecodeBase64(paymentrequest1_cert1_BASE64);
     r = handleRequest(server, data);
     r.paymentRequest.getMerchant(caStore, merchant);
     QCOMPARE(merchant, QString("testmerchant.org"));
 
     // Signed, but expired, merchant cert in the request:
     data = DecodeBase64(paymentrequest2_cert1_BASE64);
     r = handleRequest(server, data);
     r.paymentRequest.getMerchant(caStore, merchant);
     QCOMPARE(merchant, QString(""));
 
     // 10-long certificate chain, all intermediates valid:
     data = DecodeBase64(paymentrequest3_cert1_BASE64);
     r = handleRequest(server, data);
     r.paymentRequest.getMerchant(caStore, merchant);
     QCOMPARE(merchant, QString("testmerchant8.org"));
 
     // Long certificate chain, with an expired certificate in the middle:
     data = DecodeBase64(paymentrequest4_cert1_BASE64);
     r = handleRequest(server, data);
     r.paymentRequest.getMerchant(caStore, merchant);
     QCOMPARE(merchant, QString(""));
 
     // Validly signed, but by a CA not in our root CA list:
     data = DecodeBase64(paymentrequest5_cert1_BASE64);
     r = handleRequest(server, data);
     r.paymentRequest.getMerchant(caStore, merchant);
     QCOMPARE(merchant, QString(""));
 
     // Try again with no root CA's, verifiedMerchant should be empty:
     caStore = X509_STORE_new();
     PaymentServer::LoadRootCAs(caStore);
     data = DecodeBase64(paymentrequest1_cert1_BASE64);
     r = handleRequest(server, data);
     r.paymentRequest.getMerchant(caStore, merchant);
     QCOMPARE(merchant, QString(""));
 
     // Load second root certificate
     caStore = X509_STORE_new();
     X509_STORE_add_cert(caStore, parse_b64der_cert(caCert2_BASE64));
     PaymentServer::LoadRootCAs(caStore);
 
     QByteArray byteArray;
 
     // For the tests below we just need the payment request data from
     // paymentrequestdata.h parsed + stored in r.paymentRequest.
     //
     // These tests require us to bypass the following normal client execution
     // flow shown below to be able to explicitly just trigger a certain
     // condition!
     //
     // handleRequest()
     // -> PaymentServer::eventFilter()
     //   -> PaymentServer::handleURIOrFile()
     //     -> PaymentServer::readPaymentRequestFromFile()
     //       -> PaymentServer::processPaymentRequest()
 
     // Contains a testnet paytoaddress, so payment request network doesn't match
     // client network:
     data = DecodeBase64(paymentrequest1_cert2_BASE64);
     byteArray = QByteArray((const char *)&data[0], data.size());
     r.paymentRequest.parse(byteArray);
     // Ensure the request is initialized, because network "main" is default,
     // even for uninizialized payment requests and that will fail our test here.
     QVERIFY(r.paymentRequest.IsInitialized());
     QCOMPARE(PaymentServer::verifyNetwork(r.paymentRequest.getDetails()),
              false);
 
     // Expired payment request (expires is set to 1 = 1970-01-01 00:00:01):
     data = DecodeBase64(paymentrequest2_cert2_BASE64);
     byteArray = QByteArray((const char *)&data[0], data.size());
     r.paymentRequest.parse(byteArray);
     // Ensure the request is initialized
     QVERIFY(r.paymentRequest.IsInitialized());
     // compares 1 < GetTime() == false (treated as expired payment request)
     QCOMPARE(PaymentServer::verifyExpired(r.paymentRequest.getDetails()), true);
 
     // Unexpired payment request (expires is set to 0x7FFFFFFFFFFFFFFF = max.
     // int64_t):
     // 9223372036854775807 (uint64), 9223372036854775807 (int64_t) and -1
     // (int32_t)
     // -1 is 1969-12-31 23:59:59 (for a 32 bit time values)
     data = DecodeBase64(paymentrequest3_cert2_BASE64);
     byteArray = QByteArray((const char *)&data[0], data.size());
     r.paymentRequest.parse(byteArray);
     // Ensure the request is initialized
     QVERIFY(r.paymentRequest.IsInitialized());
     // compares 9223372036854775807 < GetTime() == false (treated as unexpired
     // payment request)
     QCOMPARE(PaymentServer::verifyExpired(r.paymentRequest.getDetails()),
              false);
 
     // Unexpired payment request (expires is set to 0x8000000000000000 > max.
     // int64_t, allowed uint64):
     // 9223372036854775808 (uint64), -9223372036854775808 (int64_t) and 0
     // (int32_t)
     // 0 is 1970-01-01 00:00:00 (for a 32 bit time values)
     data = DecodeBase64(paymentrequest4_cert2_BASE64);
     byteArray = QByteArray((const char *)&data[0], data.size());
     r.paymentRequest.parse(byteArray);
     // Ensure the request is initialized
     QVERIFY(r.paymentRequest.IsInitialized());
     // compares -9223372036854775808 < GetTime() == true (treated as expired
     // payment request)
     QCOMPARE(PaymentServer::verifyExpired(r.paymentRequest.getDetails()), true);
 
     // Test BIP70 DoS protection:
-    unsigned char randData[BIP70_MAX_PAYMENTREQUEST_SIZE + 1];
+    uint8_t randData[BIP70_MAX_PAYMENTREQUEST_SIZE + 1];
     GetRandBytes(randData, sizeof(randData));
     // Write data to a temp file:
     QTemporaryFile tempFile;
     tempFile.open();
     tempFile.write((const char *)randData, sizeof(randData));
     tempFile.close();
     // compares 50001 <= BIP70_MAX_PAYMENTREQUEST_SIZE == false
     QCOMPARE(PaymentServer::verifySize(tempFile.size()), false);
 
     // Payment request with amount overflow (amount is set to 21000001 BCC):
     data = DecodeBase64(paymentrequest5_cert2_BASE64);
     byteArray = QByteArray((const char *)&data[0], data.size());
     r.paymentRequest.parse(byteArray);
     // Ensure the request is initialized
     QVERIFY(r.paymentRequest.IsInitialized());
     // Extract address and amount from the request
     QList<std::pair<CScript, CAmount>> sendingTos = r.paymentRequest.getPayTo();
     for (const std::pair<CScript, CAmount> &sendingTo : sendingTos) {
         CTxDestination dest;
         if (ExtractDestination(sendingTo.first, dest))
             QCOMPARE(PaymentServer::verifyAmount(sendingTo.second), false);
     }
 
     delete server;
 }
 
 void RecipientCatcher::getRecipient(SendCoinsRecipient r) {
     recipient = r;
 }
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index ddf3737c4..2ad65c500 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -1,683 +1,682 @@
 // Copyright (c) 2011-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.
 
 #include "walletmodel.h"
 
 #include "addresstablemodel.h"
 #include "consensus/validation.h"
 #include "guiconstants.h"
 #include "guiutil.h"
 #include "paymentserver.h"
 #include "recentrequeststablemodel.h"
 #include "transactiontablemodel.h"
 
 #include "base58.h"
 #include "keystore.h"
 #include "net.h" // for g_connman
 #include "sync.h"
 #include "ui_interface.h"
 #include "util.h" // for GetBoolArg
 #include "validation.h"
 #include "wallet/wallet.h"
 #include "wallet/walletdb.h" // for BackupWallet
 
 #include <cstdint>
 
 #include <QDebug>
 #include <QSet>
 #include <QTimer>
 
 WalletModel::WalletModel(const PlatformStyle *platformStyle, CWallet *_wallet,
                          OptionsModel *_optionsModel, QObject *parent)
     : QObject(parent), wallet(_wallet), optionsModel(_optionsModel),
       addressTableModel(0), transactionTableModel(0),
       recentRequestsTableModel(0), cachedBalance(0),
       cachedUnconfirmedBalance(0), cachedImmatureBalance(0),
       cachedEncryptionStatus(Unencrypted), cachedNumBlocks(0) {
     fHaveWatchOnly = wallet->HaveWatchOnly();
     fForceCheckBalanceChanged = false;
 
     addressTableModel = new AddressTableModel(wallet, this);
     transactionTableModel =
         new TransactionTableModel(platformStyle, wallet, this);
     recentRequestsTableModel = new RecentRequestsTableModel(wallet, this);
 
     // This timer will be fired repeatedly to update the balance
     pollTimer = new QTimer(this);
     connect(pollTimer, SIGNAL(timeout()), this, SLOT(pollBalanceChanged()));
     pollTimer->start(MODEL_UPDATE_DELAY);
 
     subscribeToCoreSignals();
 }
 
 WalletModel::~WalletModel() {
     unsubscribeFromCoreSignals();
 }
 
 CAmount WalletModel::getBalance(const CCoinControl *coinControl) const {
     if (coinControl) {
         CAmount nBalance = 0;
         std::vector<COutput> vCoins;
         wallet->AvailableCoins(vCoins, true, coinControl);
         for (const COutput &out : vCoins) {
             if (out.fSpendable) nBalance += out.tx->tx->vout[out.i].nValue;
         }
 
         return nBalance;
     }
 
     return wallet->GetBalance();
 }
 
 CAmount WalletModel::getUnconfirmedBalance() const {
     return wallet->GetUnconfirmedBalance();
 }
 
 CAmount WalletModel::getImmatureBalance() const {
     return wallet->GetImmatureBalance();
 }
 
 bool WalletModel::haveWatchOnly() const {
     return fHaveWatchOnly;
 }
 
 CAmount WalletModel::getWatchBalance() const {
     return wallet->GetWatchOnlyBalance();
 }
 
 CAmount WalletModel::getWatchUnconfirmedBalance() const {
     return wallet->GetUnconfirmedWatchOnlyBalance();
 }
 
 CAmount WalletModel::getWatchImmatureBalance() const {
     return wallet->GetImmatureWatchOnlyBalance();
 }
 
 void WalletModel::updateStatus() {
     EncryptionStatus newEncryptionStatus = getEncryptionStatus();
 
     if (cachedEncryptionStatus != newEncryptionStatus)
         Q_EMIT encryptionStatusChanged(newEncryptionStatus);
 }
 
 void WalletModel::pollBalanceChanged() {
     // Get required locks upfront. This avoids the GUI from getting stuck on
     // periodical polls if the core is holding the locks for a longer time - for
     // example, during a wallet rescan.
     TRY_LOCK(cs_main, lockMain);
     if (!lockMain) return;
     TRY_LOCK(wallet->cs_wallet, lockWallet);
     if (!lockWallet) return;
 
     if (fForceCheckBalanceChanged || chainActive.Height() != cachedNumBlocks) {
         fForceCheckBalanceChanged = false;
 
         // Balance and number of transactions might have changed
         cachedNumBlocks = chainActive.Height();
 
         checkBalanceChanged();
         if (transactionTableModel) transactionTableModel->updateConfirmations();
     }
 }
 
 void WalletModel::checkBalanceChanged() {
     CAmount newBalance = getBalance();
     CAmount newUnconfirmedBalance = getUnconfirmedBalance();
     CAmount newImmatureBalance = getImmatureBalance();
     CAmount newWatchOnlyBalance = 0;
     CAmount newWatchUnconfBalance = 0;
     CAmount newWatchImmatureBalance = 0;
     if (haveWatchOnly()) {
         newWatchOnlyBalance = getWatchBalance();
         newWatchUnconfBalance = getWatchUnconfirmedBalance();
         newWatchImmatureBalance = getWatchImmatureBalance();
     }
 
     if (cachedBalance != newBalance ||
         cachedUnconfirmedBalance != newUnconfirmedBalance ||
         cachedImmatureBalance != newImmatureBalance ||
         cachedWatchOnlyBalance != newWatchOnlyBalance ||
         cachedWatchUnconfBalance != newWatchUnconfBalance ||
         cachedWatchImmatureBalance != newWatchImmatureBalance) {
         cachedBalance = newBalance;
         cachedUnconfirmedBalance = newUnconfirmedBalance;
         cachedImmatureBalance = newImmatureBalance;
         cachedWatchOnlyBalance = newWatchOnlyBalance;
         cachedWatchUnconfBalance = newWatchUnconfBalance;
         cachedWatchImmatureBalance = newWatchImmatureBalance;
         Q_EMIT balanceChanged(newBalance, newUnconfirmedBalance,
                               newImmatureBalance, newWatchOnlyBalance,
                               newWatchUnconfBalance, newWatchImmatureBalance);
     }
 }
 
 void WalletModel::updateTransaction() {
     // Balance and number of transactions might have changed
     fForceCheckBalanceChanged = true;
 }
 
 void WalletModel::updateAddressBook(const QString &address,
                                     const QString &label, bool isMine,
                                     const QString &purpose, int status) {
     if (addressTableModel)
         addressTableModel->updateEntry(address, label, isMine, purpose, status);
 }
 
 void WalletModel::updateWatchOnlyFlag(bool fHaveWatchonly) {
     fHaveWatchOnly = fHaveWatchonly;
     Q_EMIT notifyWatchonlyChanged(fHaveWatchonly);
 }
 
 bool WalletModel::validateAddress(const QString &address) {
     CBitcoinAddress addressParsed(address.toStdString());
     return addressParsed.IsValid();
 }
 
 WalletModel::SendCoinsReturn
 WalletModel::prepareTransaction(WalletModelTransaction &transaction,
                                 const CCoinControl *coinControl) {
     CAmount total = 0;
     bool fSubtractFeeFromAmount = false;
     QList<SendCoinsRecipient> recipients = transaction.getRecipients();
     std::vector<CRecipient> vecSend;
 
     if (recipients.empty()) {
         return OK;
     }
 
     // Used to detect duplicates
     QSet<QString> setAddress;
     int nAddresses = 0;
 
     // Pre-check input data for validity
     for (const SendCoinsRecipient &rcp : recipients) {
         if (rcp.fSubtractFeeFromAmount) fSubtractFeeFromAmount = true;
 
         // PaymentRequest...
         if (rcp.paymentRequest.IsInitialized()) {
             CAmount subtotal = 0;
             const payments::PaymentDetails &details =
                 rcp.paymentRequest.getDetails();
             for (int i = 0; i < details.outputs_size(); i++) {
                 const payments::Output &out = details.outputs(i);
                 if (out.amount() <= 0) continue;
                 subtotal += out.amount();
-                const unsigned char *scriptStr =
-                    (const unsigned char *)out.script().data();
+                const uint8_t *scriptStr = (const uint8_t *)out.script().data();
                 CScript scriptPubKey(scriptStr,
                                      scriptStr + out.script().size());
                 CAmount nAmount = out.amount();
                 CRecipient recipient = {scriptPubKey, nAmount,
                                         rcp.fSubtractFeeFromAmount};
                 vecSend.push_back(recipient);
             }
             if (subtotal <= 0) {
                 return InvalidAmount;
             }
             total += subtotal;
         } else { // User-entered bitcoin address / amount:
             if (!validateAddress(rcp.address)) {
                 return InvalidAddress;
             }
             if (rcp.amount <= 0) {
                 return InvalidAmount;
             }
             setAddress.insert(rcp.address);
             ++nAddresses;
 
             CScript scriptPubKey = GetScriptForDestination(
                 CBitcoinAddress(rcp.address.toStdString()).Get());
             CRecipient recipient = {scriptPubKey, rcp.amount,
                                     rcp.fSubtractFeeFromAmount};
             vecSend.push_back(recipient);
 
             total += rcp.amount;
         }
     }
     if (setAddress.size() != nAddresses) {
         return DuplicateAddress;
     }
 
     CAmount nBalance = getBalance(coinControl);
 
     if (total > nBalance) {
         return AmountExceedsBalance;
     }
 
     {
         LOCK2(cs_main, wallet->cs_wallet);
 
         transaction.newPossibleKeyChange(wallet);
 
         CAmount nFeeRequired = 0;
         int nChangePosRet = -1;
         std::string strFailReason;
 
         CWalletTx *newTx = transaction.getTransaction();
         CReserveKey *keyChange = transaction.getPossibleKeyChange();
         bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange,
                                                   nFeeRequired, nChangePosRet,
                                                   strFailReason, coinControl);
         transaction.setTransactionFee(nFeeRequired);
         if (fSubtractFeeFromAmount && fCreated)
             transaction.reassignAmounts(nChangePosRet);
 
         if (!fCreated) {
             if (!fSubtractFeeFromAmount && (total + nFeeRequired) > nBalance) {
                 return SendCoinsReturn(AmountWithFeeExceedsBalance);
             }
             Q_EMIT message(tr("Send Coins"),
                            QString::fromStdString(strFailReason),
                            CClientUIInterface::MSG_ERROR);
             return TransactionCreationFailed;
         }
 
         // reject absurdly high fee. (This can never happen because the wallet
         // caps the fee at maxTxFee. This merely serves as a belt-and-suspenders
         // check)
         if (nFeeRequired > maxTxFee) return AbsurdFee;
     }
 
     return SendCoinsReturn(OK);
 }
 
 WalletModel::SendCoinsReturn
 WalletModel::sendCoins(WalletModelTransaction &transaction) {
     /* store serialized transaction */
     QByteArray transaction_array;
 
     {
         LOCK2(cs_main, wallet->cs_wallet);
         CWalletTx *newTx = transaction.getTransaction();
 
         for (const SendCoinsRecipient &rcp : transaction.getRecipients()) {
             if (rcp.paymentRequest.IsInitialized()) {
                 // Make sure any payment requests involved are still valid.
                 if (PaymentServer::verifyExpired(
                         rcp.paymentRequest.getDetails())) {
                     return PaymentRequestExpired;
                 }
 
                 // Store PaymentRequests in wtx.vOrderForm in wallet.
                 std::string key("PaymentRequest");
                 std::string value;
                 rcp.paymentRequest.SerializeToString(&value);
                 newTx->vOrderForm.push_back(make_pair(key, value));
             } else if (!rcp.message.isEmpty()) {
                 // Message from normal bitcoin:URI
                 // (bitcoin:123...?message=example)
                 newTx->vOrderForm.push_back(
                     make_pair("Message", rcp.message.toStdString()));
             }
         }
 
         CReserveKey *keyChange = transaction.getPossibleKeyChange();
         CValidationState state;
         if (!wallet->CommitTransaction(*newTx, *keyChange, g_connman.get(),
                                        state))
             return SendCoinsReturn(
                 TransactionCommitFailed,
                 QString::fromStdString(state.GetRejectReason()));
 
         CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
         ssTx << *newTx->tx;
         transaction_array.append(&(ssTx[0]), ssTx.size());
     }
 
     // Add addresses / update labels that we've sent to to the address book, and
     // emit coinsSent signal for each recipient
     for (const SendCoinsRecipient &rcp : transaction.getRecipients()) {
         // Don't touch the address book when we have a payment request
         if (!rcp.paymentRequest.IsInitialized()) {
             std::string strAddress = rcp.address.toStdString();
             CTxDestination dest = CBitcoinAddress(strAddress).Get();
             std::string strLabel = rcp.label.toStdString();
             {
                 LOCK(wallet->cs_wallet);
 
                 std::map<CTxDestination, CAddressBookData>::iterator mi =
                     wallet->mapAddressBook.find(dest);
 
                 // Check if we have a new address or an updated label
                 if (mi == wallet->mapAddressBook.end()) {
                     wallet->SetAddressBook(dest, strLabel, "send");
                 } else if (mi->second.name != strLabel) {
                     // "" means don't change purpose
                     wallet->SetAddressBook(dest, strLabel, "");
                 }
             }
         }
         Q_EMIT coinsSent(wallet, rcp, transaction_array);
     }
 
     // update balance immediately, otherwise there could be a short noticeable
     // delay until pollBalanceChanged hits
     checkBalanceChanged();
 
     return SendCoinsReturn(OK);
 }
 
 OptionsModel *WalletModel::getOptionsModel() {
     return optionsModel;
 }
 
 AddressTableModel *WalletModel::getAddressTableModel() {
     return addressTableModel;
 }
 
 TransactionTableModel *WalletModel::getTransactionTableModel() {
     return transactionTableModel;
 }
 
 RecentRequestsTableModel *WalletModel::getRecentRequestsTableModel() {
     return recentRequestsTableModel;
 }
 
 WalletModel::EncryptionStatus WalletModel::getEncryptionStatus() const {
     if (!wallet->IsCrypted()) {
         return Unencrypted;
     } else if (wallet->IsLocked()) {
         return Locked;
     } else {
         return Unlocked;
     }
 }
 
 bool WalletModel::setWalletEncrypted(bool encrypted,
                                      const SecureString &passphrase) {
     if (encrypted) {
         // Encrypt
         return wallet->EncryptWallet(passphrase);
     } else {
         // Decrypt -- TODO; not supported yet
         return false;
     }
 }
 
 bool WalletModel::setWalletLocked(bool locked, const SecureString &passPhrase) {
     if (locked) {
         // Lock
         return wallet->Lock();
     } else {
         // Unlock
         return wallet->Unlock(passPhrase);
     }
 }
 
 bool WalletModel::changePassphrase(const SecureString &oldPass,
                                    const SecureString &newPass) {
     bool retval;
     {
         LOCK(wallet->cs_wallet);
         // Make sure wallet is locked before attempting pass change
         wallet->Lock();
         retval = wallet->ChangeWalletPassphrase(oldPass, newPass);
     }
     return retval;
 }
 
 bool WalletModel::backupWallet(const QString &filename) {
     return wallet->BackupWallet(filename.toLocal8Bit().data());
 }
 
 // Handlers for core signals
 static void NotifyKeyStoreStatusChanged(WalletModel *walletmodel,
                                         CCryptoKeyStore *wallet) {
     qDebug() << "NotifyKeyStoreStatusChanged";
     QMetaObject::invokeMethod(walletmodel, "updateStatus",
                               Qt::QueuedConnection);
 }
 
 static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet,
                                      const CTxDestination &address,
                                      const std::string &label, bool isMine,
                                      const std::string &purpose,
                                      ChangeType status) {
     QString strAddress =
         QString::fromStdString(CBitcoinAddress(address).ToString());
     QString strLabel = QString::fromStdString(label);
     QString strPurpose = QString::fromStdString(purpose);
 
     qDebug() << "NotifyAddressBookChanged: " + strAddress + " " + strLabel +
                     " isMine=" + QString::number(isMine) + " purpose=" +
                     strPurpose + " status=" + QString::number(status);
     QMetaObject::invokeMethod(walletmodel, "updateAddressBook",
                               Qt::QueuedConnection, Q_ARG(QString, strAddress),
                               Q_ARG(QString, strLabel), Q_ARG(bool, isMine),
                               Q_ARG(QString, strPurpose), Q_ARG(int, status));
 }
 
 static void NotifyTransactionChanged(WalletModel *walletmodel, CWallet *wallet,
                                      const uint256 &hash, ChangeType status) {
     Q_UNUSED(wallet);
     Q_UNUSED(hash);
     Q_UNUSED(status);
     QMetaObject::invokeMethod(walletmodel, "updateTransaction",
                               Qt::QueuedConnection);
 }
 
 static void ShowProgress(WalletModel *walletmodel, const std::string &title,
                          int nProgress) {
     // emits signal "showProgress"
     QMetaObject::invokeMethod(walletmodel, "showProgress", Qt::QueuedConnection,
                               Q_ARG(QString, QString::fromStdString(title)),
                               Q_ARG(int, nProgress));
 }
 
 static void NotifyWatchonlyChanged(WalletModel *walletmodel,
                                    bool fHaveWatchonly) {
     QMetaObject::invokeMethod(walletmodel, "updateWatchOnlyFlag",
                               Qt::QueuedConnection,
                               Q_ARG(bool, fHaveWatchonly));
 }
 
 void WalletModel::subscribeToCoreSignals() {
     // Connect signals to wallet
     wallet->NotifyStatusChanged.connect(
         boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
     wallet->NotifyAddressBookChanged.connect(
         boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5, _6));
     wallet->NotifyTransactionChanged.connect(
         boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
     wallet->ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
     wallet->NotifyWatchonlyChanged.connect(
         boost::bind(NotifyWatchonlyChanged, this, _1));
 }
 
 void WalletModel::unsubscribeFromCoreSignals() {
     // Disconnect signals from wallet
     wallet->NotifyStatusChanged.disconnect(
         boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
     wallet->NotifyAddressBookChanged.disconnect(
         boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5, _6));
     wallet->NotifyTransactionChanged.disconnect(
         boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
     wallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
     wallet->NotifyWatchonlyChanged.disconnect(
         boost::bind(NotifyWatchonlyChanged, this, _1));
 }
 
 // WalletModel::UnlockContext implementation
 WalletModel::UnlockContext WalletModel::requestUnlock() {
     bool was_locked = getEncryptionStatus() == Locked;
     if (was_locked) {
         // Request UI to unlock wallet
         Q_EMIT requireUnlock();
     }
     // If wallet is still locked, unlock was failed or cancelled, mark context
     // as invalid
     bool valid = getEncryptionStatus() != Locked;
 
     return UnlockContext(this, valid, was_locked);
 }
 
 WalletModel::UnlockContext::UnlockContext(WalletModel *_wallet, bool _valid,
                                           bool _relock)
     : wallet(_wallet), valid(_valid), relock(_relock) {}
 
 WalletModel::UnlockContext::~UnlockContext() {
     if (valid && relock) {
         wallet->setWalletLocked(true);
     }
 }
 
 void WalletModel::UnlockContext::CopyFrom(const UnlockContext &rhs) {
     // Transfer context; old object no longer relocks wallet
     *this = rhs;
     rhs.relock = false;
 }
 
 bool WalletModel::getPubKey(const CKeyID &address,
                             CPubKey &vchPubKeyOut) const {
     return wallet->GetPubKey(address, vchPubKeyOut);
 }
 
 bool WalletModel::havePrivKey(const CKeyID &address) const {
     return wallet->HaveKey(address);
 }
 
 bool WalletModel::getPrivKey(const CKeyID &address, CKey &vchPrivKeyOut) const {
     return wallet->GetKey(address, vchPrivKeyOut);
 }
 
 // returns a list of COutputs from COutPoints
 void WalletModel::getOutputs(const std::vector<COutPoint> &vOutpoints,
                              std::vector<COutput> &vOutputs) {
     LOCK2(cs_main, wallet->cs_wallet);
     for (const COutPoint &outpoint : vOutpoints) {
         if (!wallet->mapWallet.count(outpoint.hash)) continue;
         int nDepth = wallet->mapWallet[outpoint.hash].GetDepthInMainChain();
         if (nDepth < 0) continue;
         COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, nDepth, true,
                     true);
         vOutputs.push_back(out);
     }
 }
 
 bool WalletModel::isSpent(const COutPoint &outpoint) const {
     LOCK2(cs_main, wallet->cs_wallet);
     return wallet->IsSpent(outpoint.hash, outpoint.n);
 }
 
 // AvailableCoins + LockedCoins grouped by wallet address (put change in one
 // group with wallet address)
 void WalletModel::listCoins(
     std::map<QString, std::vector<COutput>> &mapCoins) const {
     std::vector<COutput> vCoins;
     wallet->AvailableCoins(vCoins);
 
     // ListLockedCoins, mapWallet
     LOCK2(cs_main, wallet->cs_wallet);
     std::vector<COutPoint> vLockedCoins;
     wallet->ListLockedCoins(vLockedCoins);
 
     // add locked coins
     for (const COutPoint &outpoint : vLockedCoins) {
         if (!wallet->mapWallet.count(outpoint.hash)) continue;
         int nDepth = wallet->mapWallet[outpoint.hash].GetDepthInMainChain();
         if (nDepth < 0) continue;
         COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, nDepth, true,
                     true);
         if (outpoint.n < out.tx->tx->vout.size() &&
             wallet->IsMine(out.tx->tx->vout[outpoint.n]) == ISMINE_SPENDABLE)
             vCoins.push_back(out);
     }
 
     for (const COutput &out : vCoins) {
         COutput cout = out;
 
         while (wallet->IsChange(cout.tx->tx->vout[cout.i]) &&
                cout.tx->tx->vin.size() > 0 &&
                wallet->IsMine(cout.tx->tx->vin[0])) {
             if (!wallet->mapWallet.count(cout.tx->tx->vin[0].prevout.hash))
                 break;
             cout = COutput(&wallet->mapWallet[cout.tx->tx->vin[0].prevout.hash],
                            cout.tx->tx->vin[0].prevout.n, 0, true, true);
         }
 
         CTxDestination address;
         if (!out.fSpendable ||
             !ExtractDestination(cout.tx->tx->vout[cout.i].scriptPubKey,
                                 address))
             continue;
         mapCoins[QString::fromStdString(CBitcoinAddress(address).ToString())]
             .push_back(out);
     }
 }
 
 bool WalletModel::isLockedCoin(uint256 hash, unsigned int n) const {
     LOCK2(cs_main, wallet->cs_wallet);
     return wallet->IsLockedCoin(hash, n);
 }
 
 void WalletModel::lockCoin(COutPoint &output) {
     LOCK2(cs_main, wallet->cs_wallet);
     wallet->LockCoin(output);
 }
 
 void WalletModel::unlockCoin(COutPoint &output) {
     LOCK2(cs_main, wallet->cs_wallet);
     wallet->UnlockCoin(output);
 }
 
 void WalletModel::listLockedCoins(std::vector<COutPoint> &vOutpts) {
     LOCK2(cs_main, wallet->cs_wallet);
     wallet->ListLockedCoins(vOutpts);
 }
 
 void WalletModel::loadReceiveRequests(
     std::vector<std::string> &vReceiveRequests) {
     LOCK(wallet->cs_wallet);
     for (const std::pair<CTxDestination, CAddressBookData> &item :
          wallet->mapAddressBook) {
         for (const std::pair<std::string, std::string> &item2 :
              item.second.destdata)
             if (item2.first.size() > 2 &&
                 item2.first.substr(0, 2) == "rr") // receive request
                 vReceiveRequests.push_back(item2.second);
     }
 }
 
 bool WalletModel::saveReceiveRequest(const std::string &sAddress,
                                      const int64_t nId,
                                      const std::string &sRequest) {
     CTxDestination dest = CBitcoinAddress(sAddress).Get();
 
     std::stringstream ss;
     ss << nId;
     // "rr" prefix = "receive request" in destdata
     std::string key = "rr" + ss.str();
 
     LOCK(wallet->cs_wallet);
     if (sRequest.empty())
         return wallet->EraseDestData(dest, key);
     else
         return wallet->AddDestData(dest, key, sRequest);
 }
 
 bool WalletModel::transactionCanBeAbandoned(uint256 hash) const {
     LOCK2(cs_main, wallet->cs_wallet);
     const CWalletTx *wtx = wallet->GetWalletTx(hash);
     if (!wtx || wtx->isAbandoned() || wtx->GetDepthInMainChain() > 0 ||
         wtx->InMempool())
         return false;
     return true;
 }
 
 bool WalletModel::abandonTransaction(uint256 hash) const {
     LOCK2(cs_main, wallet->cs_wallet);
     return wallet->AbandonTransaction(hash);
 }
 
 bool WalletModel::isWalletEnabled() {
     return !GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET);
 }
 
 bool WalletModel::hdEnabled() const {
     return wallet->IsHDEnabled();
 }
 
 int WalletModel::getDefaultConfirmTarget() const {
     return nTxConfirmTarget;
 }
diff --git a/src/random.cpp b/src/random.cpp
index a1028853e..fae4e6c45 100644
--- a/src/random.cpp
+++ b/src/random.cpp
@@ -1,193 +1,193 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #include "random.h"
 
 #include "crypto/sha512.h"
 #include "support/cleanse.h"
 #ifdef WIN32
 #include "compat.h" // for Windows API
 #include <wincrypt.h>
 #endif
 #include "util.h"             // for LogPrint()
 #include "utilstrencodings.h" // for GetTime()
 
 #include <cstdlib>
 #include <limits>
 
 #ifndef WIN32
 #include <sys/time.h>
 #endif
 
 #include <openssl/err.h>
 #include <openssl/rand.h>
 
 static void RandFailure() {
     LogPrintf("Failed to read randomness, aborting\n");
     abort();
 }
 
 static inline int64_t GetPerformanceCounter() {
     int64_t nCounter = 0;
 #ifdef WIN32
     QueryPerformanceCounter((LARGE_INTEGER *)&nCounter);
 #else
     timeval t;
     gettimeofday(&t, nullptr);
     nCounter = (int64_t)(t.tv_sec * 1000000 + t.tv_usec);
 #endif
     return nCounter;
 }
 
 void RandAddSeed() {
     // Seed with CPU performance counter
     int64_t nCounter = GetPerformanceCounter();
     RAND_add(&nCounter, sizeof(nCounter), 1.5);
     memory_cleanse((void *)&nCounter, sizeof(nCounter));
 }
 
 static void RandAddSeedPerfmon() {
     RandAddSeed();
 
 #ifdef WIN32
     // Don't need this on Linux, OpenSSL automatically uses /dev/urandom
     // Seed with the entire set of perfmon data
 
     // This can take up to 2 seconds, so only do it every 10 minutes
     static int64_t nLastPerfmon;
     if (GetTime() < nLastPerfmon + 10 * 60) return;
     nLastPerfmon = GetTime();
 
-    std::vector<unsigned char> vData(250000, 0);
+    std::vector<uint8_t> vData(250000, 0);
     long ret = 0;
     unsigned long nSize = 0;
     // Bail out at more than 10MB of performance data
     const size_t nMaxSize = 10000000;
     while (true) {
         nSize = vData.size();
         ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", nullptr,
                                nullptr, vData.data(), &nSize);
         if (ret != ERROR_MORE_DATA || vData.size() >= nMaxSize) {
             break;
         }
         // Grow size of buffer exponentially
         vData.resize(std::max((vData.size() * 3) / 2, nMaxSize));
     }
     RegCloseKey(HKEY_PERFORMANCE_DATA);
     if (ret == ERROR_SUCCESS) {
         RAND_add(vData.data(), nSize, nSize / 100.0);
         memory_cleanse(vData.data(), nSize);
         LogPrint("rand", "%s: %lu bytes\n", __func__, nSize);
     } else {
         // Warn only once
         static bool warned = false;
         if (!warned) {
             LogPrintf("%s: Warning: RegQueryValueExA(HKEY_PERFORMANCE_DATA) "
                       "failed with code %i\n",
                       __func__, ret);
             warned = true;
         }
     }
 #endif
 }
 
 /** Get 32 bytes of system entropy. */
-static void GetOSRand(unsigned char *ent32) {
+static void GetOSRand(uint8_t *ent32) {
 #ifdef WIN32
     HCRYPTPROV hProvider;
     int ret = CryptAcquireContextW(&hProvider, nullptr, nullptr, PROV_RSA_FULL,
                                    CRYPT_VERIFYCONTEXT);
     if (!ret) {
         RandFailure();
     }
     ret = CryptGenRandom(hProvider, 32, ent32);
     if (!ret) {
         RandFailure();
     }
     CryptReleaseContext(hProvider, 0);
 #else
     int f = open("/dev/urandom", O_RDONLY);
     if (f == -1) {
         RandFailure();
     }
     int have = 0;
     do {
         ssize_t n = read(f, ent32 + have, 32 - have);
         if (n <= 0 || n + have > 32) {
             RandFailure();
         }
         have += n;
     } while (have < 32);
     close(f);
 #endif
 }
 
-void GetRandBytes(unsigned char *buf, int num) {
+void GetRandBytes(uint8_t *buf, int num) {
     if (RAND_bytes(buf, num) != 1) {
         RandFailure();
     }
 }
 
-void GetStrongRandBytes(unsigned char *out, int num) {
+void GetStrongRandBytes(uint8_t *out, int num) {
     assert(num <= 32);
     CSHA512 hasher;
-    unsigned char buf[64];
+    uint8_t buf[64];
 
     // First source: OpenSSL's RNG
     RandAddSeedPerfmon();
     GetRandBytes(buf, 32);
     hasher.Write(buf, 32);
 
     // Second source: OS RNG
     GetOSRand(buf);
     hasher.Write(buf, 32);
 
     // Produce output
     hasher.Finalize(buf);
     memcpy(out, buf, num);
     memory_cleanse(buf, 64);
 }
 
 uint64_t GetRand(uint64_t nMax) {
     if (nMax == 0) {
         return 0;
     }
 
     // The range of the random source must be a multiple of the modulus to give
     // every possible output value an equal possibility
     uint64_t nRange = (std::numeric_limits<uint64_t>::max() / nMax) * nMax;
     uint64_t nRand = 0;
     do {
-        GetRandBytes((unsigned char *)&nRand, sizeof(nRand));
+        GetRandBytes((uint8_t *)&nRand, sizeof(nRand));
     } while (nRand >= nRange);
     return (nRand % nMax);
 }
 
 int GetRandInt(int nMax) {
     return GetRand(nMax);
 }
 
 uint256 GetRandHash() {
     uint256 hash;
-    GetRandBytes((unsigned char *)&hash, sizeof(hash));
+    GetRandBytes((uint8_t *)&hash, sizeof(hash));
     return hash;
 }
 
 FastRandomContext::FastRandomContext(bool fDeterministic) {
     // The seed values have some unlikely fixed points which we avoid.
     if (fDeterministic) {
         Rz = Rw = 11;
     } else {
         uint32_t tmp;
         do {
-            GetRandBytes((unsigned char *)&tmp, 4);
+            GetRandBytes((uint8_t *)&tmp, 4);
         } while (tmp == 0 || tmp == 0x9068ffffU);
         Rz = tmp;
         do {
-            GetRandBytes((unsigned char *)&tmp, 4);
+            GetRandBytes((uint8_t *)&tmp, 4);
         } while (tmp == 0 || tmp == 0x464fffffU);
         Rw = tmp;
     }
 }
diff --git a/src/random.h b/src/random.h
index 098a02242..fda43fcd4 100644
--- a/src/random.h
+++ b/src/random.h
@@ -1,49 +1,49 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_RANDOM_H
 #define BITCOIN_RANDOM_H
 
 #include "uint256.h"
 
 #include <cstdint>
 
 /* Seed OpenSSL PRNG with additional entropy data */
 void RandAddSeed();
 
 /**
  * Functions to gather random data via the OpenSSL PRNG
  */
-void GetRandBytes(unsigned char *buf, int num);
+void GetRandBytes(uint8_t *buf, int num);
 uint64_t GetRand(uint64_t nMax);
 int GetRandInt(int nMax);
 uint256 GetRandHash();
 
 /**
  * Function to gather random data from multiple sources, failing whenever any of
  * those source fail to provide a result.
  */
-void GetStrongRandBytes(unsigned char *buf, int num);
+void GetStrongRandBytes(uint8_t *buf, int num);
 
 /**
  * Fast randomness source. This is seeded once with secure random data, but is
  * completely deterministic and insecure after that.
  * This class is not thread-safe.
  */
 class FastRandomContext {
 public:
     explicit FastRandomContext(bool fDeterministic = false);
 
     uint32_t rand32() {
         Rz = 36969 * (Rz & 65535) + (Rz >> 16);
         Rw = 18000 * (Rw & 65535) + (Rw >> 16);
         return (Rw << 16) + Rz;
     }
 
     uint32_t Rz;
     uint32_t Rw;
 };
 
 #endif // BITCOIN_RANDOM_H
diff --git a/src/rest.cpp b/src/rest.cpp
index 0239ee343..46aa06548 100644
--- a/src/rest.cpp
+++ b/src/rest.cpp
@@ -1,656 +1,655 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #include "chain.h"
 #include "chainparams.h"
 #include "httpserver.h"
 #include "primitives/block.h"
 #include "primitives/transaction.h"
 #include "rpc/blockchain.h"
 #include "rpc/server.h"
 #include "streams.h"
 #include "sync.h"
 #include "txmempool.h"
 #include "utilstrencodings.h"
 #include "validation.h"
 #include "version.h"
 
 #include <boost/algorithm/string.hpp>
 
 #include <univalue.h>
 
 // Allow a max of 15 outpoints to be queried at once.
 static const size_t MAX_GETUTXOS_OUTPOINTS = 15;
 
 enum RetFormat {
     RF_UNDEF,
     RF_BINARY,
     RF_HEX,
     RF_JSON,
 };
 
 static const struct {
     enum RetFormat rf;
     const char *name;
 } rf_names[] = {
     {RF_UNDEF, ""}, {RF_BINARY, "bin"}, {RF_HEX, "hex"}, {RF_JSON, "json"},
 };
 
 struct CCoin {
     uint32_t nHeight;
     CTxOut out;
 
     CCoin() : nHeight(0) {}
     CCoin(Coin in) : nHeight(in.GetHeight()), out(std::move(in.GetTxOut())) {}
 
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
     inline void SerializationOp(Stream &s, Operation ser_action) {
         uint32_t nTxVerDummy = 0;
         READWRITE(nTxVerDummy);
         READWRITE(nHeight);
         READWRITE(out);
     }
 };
 
 extern void TxToJSON(const CTransaction &tx, const uint256 hashBlock,
                      UniValue &entry);
 extern UniValue blockToJSON(const CBlock &block, const CBlockIndex *blockindex,
                             bool txDetails = false);
 extern UniValue mempoolInfoToJSON();
 extern UniValue mempoolToJSON(bool fVerbose = false);
 extern void ScriptPubKeyToJSON(const CScript &scriptPubKey, UniValue &out,
                                bool fIncludeHex);
 extern UniValue blockheaderToJSON(const CBlockIndex *blockindex);
 
 static bool RESTERR(HTTPRequest *req, enum HTTPStatusCode status,
                     std::string message) {
     req->WriteHeader("Content-Type", "text/plain");
     req->WriteReply(status, message + "\r\n");
     return false;
 }
 
 static enum RetFormat ParseDataFormat(std::string &param,
                                       const std::string &strReq) {
     const std::string::size_type pos = strReq.rfind('.');
     if (pos == std::string::npos) {
         param = strReq;
         return rf_names[0].rf;
     }
 
     param = strReq.substr(0, pos);
     const std::string suff(strReq, pos + 1);
 
     for (unsigned int i = 0; i < ARRAYLEN(rf_names); i++)
         if (suff == rf_names[i].name) return rf_names[i].rf;
 
     /* If no suffix is found, return original string.  */
     param = strReq;
     return rf_names[0].rf;
 }
 
 static std::string AvailableDataFormatsString() {
     std::string formats = "";
     for (unsigned int i = 0; i < ARRAYLEN(rf_names); i++)
         if (strlen(rf_names[i].name) > 0) {
             formats.append(".");
             formats.append(rf_names[i].name);
             formats.append(", ");
         }
 
     if (formats.length() > 0) return formats.substr(0, formats.length() - 2);
 
     return formats;
 }
 
 static bool ParseHashStr(const std::string &strReq, uint256 &v) {
     if (!IsHex(strReq) || (strReq.size() != 64)) return false;
 
     v.SetHex(strReq);
     return true;
 }
 
 static bool CheckWarmup(HTTPRequest *req) {
     std::string statusmessage;
     if (RPCIsInWarmup(&statusmessage))
         return RESTERR(req, HTTP_SERVICE_UNAVAILABLE,
                        "Service temporarily unavailable: " + statusmessage);
     return true;
 }
 
 static bool rest_headers(Config &config, HTTPRequest *req,
                          const std::string &strURIPart) {
     if (!CheckWarmup(req)) return false;
     std::string param;
     const RetFormat rf = ParseDataFormat(param, strURIPart);
     std::vector<std::string> path;
     boost::split(path, param, boost::is_any_of("/"));
 
     if (path.size() != 2)
         return RESTERR(req, HTTP_BAD_REQUEST, "No header count specified. Use "
                                               "/rest/headers/<count>/"
                                               "<hash>.<ext>.");
 
     long count = strtol(path[0].c_str(), nullptr, 10);
     if (count < 1 || count > 2000)
         return RESTERR(req, HTTP_BAD_REQUEST,
                        "Header count out of range: " + path[0]);
 
     std::string hashStr = path[1];
     uint256 hash;
     if (!ParseHashStr(hashStr, hash))
         return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
 
     std::vector<const CBlockIndex *> headers;
     headers.reserve(count);
     {
         LOCK(cs_main);
         BlockMap::const_iterator it = mapBlockIndex.find(hash);
         const CBlockIndex *pindex =
             (it != mapBlockIndex.end()) ? it->second : nullptr;
         while (pindex != nullptr && chainActive.Contains(pindex)) {
             headers.push_back(pindex);
             if (headers.size() == (unsigned long)count) break;
             pindex = chainActive.Next(pindex);
         }
     }
 
     CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION);
     for (const CBlockIndex *pindex : headers) {
         ssHeader << pindex->GetBlockHeader();
     }
 
     switch (rf) {
         case RF_BINARY: {
             std::string binaryHeader = ssHeader.str();
             req->WriteHeader("Content-Type", "application/octet-stream");
             req->WriteReply(HTTP_OK, binaryHeader);
             return true;
         }
 
         case RF_HEX: {
             std::string strHex =
                 HexStr(ssHeader.begin(), ssHeader.end()) + "\n";
             req->WriteHeader("Content-Type", "text/plain");
             req->WriteReply(HTTP_OK, strHex);
             return true;
         }
         case RF_JSON: {
             UniValue jsonHeaders(UniValue::VARR);
             for (const CBlockIndex *pindex : headers) {
                 jsonHeaders.push_back(blockheaderToJSON(pindex));
             }
             std::string strJSON = jsonHeaders.write() + "\n";
             req->WriteHeader("Content-Type", "application/json");
             req->WriteReply(HTTP_OK, strJSON);
             return true;
         }
         default: {
             return RESTERR(req, HTTP_NOT_FOUND,
                            "output format not found (available: .bin, .hex)");
         }
     }
 
     // not reached
     // continue to process further HTTP reqs on this cxn
     return true;
 }
 
 static bool rest_block(HTTPRequest *req, const std::string &strURIPart,
                        bool showTxDetails) {
     if (!CheckWarmup(req)) return false;
     std::string hashStr;
     const RetFormat rf = ParseDataFormat(hashStr, strURIPart);
 
     uint256 hash;
     if (!ParseHashStr(hashStr, hash))
         return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
 
     CBlock block;
     CBlockIndex *pblockindex = nullptr;
     {
         LOCK(cs_main);
         if (mapBlockIndex.count(hash) == 0)
             return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
 
         pblockindex = mapBlockIndex[hash];
         if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) &&
             pblockindex->nTx > 0)
             return RESTERR(req, HTTP_NOT_FOUND,
                            hashStr + " not available (pruned data)");
 
         if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus()))
             return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
     }
 
     CDataStream ssBlock(SER_NETWORK,
                         PROTOCOL_VERSION | RPCSerializationFlags());
     ssBlock << block;
 
     switch (rf) {
         case RF_BINARY: {
             std::string binaryBlock = ssBlock.str();
             req->WriteHeader("Content-Type", "application/octet-stream");
             req->WriteReply(HTTP_OK, binaryBlock);
             return true;
         }
 
         case RF_HEX: {
             std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()) + "\n";
             req->WriteHeader("Content-Type", "text/plain");
             req->WriteReply(HTTP_OK, strHex);
             return true;
         }
 
         case RF_JSON: {
             UniValue objBlock = blockToJSON(block, pblockindex, showTxDetails);
             std::string strJSON = objBlock.write() + "\n";
             req->WriteHeader("Content-Type", "application/json");
             req->WriteReply(HTTP_OK, strJSON);
             return true;
         }
 
         default: {
             return RESTERR(req, HTTP_NOT_FOUND,
                            "output format not found (available: " +
                                AvailableDataFormatsString() + ")");
         }
     }
 
     // not reached
     // continue to process further HTTP reqs on this cxn
     return true;
 }
 
 static bool rest_block_extended(Config &config, HTTPRequest *req,
                                 const std::string &strURIPart) {
     return rest_block(req, strURIPart, true);
 }
 
 static bool rest_block_notxdetails(Config &config, HTTPRequest *req,
                                    const std::string &strURIPart) {
     return rest_block(req, strURIPart, false);
 }
 
 static bool rest_chaininfo(Config &config, HTTPRequest *req,
                            const std::string &strURIPart) {
     if (!CheckWarmup(req)) return false;
     std::string param;
     const RetFormat rf = ParseDataFormat(param, strURIPart);
 
     switch (rf) {
         case RF_JSON: {
             JSONRPCRequest jsonRequest;
             jsonRequest.params = UniValue(UniValue::VARR);
             UniValue chainInfoObject = getblockchaininfo(config, jsonRequest);
             std::string strJSON = chainInfoObject.write() + "\n";
             req->WriteHeader("Content-Type", "application/json");
             req->WriteReply(HTTP_OK, strJSON);
             return true;
         }
         default: {
             return RESTERR(req, HTTP_NOT_FOUND,
                            "output format not found (available: json)");
         }
     }
 
     // not reached
     // continue to process further HTTP reqs on this cxn
     return true;
 }
 
 static bool rest_mempool_info(Config &config, HTTPRequest *req,
                               const std::string &strURIPart) {
     if (!CheckWarmup(req)) return false;
     std::string param;
     const RetFormat rf = ParseDataFormat(param, strURIPart);
 
     switch (rf) {
         case RF_JSON: {
             UniValue mempoolInfoObject = mempoolInfoToJSON();
 
             std::string strJSON = mempoolInfoObject.write() + "\n";
             req->WriteHeader("Content-Type", "application/json");
             req->WriteReply(HTTP_OK, strJSON);
             return true;
         }
         default: {
             return RESTERR(req, HTTP_NOT_FOUND,
                            "output format not found (available: json)");
         }
     }
 
     // not reached
     // continue to process further HTTP reqs on this cxn
     return true;
 }
 
 static bool rest_mempool_contents(Config &config, HTTPRequest *req,
                                   const std::string &strURIPart) {
     if (!CheckWarmup(req)) return false;
     std::string param;
     const RetFormat rf = ParseDataFormat(param, strURIPart);
 
     switch (rf) {
         case RF_JSON: {
             UniValue mempoolObject = mempoolToJSON(true);
 
             std::string strJSON = mempoolObject.write() + "\n";
             req->WriteHeader("Content-Type", "application/json");
             req->WriteReply(HTTP_OK, strJSON);
             return true;
         }
         default: {
             return RESTERR(req, HTTP_NOT_FOUND,
                            "output format not found (available: json)");
         }
     }
 
     // not reached
     // continue to process further HTTP reqs on this cxn
     return true;
 }
 
 static bool rest_tx(Config &config, HTTPRequest *req,
                     const std::string &strURIPart) {
     if (!CheckWarmup(req)) return false;
     std::string hashStr;
     const RetFormat rf = ParseDataFormat(hashStr, strURIPart);
 
     uint256 hash;
     if (!ParseHashStr(hashStr, hash))
         return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
 
     CTransactionRef tx;
     uint256 hashBlock = uint256();
     if (!GetTransaction(config, hash, tx, hashBlock, true)) {
         return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
     }
 
     CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
     ssTx << tx;
 
     switch (rf) {
         case RF_BINARY: {
             std::string binaryTx = ssTx.str();
             req->WriteHeader("Content-Type", "application/octet-stream");
             req->WriteReply(HTTP_OK, binaryTx);
             return true;
         }
 
         case RF_HEX: {
             std::string strHex = HexStr(ssTx.begin(), ssTx.end()) + "\n";
             req->WriteHeader("Content-Type", "text/plain");
             req->WriteReply(HTTP_OK, strHex);
             return true;
         }
 
         case RF_JSON: {
             UniValue objTx(UniValue::VOBJ);
             TxToJSON(*tx, hashBlock, objTx);
             std::string strJSON = objTx.write() + "\n";
             req->WriteHeader("Content-Type", "application/json");
             req->WriteReply(HTTP_OK, strJSON);
             return true;
         }
 
         default: {
             return RESTERR(req, HTTP_NOT_FOUND,
                            "output format not found (available: " +
                                AvailableDataFormatsString() + ")");
         }
     }
 
     // not reached
     // continue to process further HTTP reqs on this cxn
     return true;
 }
 
 static bool rest_getutxos(Config &config, HTTPRequest *req,
                           const std::string &strURIPart) {
     if (!CheckWarmup(req)) return false;
     std::string param;
     const RetFormat rf = ParseDataFormat(param, strURIPart);
 
     std::vector<std::string> uriParts;
     if (param.length() > 1) {
         std::string strUriParams = param.substr(1);
         boost::split(uriParts, strUriParams, boost::is_any_of("/"));
     }
 
     // throw exception in case of a empty request
     std::string strRequestMutable = req->ReadBody();
     if (strRequestMutable.length() == 0 && uriParts.size() == 0)
         return RESTERR(req, HTTP_BAD_REQUEST, "Error: empty request");
 
     bool fInputParsed = false;
     bool fCheckMemPool = false;
     std::vector<COutPoint> vOutPoints;
 
     // parse/deserialize input
     // input-format = output-format, rest/getutxos/bin requires binary input,
     // gives binary output, ...
 
     if (uriParts.size() > 0) {
 
         // inputs is sent over URI scheme
         // (/rest/getutxos/checkmempool/txid1-n/txid2-n/...)
         if (uriParts.size() > 0 && uriParts[0] == "checkmempool")
             fCheckMemPool = true;
 
         for (size_t i = (fCheckMemPool) ? 1 : 0; i < uriParts.size(); i++) {
             uint256 txid;
             int32_t nOutput;
             std::string strTxid = uriParts[i].substr(0, uriParts[i].find("-"));
             std::string strOutput =
                 uriParts[i].substr(uriParts[i].find("-") + 1);
 
             if (!ParseInt32(strOutput, &nOutput) || !IsHex(strTxid))
                 return RESTERR(req, HTTP_BAD_REQUEST, "Parse error");
 
             txid.SetHex(strTxid);
             vOutPoints.push_back(COutPoint(txid, (uint32_t)nOutput));
         }
 
         if (vOutPoints.size() > 0) {
             fInputParsed = true;
         } else {
             return RESTERR(req, HTTP_BAD_REQUEST, "Error: empty request");
         }
     }
 
     switch (rf) {
         case RF_HEX: {
             // convert hex to bin, continue then with bin part
-            std::vector<unsigned char> strRequestV =
-                ParseHex(strRequestMutable);
+            std::vector<uint8_t> strRequestV = ParseHex(strRequestMutable);
             strRequestMutable.assign(strRequestV.begin(), strRequestV.end());
             // FALLTHROUGH
         }
 
         case RF_BINARY: {
             try {
                 // deserialize only if user sent a request
                 if (strRequestMutable.size() > 0) {
                     // don't allow sending input over URI and HTTP RAW DATA
                     if (fInputParsed) {
                         return RESTERR(req, HTTP_BAD_REQUEST,
                                        "Combination of URI scheme inputs and "
                                        "raw post data is not allowed");
                     }
 
                     CDataStream oss(SER_NETWORK, PROTOCOL_VERSION);
                     oss << strRequestMutable;
                     oss >> fCheckMemPool;
                     oss >> vOutPoints;
                 }
             } catch (const std::ios_base::failure &e) {
                 // abort in case of unreadable binary data
                 return RESTERR(req, HTTP_BAD_REQUEST, "Parse error");
             }
             break;
         }
 
         case RF_JSON: {
             if (!fInputParsed) {
                 return RESTERR(req, HTTP_BAD_REQUEST, "Error: empty request");
             }
             break;
         }
         default: {
             return RESTERR(req, HTTP_NOT_FOUND,
                            "output format not found (available: " +
                                AvailableDataFormatsString() + ")");
         }
     }
 
     // limit max outpoints
     if (vOutPoints.size() > MAX_GETUTXOS_OUTPOINTS)
         return RESTERR(
             req, HTTP_BAD_REQUEST,
             strprintf("Error: max outpoints exceeded (max: %d, tried: %d)",
                       MAX_GETUTXOS_OUTPOINTS, vOutPoints.size()));
 
     // check spentness and form a bitmap (as well as a JSON capable
     // human-readable string representation)
-    std::vector<unsigned char> bitmap;
+    std::vector<uint8_t> bitmap;
     std::vector<CCoin> outs;
     std::string bitmapStringRepresentation;
     std::vector<bool> hits;
     bitmap.resize((vOutPoints.size() + 7) / 8);
     {
         LOCK2(cs_main, mempool.cs);
 
         CCoinsView viewDummy;
         CCoinsViewCache view(&viewDummy);
 
         CCoinsViewCache &viewChain = *pcoinsTip;
         CCoinsViewMemPool viewMempool(&viewChain, mempool);
 
         if (fCheckMemPool) {
             // switch cache backend to db+mempool in case user likes to query
             // mempool.
             view.SetBackend(viewMempool);
         }
 
         for (size_t i = 0; i < vOutPoints.size(); i++) {
             Coin coin;
             bool hit = false;
             if (view.GetCoin(vOutPoints[i], coin) &&
                 !mempool.isSpent(vOutPoints[i])) {
                 hit = true;
                 outs.emplace_back(std::move(coin));
             }
 
             hits.push_back(hit);
             // form a binary string representation (human-readable for json
             // output)
             bitmapStringRepresentation.append(hit ? "1" : "0");
             bitmap[i / 8] |= ((uint8_t)hit) << (i % 8);
         }
     }
 
     switch (rf) {
         case RF_BINARY: {
             // serialize data
             // use exact same output as mentioned in Bip64
             CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION);
             ssGetUTXOResponse << chainActive.Height()
                               << chainActive.Tip()->GetBlockHash() << bitmap
                               << outs;
             std::string ssGetUTXOResponseString = ssGetUTXOResponse.str();
 
             req->WriteHeader("Content-Type", "application/octet-stream");
             req->WriteReply(HTTP_OK, ssGetUTXOResponseString);
             return true;
         }
 
         case RF_HEX: {
             CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION);
             ssGetUTXOResponse << chainActive.Height()
                               << chainActive.Tip()->GetBlockHash() << bitmap
                               << outs;
             std::string strHex =
                 HexStr(ssGetUTXOResponse.begin(), ssGetUTXOResponse.end()) +
                 "\n";
 
             req->WriteHeader("Content-Type", "text/plain");
             req->WriteReply(HTTP_OK, strHex);
             return true;
         }
 
         case RF_JSON: {
             UniValue objGetUTXOResponse(UniValue::VOBJ);
 
             // pack in some essentials
             // use more or less the same output as mentioned in Bip64
             objGetUTXOResponse.push_back(
                 Pair("chainHeight", chainActive.Height()));
             objGetUTXOResponse.push_back(Pair(
                 "chaintipHash", chainActive.Tip()->GetBlockHash().GetHex()));
             objGetUTXOResponse.push_back(
                 Pair("bitmap", bitmapStringRepresentation));
 
             UniValue utxos(UniValue::VARR);
             for (const CCoin &coin : outs) {
                 UniValue utxo(UniValue::VOBJ);
                 utxo.push_back(Pair("height", int32_t(coin.nHeight)));
                 utxo.push_back(Pair("value", ValueFromAmount(coin.out.nValue)));
 
                 // include the script in a json output
                 UniValue o(UniValue::VOBJ);
                 ScriptPubKeyToJSON(coin.out.scriptPubKey, o, true);
                 utxo.push_back(Pair("scriptPubKey", o));
                 utxos.push_back(utxo);
             }
             objGetUTXOResponse.push_back(Pair("utxos", utxos));
 
             // return json string
             std::string strJSON = objGetUTXOResponse.write() + "\n";
             req->WriteHeader("Content-Type", "application/json");
             req->WriteReply(HTTP_OK, strJSON);
             return true;
         }
         default: {
             return RESTERR(req, HTTP_NOT_FOUND,
                            "output format not found (available: " +
                                AvailableDataFormatsString() + ")");
         }
     }
 
     // not reached
     // continue to process further HTTP reqs on this cxn
     return true;
 }
 
 static const struct {
     const char *prefix;
     bool (*handler)(Config &config, HTTPRequest *req,
                     const std::string &strReq);
 } uri_prefixes[] = {
     {"/rest/tx/", rest_tx},
     {"/rest/block/notxdetails/", rest_block_notxdetails},
     {"/rest/block/", rest_block_extended},
     {"/rest/chaininfo", rest_chaininfo},
     {"/rest/mempool/info", rest_mempool_info},
     {"/rest/mempool/contents", rest_mempool_contents},
     {"/rest/headers/", rest_headers},
     {"/rest/getutxos", rest_getutxos},
 };
 
 bool StartREST() {
     for (unsigned int i = 0; i < ARRAYLEN(uri_prefixes); i++)
         RegisterHTTPHandler(uri_prefixes[i].prefix, false,
                             uri_prefixes[i].handler);
     return true;
 }
 
 void InterruptREST() {}
 
 void StopREST() {
     for (unsigned int i = 0; i < ARRAYLEN(uri_prefixes); i++)
         UnregisterHTTPHandler(uri_prefixes[i].prefix, false);
 }
diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp
index 5d5f7ecc4..bc316f6fd 100644
--- a/src/rpc/misc.cpp
+++ b/src/rpc/misc.cpp
@@ -1,604 +1,603 @@
 // Copyright (c) 2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #include "rpc/misc.h"
 
 #include "base58.h"
 #include "clientversion.h"
 #include "config.h"
 #include "init.h"
 #include "net.h"
 #include "netbase.h"
 #include "rpc/server.h"
 #include "timedata.h"
 #include "util.h"
 #include "utilstrencodings.h"
 #include "validation.h"
 #ifdef ENABLE_WALLET
 #include "wallet/wallet.h"
 #include "wallet/walletdb.h"
 #endif
 
 #include <cstdint>
 
 #include <boost/assign/list_of.hpp>
 
 #include <univalue.h>
 
 /**
  * @note Do not add or change anything in the information returned by this
  * method. `getinfo` exists for backwards-compatibility only. It combines
  * information from wildly different sources in the program, which is a mess,
  * and is thus planned to be deprecated eventually.
  *
  * Based on the source of the information, new information should be added to:
  * - `getblockchaininfo`,
  * - `getnetworkinfo` or
  * - `getwalletinfo`
  *
  * Or alternatively, create a specific query method for the information.
  **/
 static UniValue getinfo(const Config &config, const JSONRPCRequest &request) {
     if (request.fHelp || request.params.size() != 0)
         throw std::runtime_error(
             "getinfo\n"
             "\nDEPRECATED. Returns an object containing various state info.\n"
             "\nResult:\n"
             "{\n"
             "  \"version\": xxxxx,           (numeric) the server version\n"
             "  \"protocolversion\": xxxxx,   (numeric) the protocol version\n"
             "  \"walletversion\": xxxxx,     (numeric) the wallet version\n"
             "  \"balance\": xxxxxxx,         (numeric) the total bitcoin "
             "balance of the wallet\n"
             "  \"blocks\": xxxxxx,           (numeric) the current number of "
             "blocks processed in the server\n"
             "  \"timeoffset\": xxxxx,        (numeric) the time offset\n"
             "  \"connections\": xxxxx,       (numeric) the number of "
             "connections\n"
             "  \"proxy\": \"host:port\",     (string, optional) the proxy used "
             "by the server\n"
             "  \"difficulty\": xxxxxx,       (numeric) the current difficulty\n"
             "  \"testnet\": true|false,      (boolean) if the server is using "
             "testnet or not\n"
             "  \"keypoololdest\": xxxxxx,    (numeric) the timestamp (seconds "
             "since Unix epoch) of the oldest pre-generated key in the key "
             "pool\n"
             "  \"keypoolsize\": xxxx,        (numeric) how many new keys are "
             "pre-generated\n"
             "  \"unlocked_until\": ttt,      (numeric) the timestamp in "
             "seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is "
             "unlocked for transfers, or 0 if the wallet is locked\n"
             "  \"paytxfee\": x.xxxx,         (numeric) the transaction fee set "
             "in " +
             CURRENCY_UNIT + "/kB\n"
                             "  \"relayfee\": x.xxxx,         (numeric) minimum "
                             "relay fee for non-free transactions in " +
             CURRENCY_UNIT +
             "/kB\n"
             "  \"errors\": \"...\"           (string) any error messages\n"
             "}\n"
             "\nExamples:\n" +
             HelpExampleCli("getinfo", "") + HelpExampleRpc("getinfo", ""));
 
 #ifdef ENABLE_WALLET
     LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : nullptr);
 #else
     LOCK(cs_main);
 #endif
 
     proxyType proxy;
     GetProxy(NET_IPV4, proxy);
 
     UniValue obj(UniValue::VOBJ);
     obj.push_back(Pair("version", CLIENT_VERSION));
     obj.push_back(Pair("protocolversion", PROTOCOL_VERSION));
 #ifdef ENABLE_WALLET
     if (pwalletMain) {
         obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
         obj.push_back(
             Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
     }
 #endif
     obj.push_back(Pair("blocks", (int)chainActive.Height()));
     obj.push_back(Pair("timeoffset", GetTimeOffset()));
     if (g_connman)
         obj.push_back(Pair("connections", (int)g_connman->GetNodeCount(
                                               CConnman::CONNECTIONS_ALL)));
     obj.push_back(Pair("proxy", (proxy.IsValid() ? proxy.proxy.ToStringIPPort()
                                                  : std::string())));
     obj.push_back(Pair("difficulty", (double)GetDifficulty()));
     obj.push_back(Pair("testnet", Params().NetworkIDString() ==
                                       CBaseChainParams::TESTNET));
 #ifdef ENABLE_WALLET
     if (pwalletMain) {
         obj.push_back(
             Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime()));
         obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
     }
     if (pwalletMain && pwalletMain->IsCrypted())
         obj.push_back(Pair("unlocked_until", nWalletUnlockTime));
     obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())));
 #endif
     obj.push_back(
         Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())));
     obj.push_back(Pair("errors", GetWarnings("statusbar")));
     return obj;
 }
 
 #ifdef ENABLE_WALLET
 class DescribeAddressVisitor : public boost::static_visitor<UniValue> {
 public:
     UniValue operator()(const CNoDestination &dest) const {
         return UniValue(UniValue::VOBJ);
     }
 
     UniValue operator()(const CKeyID &keyID) const {
         UniValue obj(UniValue::VOBJ);
         CPubKey vchPubKey;
         obj.push_back(Pair("isscript", false));
         if (pwalletMain && pwalletMain->GetPubKey(keyID, vchPubKey)) {
             obj.push_back(Pair("pubkey", HexStr(vchPubKey)));
             obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed()));
         }
         return obj;
     }
 
     UniValue operator()(const CScriptID &scriptID) const {
         UniValue obj(UniValue::VOBJ);
         CScript subscript;
         obj.push_back(Pair("isscript", true));
         if (pwalletMain && pwalletMain->GetCScript(scriptID, subscript)) {
             std::vector<CTxDestination> addresses;
             txnouttype whichType;
             int nRequired;
             ExtractDestinations(subscript, whichType, addresses, nRequired);
             obj.push_back(Pair("script", GetTxnOutputType(whichType)));
             obj.push_back(
                 Pair("hex", HexStr(subscript.begin(), subscript.end())));
             UniValue a(UniValue::VARR);
             for (const CTxDestination &addr : addresses) {
                 a.push_back(CBitcoinAddress(addr).ToString());
             }
             obj.push_back(Pair("addresses", a));
             if (whichType == TX_MULTISIG)
                 obj.push_back(Pair("sigsrequired", nRequired));
         }
         return obj;
     }
 };
 #endif
 
 static UniValue validateaddress(const Config &config,
                                 const JSONRPCRequest &request) {
     if (request.fHelp || request.params.size() != 1)
         throw std::runtime_error(
             "validateaddress \"address\"\n"
             "\nReturn information about the given bitcoin address.\n"
             "\nArguments:\n"
             "1. \"address\"     (string, required) The bitcoin address to "
             "validate\n"
             "\nResult:\n"
             "{\n"
             "  \"isvalid\" : true|false,       (boolean) If the address is "
             "valid or not. If not, this is the only property returned.\n"
             "  \"address\" : \"address\", (string) The bitcoin address "
             "validated\n"
             "  \"scriptPubKey\" : \"hex\",       (string) The hex encoded "
             "scriptPubKey generated by the address\n"
             "  \"ismine\" : true|false,        (boolean) If the address is "
             "yours or not\n"
             "  \"iswatchonly\" : true|false,   (boolean) If the address is "
             "watchonly\n"
             "  \"isscript\" : true|false,      (boolean) If the key is a "
             "script\n"
             "  \"pubkey\" : \"publickeyhex\",    (string) The hex value of the "
             "raw public key\n"
             "  \"iscompressed\" : true|false,  (boolean) If the address is "
             "compressed\n"
             "  \"account\" : \"account\"         (string) DEPRECATED. The "
             "account associated with the address, \"\" is the default account\n"
             "  \"timestamp\" : timestamp,        (number, optional) The "
             "creation time of the key if available in seconds since epoch (Jan "
             "1 1970 GMT)\n"
             "  \"hdkeypath\" : \"keypath\"       (string, optional) The HD "
             "keypath if the key is HD and available\n"
             "  \"hdmasterkeyid\" : \"<hash160>\" (string, optional) The "
             "Hash160 of the HD master pubkey\n"
             "}\n"
             "\nExamples:\n" +
             HelpExampleCli("validateaddress",
                            "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"") +
             HelpExampleRpc("validateaddress",
                            "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\""));
 
 #ifdef ENABLE_WALLET
     LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : nullptr);
 #else
     LOCK(cs_main);
 #endif
 
     CBitcoinAddress address(request.params[0].get_str());
     bool isValid = address.IsValid();
 
     UniValue ret(UniValue::VOBJ);
     ret.push_back(Pair("isvalid", isValid));
     if (isValid) {
         CTxDestination dest = address.Get();
         std::string currentAddress = address.ToString();
         ret.push_back(Pair("address", currentAddress));
 
         CScript scriptPubKey = GetScriptForDestination(dest);
         ret.push_back(Pair("scriptPubKey",
                            HexStr(scriptPubKey.begin(), scriptPubKey.end())));
 
 #ifdef ENABLE_WALLET
         isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO;
         ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false));
         ret.push_back(
             Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true : false));
         UniValue detail = boost::apply_visitor(DescribeAddressVisitor(), dest);
         ret.pushKVs(detail);
         if (pwalletMain && pwalletMain->mapAddressBook.count(dest))
             ret.push_back(
                 Pair("account", pwalletMain->mapAddressBook[dest].name));
         CKeyID keyID;
         if (pwalletMain) {
             const auto &meta = pwalletMain->mapKeyMetadata;
             auto it = address.GetKeyID(keyID) ? meta.find(keyID) : meta.end();
             if (it == meta.end()) {
                 it = meta.find(CScriptID(scriptPubKey));
             }
             if (it != meta.end()) {
                 ret.push_back(Pair("timestamp", it->second.nCreateTime));
                 if (!it->second.hdKeypath.empty()) {
                     ret.push_back(Pair("hdkeypath", it->second.hdKeypath));
                     ret.push_back(Pair("hdmasterkeyid",
                                        it->second.hdMasterKeyID.GetHex()));
                 }
             }
         }
 #endif
     }
     return ret;
 }
 
 /**
  * Used by addmultisigaddress / createmultisig:
  */
 CScript createmultisig_redeemScript(const UniValue &params) {
     int nRequired = params[0].get_int();
     const UniValue &keys = params[1].get_array();
 
     // Gather public keys
     if (nRequired < 1)
         throw std::runtime_error(
             "a multisignature address must require at least one key to redeem");
     if ((int)keys.size() < nRequired)
         throw std::runtime_error(
             strprintf("not enough keys supplied "
                       "(got %u keys, but need at least %d to redeem)",
                       keys.size(), nRequired));
     if (keys.size() > 16)
         throw std::runtime_error(
             "Number of addresses involved in the "
             "multisignature address creation > 16\nReduce the "
             "number");
     std::vector<CPubKey> pubkeys;
     pubkeys.resize(keys.size());
     for (unsigned int i = 0; i < keys.size(); i++) {
         const std::string &ks = keys[i].get_str();
 #ifdef ENABLE_WALLET
         // Case 1: Bitcoin address and we have full public key:
         CBitcoinAddress address(ks);
         if (pwalletMain && address.IsValid()) {
             CKeyID keyID;
             if (!address.GetKeyID(keyID))
                 throw std::runtime_error(
                     strprintf("%s does not refer to a key", ks));
             CPubKey vchPubKey;
             if (!pwalletMain->GetPubKey(keyID, vchPubKey))
                 throw std::runtime_error(
                     strprintf("no full public key for address %s", ks));
             if (!vchPubKey.IsFullyValid())
                 throw std::runtime_error(" Invalid public key: " + ks);
             pubkeys[i] = vchPubKey;
         }
 
         // Case 2: hex public key
         else
 #endif
             if (IsHex(ks)) {
             CPubKey vchPubKey(ParseHex(ks));
             if (!vchPubKey.IsFullyValid())
                 throw std::runtime_error(" Invalid public key: " + ks);
             pubkeys[i] = vchPubKey;
         } else {
             throw std::runtime_error(" Invalid public key: " + ks);
         }
     }
     CScript result = GetScriptForMultisig(nRequired, pubkeys);
 
     if (result.size() > MAX_SCRIPT_ELEMENT_SIZE)
         throw std::runtime_error(
             strprintf("redeemScript exceeds size limit: %d > %d", result.size(),
                       MAX_SCRIPT_ELEMENT_SIZE));
 
     return result;
 }
 
 static UniValue createmultisig(const Config &config,
                                const JSONRPCRequest &request) {
     if (request.fHelp || request.params.size() < 2 ||
         request.params.size() > 2) {
         std::string msg =
             "createmultisig nrequired [\"key\",...]\n"
             "\nCreates a multi-signature address with n signature of m keys "
             "required.\n"
             "It returns a json object with the address and redeemScript.\n"
 
             "\nArguments:\n"
             "1. nrequired      (numeric, required) The number of required "
             "signatures out of the n keys or addresses.\n"
             "2. \"keys\"       (string, required) A json array of keys which "
             "are bitcoin addresses or hex-encoded public keys\n"
             "     [\n"
             "       \"key\"    (string) bitcoin address or hex-encoded public "
             "key\n"
             "       ,...\n"
             "     ]\n"
 
             "\nResult:\n"
             "{\n"
             "  \"address\":\"multisigaddress\",  (string) The value of the new "
             "multisig address.\n"
             "  \"redeemScript\":\"script\"       (string) The string value of "
             "the hex-encoded redemption script.\n"
             "}\n"
 
             "\nExamples:\n"
             "\nCreate a multisig address from 2 addresses\n" +
             HelpExampleCli("createmultisig",
                            "2 "
                            "\"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\","
                            "\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") +
             "\nAs a json rpc call\n" +
             HelpExampleRpc("createmultisig",
                            "2, "
                            "\"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\","
                            "\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"");
         throw std::runtime_error(msg);
     }
 
     // Construct using pay-to-script-hash:
     CScript inner = createmultisig_redeemScript(request.params);
     CScriptID innerID(inner);
     CBitcoinAddress address(innerID);
 
     UniValue result(UniValue::VOBJ);
     result.push_back(Pair("address", address.ToString()));
     result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end())));
 
     return result;
 }
 
 static UniValue verifymessage(const Config &config,
                               const JSONRPCRequest &request) {
     if (request.fHelp || request.params.size() != 3)
         throw std::runtime_error(
             "verifymessage \"address\" \"signature\" \"message\"\n"
             "\nVerify a signed message\n"
             "\nArguments:\n"
             "1. \"address\"         (string, required) The bitcoin address to "
             "use for the signature.\n"
             "2. \"signature\"       (string, required) The signature provided "
             "by the signer in base 64 encoding (see signmessage).\n"
             "3. \"message\"         (string, required) The message that was "
             "signed.\n"
             "\nResult:\n"
             "true|false   (boolean) If the signature is verified or not.\n"
             "\nExamples:\n"
             "\nUnlock the wallet for 30 seconds\n" +
             HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
             "\nCreate the signature\n" +
             HelpExampleCli(
                 "signmessage",
                 "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") +
             "\nVerify the signature\n" +
             HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4"
                                             "XX\" \"signature\" \"my "
                                             "message\"") +
             "\nAs json rpc\n" +
             HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4"
                                             "XX\", \"signature\", \"my "
                                             "message\""));
 
     LOCK(cs_main);
 
     std::string strAddress = request.params[0].get_str();
     std::string strSign = request.params[1].get_str();
     std::string strMessage = request.params[2].get_str();
 
     CBitcoinAddress addr(strAddress);
     if (!addr.IsValid()) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
 
     CKeyID keyID;
     if (!addr.GetKeyID(keyID))
         throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
 
     bool fInvalid = false;
-    std::vector<unsigned char> vchSig =
-        DecodeBase64(strSign.c_str(), &fInvalid);
+    std::vector<uint8_t> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);
 
     if (fInvalid)
         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                            "Malformed base64 encoding");
 
     CHashWriter ss(SER_GETHASH, 0);
     ss << strMessageMagic;
     ss << strMessage;
 
     CPubKey pubkey;
     if (!pubkey.RecoverCompact(ss.GetHash(), vchSig)) return false;
 
     return (pubkey.GetID() == keyID);
 }
 
 static UniValue signmessagewithprivkey(const Config &config,
                                        const JSONRPCRequest &request) {
     if (request.fHelp || request.params.size() != 2)
         throw std::runtime_error(
             "signmessagewithprivkey \"privkey\" \"message\"\n"
             "\nSign a message with the private key of an address\n"
             "\nArguments:\n"
             "1. \"privkey\"         (string, required) The private key to sign "
             "the message with.\n"
             "2. \"message\"         (string, required) The message to create a "
             "signature of.\n"
             "\nResult:\n"
             "\"signature\"          (string) The signature of the message "
             "encoded in base 64\n"
             "\nExamples:\n"
             "\nCreate the signature\n" +
             HelpExampleCli("signmessagewithprivkey",
                            "\"privkey\" \"my message\"") +
             "\nVerify the signature\n" +
             HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4"
                                             "XX\" \"signature\" \"my "
                                             "message\"") +
             "\nAs json rpc\n" + HelpExampleRpc("signmessagewithprivkey",
                                                "\"privkey\", \"my message\""));
 
     std::string strPrivkey = request.params[0].get_str();
     std::string strMessage = request.params[1].get_str();
 
     CBitcoinSecret vchSecret;
     bool fGood = vchSecret.SetString(strPrivkey);
     if (!fGood)
         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
     CKey key = vchSecret.GetKey();
     if (!key.IsValid())
         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                            "Private key outside allowed range");
 
     CHashWriter ss(SER_GETHASH, 0);
     ss << strMessageMagic;
     ss << strMessage;
 
-    std::vector<unsigned char> vchSig;
+    std::vector<uint8_t> vchSig;
     if (!key.SignCompact(ss.GetHash(), vchSig))
         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed");
 
     return EncodeBase64(&vchSig[0], vchSig.size());
 }
 
 static UniValue setmocktime(const Config &config,
                             const JSONRPCRequest &request) {
     if (request.fHelp || request.params.size() != 1)
         throw std::runtime_error(
             "setmocktime timestamp\n"
             "\nSet the local time to given timestamp (-regtest only)\n"
             "\nArguments:\n"
             "1. timestamp  (integer, required) Unix seconds-since-epoch "
             "timestamp\n"
             "   Pass 0 to go back to using the system time.");
 
     if (!Params().MineBlocksOnDemand())
         throw std::runtime_error(
             "setmocktime for regression testing (-regtest mode) only");
 
     // For now, don't change mocktime if we're in the middle of validation, as
     // this could have an effect on mempool time-based eviction, as well as
     // IsCurrentForFeeEstimation() and IsInitialBlockDownload().
     // TODO: figure out the right way to synchronize around mocktime, and
     // ensure all callsites of GetTime() are accessing this safely.
     LOCK(cs_main);
 
     RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VNUM));
     SetMockTime(request.params[0].get_int64());
 
     return NullUniValue;
 }
 
 static UniValue RPCLockedMemoryInfo() {
     LockedPool::Stats stats = LockedPoolManager::Instance().stats();
     UniValue obj(UniValue::VOBJ);
     obj.push_back(Pair("used", uint64_t(stats.used)));
     obj.push_back(Pair("free", uint64_t(stats.free)));
     obj.push_back(Pair("total", uint64_t(stats.total)));
     obj.push_back(Pair("locked", uint64_t(stats.locked)));
     obj.push_back(Pair("chunks_used", uint64_t(stats.chunks_used)));
     obj.push_back(Pair("chunks_free", uint64_t(stats.chunks_free)));
     return obj;
 }
 
 static UniValue getmemoryinfo(const Config &config,
                               const JSONRPCRequest &request) {
     /* Please, avoid using the word "pool" here in the RPC interface or help,
      * as users will undoubtedly confuse it with the other "memory pool"
      */
     if (request.fHelp || request.params.size() != 0)
         throw std::runtime_error(
             "getmemoryinfo\n"
             "Returns an object containing information about memory usage.\n"
             "\nResult:\n"
             "{\n"
             "  \"locked\": {               (json object) Information about "
             "locked memory manager\n"
             "    \"used\": xxxxx,          (numeric) Number of bytes used\n"
             "    \"free\": xxxxx,          (numeric) Number of bytes available "
             "in current arenas\n"
             "    \"total\": xxxxxxx,       (numeric) Total number of bytes "
             "managed\n"
             "    \"locked\": xxxxxx,       (numeric) Amount of bytes that "
             "succeeded locking. If this number is smaller than total, locking "
             "pages failed at some point and key data could be swapped to "
             "disk.\n"
             "    \"chunks_used\": xxxxx,   (numeric) Number allocated chunks\n"
             "    \"chunks_free\": xxxxx,   (numeric) Number unused chunks\n"
             "  }\n"
             "}\n"
             "\nExamples:\n" +
             HelpExampleCli("getmemoryinfo", "") +
             HelpExampleRpc("getmemoryinfo", ""));
     UniValue obj(UniValue::VOBJ);
     obj.push_back(Pair("locked", RPCLockedMemoryInfo()));
     return obj;
 }
 
 static UniValue echo(const Config &config, const JSONRPCRequest &request) {
     if (request.fHelp)
         throw std::runtime_error(
             "echo|echojson \"message\" ...\n"
             "\nSimply echo back the input arguments. This command is for "
             "testing.\n"
             "\nThe difference between echo and echojson is that echojson has "
             "argument conversion enabled in the client-side table in"
             "bitcoin-cli and the GUI. There is no server-side difference.");
 
     return request.params;
 }
 
 // clang-format off
 static const CRPCCommand commands[] = {
     //  category            name                      actor (function)        okSafeMode
     //  ------------------- ------------------------  ----------------------  ----------
     { "control",            "getinfo",                getinfo,                true,  {} }, /* uses wallet if enabled */
     { "control",            "getmemoryinfo",          getmemoryinfo,          true,  {} },
     { "util",               "validateaddress",        validateaddress,        true,  {"address"} }, /* uses wallet if enabled */
     { "util",               "createmultisig",         createmultisig,         true,  {"nrequired","keys"} },
     { "util",               "verifymessage",          verifymessage,          true,  {"address","signature","message"} },
     { "util",               "signmessagewithprivkey", signmessagewithprivkey, true,  {"privkey","message"} },
 
     /* Not shown in help */
     { "hidden",             "setmocktime",            setmocktime,            true,  {"timestamp"}},
     { "hidden",             "echo",                   echo,                   true,  {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}},
     { "hidden",             "echojson",               echo,                   true,  {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}},
 };
 // clang-format on
 
 void RegisterMiscRPCCommands(CRPCTable &t) {
     for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
         t.appendCommand(commands[vcidx].name, &commands[vcidx]);
 }
diff --git a/src/rpc/protocol.cpp b/src/rpc/protocol.cpp
index 531f665b5..8aa561f1d 100644
--- a/src/rpc/protocol.cpp
+++ b/src/rpc/protocol.cpp
@@ -1,120 +1,120 @@
 // Copyright (c) 2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #include "rpc/protocol.h"
 
 #include "random.h"
 #include "tinyformat.h"
 #include "util.h"
 #include "utilstrencodings.h"
 #include "utiltime.h"
 #include "version.h"
 
 #include <cstdint>
 #include <fstream>
 
 /**
  * JSON-RPC protocol.  Bitcoin speaks version 1.0 for maximum compatibility, but
  * uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were
  * unspecified (HTTP errors and contents of 'error').
  *
  * 1.0 spec: http://json-rpc.org/wiki/specification
  * 1.2 spec: http://jsonrpc.org/historical/json-rpc-over-http.html
  */
 
 UniValue JSONRPCRequestObj(const std::string &strMethod, const UniValue &params,
                            const UniValue &id) {
     UniValue request(UniValue::VOBJ);
     request.push_back(Pair("method", strMethod));
     request.push_back(Pair("params", params));
     request.push_back(Pair("id", id));
     return request;
 }
 
 UniValue JSONRPCReplyObj(const UniValue &result, const UniValue &error,
                          const UniValue &id) {
     UniValue reply(UniValue::VOBJ);
     if (!error.isNull())
         reply.push_back(Pair("result", NullUniValue));
     else
         reply.push_back(Pair("result", result));
     reply.push_back(Pair("error", error));
     reply.push_back(Pair("id", id));
     return reply;
 }
 
 std::string JSONRPCReply(const UniValue &result, const UniValue &error,
                          const UniValue &id) {
     UniValue reply = JSONRPCReplyObj(result, error, id);
     return reply.write() + "\n";
 }
 
 UniValue JSONRPCError(int code, const std::string &message) {
     UniValue error(UniValue::VOBJ);
     error.push_back(Pair("code", code));
     error.push_back(Pair("message", message));
     return error;
 }
 
 /** Username used when cookie authentication is in use (arbitrary, only for
  * recognizability in debugging/logging purposes)
  */
 static const std::string COOKIEAUTH_USER = "__cookie__";
 /** Default name for auth cookie file */
 static const std::string COOKIEAUTH_FILE = ".cookie";
 
 boost::filesystem::path GetAuthCookieFile() {
     boost::filesystem::path path(GetArg("-rpccookiefile", COOKIEAUTH_FILE));
     if (!path.is_complete()) path = GetDataDir() / path;
     return path;
 }
 
 bool GenerateAuthCookie(std::string *cookie_out) {
     const size_t COOKIE_SIZE = 32;
-    unsigned char rand_pwd[COOKIE_SIZE];
+    uint8_t rand_pwd[COOKIE_SIZE];
     GetRandBytes(rand_pwd, COOKIE_SIZE);
     std::string cookie =
         COOKIEAUTH_USER + ":" + HexStr(rand_pwd, rand_pwd + COOKIE_SIZE);
 
     /** the umask determines what permissions are used to create this file -
      * these are set to 077 in init.cpp unless overridden with -sysperms.
      */
     std::ofstream file;
     boost::filesystem::path filepath = GetAuthCookieFile();
     file.open(filepath.string().c_str());
     if (!file.is_open()) {
         LogPrintf("Unable to open cookie authentication file %s for writing\n",
                   filepath.string());
         return false;
     }
     file << cookie;
     file.close();
     LogPrintf("Generated RPC authentication cookie %s\n", filepath.string());
 
     if (cookie_out) *cookie_out = cookie;
     return true;
 }
 
 bool GetAuthCookie(std::string *cookie_out) {
     std::ifstream file;
     std::string cookie;
     boost::filesystem::path filepath = GetAuthCookieFile();
     file.open(filepath.string().c_str());
     if (!file.is_open()) return false;
     std::getline(file, cookie);
     file.close();
 
     if (cookie_out) *cookie_out = cookie;
     return true;
 }
 
 void DeleteAuthCookie() {
     try {
         boost::filesystem::remove(GetAuthCookieFile());
     } catch (const boost::filesystem::filesystem_error &e) {
         LogPrintf("%s: Unable to remove random auth cookie file: %s\n",
                   __func__, e.what());
     }
 }
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
index f63bccb17..b0974f8d3 100644
--- a/src/rpc/rawtransaction.cpp
+++ b/src/rpc/rawtransaction.cpp
@@ -1,1195 +1,1192 @@
 // Copyright (c) 2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #include "base58.h"
 #include "chain.h"
 #include "coins.h"
 #include "config.h"
 #include "consensus/validation.h"
 #include "core_io.h"
 #include "init.h"
 #include "keystore.h"
 #include "merkleblock.h"
 #include "net.h"
 #include "policy/policy.h"
 #include "primitives/transaction.h"
 #include "rpc/server.h"
 #include "script/script.h"
 #include "script/script_error.h"
 #include "script/sign.h"
 #include "script/standard.h"
 #include "txmempool.h"
 #include "uint256.h"
 #include "utilstrencodings.h"
 #include "validation.h"
 #ifdef ENABLE_WALLET
 #include "wallet/wallet.h"
 #endif
 
 #include <cstdint>
 
 #include <univalue.h>
 
 void ScriptPubKeyToJSON(const CScript &scriptPubKey, UniValue &out,
                         bool fIncludeHex) {
     txnouttype type;
     std::vector<CTxDestination> addresses;
     int nRequired;
 
     out.push_back(Pair("asm", ScriptToAsmStr(scriptPubKey)));
     if (fIncludeHex) {
         out.push_back(
             Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
     }
 
     if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) {
         out.push_back(Pair("type", GetTxnOutputType(type)));
         return;
     }
 
     out.push_back(Pair("reqSigs", nRequired));
     out.push_back(Pair("type", GetTxnOutputType(type)));
 
     UniValue a(UniValue::VARR);
     for (const CTxDestination &addr : addresses) {
         a.push_back(CBitcoinAddress(addr).ToString());
     }
 
     out.push_back(Pair("addresses", a));
 }
 
 void TxToJSON(const CTransaction &tx, const uint256 hashBlock,
               UniValue &entry) {
     entry.push_back(Pair("txid", tx.GetId().GetHex()));
     entry.push_back(Pair("hash", tx.GetHash().GetHex()));
     entry.push_back(Pair(
         "size", (int)::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION)));
     entry.push_back(Pair("version", tx.nVersion));
     entry.push_back(Pair("locktime", (int64_t)tx.nLockTime));
 
     UniValue vin(UniValue::VARR);
     for (unsigned int i = 0; i < tx.vin.size(); i++) {
         const CTxIn &txin = tx.vin[i];
         UniValue in(UniValue::VOBJ);
         if (tx.IsCoinBase()) {
             in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(),
                                                  txin.scriptSig.end())));
         } else {
             in.push_back(Pair("txid", txin.prevout.hash.GetHex()));
             in.push_back(Pair("vout", (int64_t)txin.prevout.n));
             UniValue o(UniValue::VOBJ);
             o.push_back(Pair("asm", ScriptToAsmStr(txin.scriptSig, true)));
             o.push_back(Pair(
                 "hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
             in.push_back(Pair("scriptSig", o));
         }
 
         in.push_back(Pair("sequence", (int64_t)txin.nSequence));
         vin.push_back(in);
     }
 
     entry.push_back(Pair("vin", vin));
     UniValue vout(UniValue::VARR);
     for (unsigned int i = 0; i < tx.vout.size(); i++) {
         const CTxOut &txout = tx.vout[i];
         UniValue out(UniValue::VOBJ);
         out.push_back(Pair("value", ValueFromAmount(txout.nValue)));
         out.push_back(Pair("n", (int64_t)i));
         UniValue o(UniValue::VOBJ);
         ScriptPubKeyToJSON(txout.scriptPubKey, o, true);
         out.push_back(Pair("scriptPubKey", o));
         vout.push_back(out);
     }
 
     entry.push_back(Pair("vout", vout));
 
     if (!hashBlock.IsNull()) {
         entry.push_back(Pair("blockhash", hashBlock.GetHex()));
         BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
         if (mi != mapBlockIndex.end() && (*mi).second) {
             CBlockIndex *pindex = (*mi).second;
             if (chainActive.Contains(pindex)) {
                 entry.push_back(Pair("confirmations", 1 + chainActive.Height() -
                                                           pindex->nHeight));
                 entry.push_back(Pair("time", pindex->GetBlockTime()));
                 entry.push_back(Pair("blocktime", pindex->GetBlockTime()));
             } else {
                 entry.push_back(Pair("confirmations", 0));
             }
         }
     }
 }
 
 static UniValue getrawtransaction(const Config &config,
                                   const JSONRPCRequest &request) {
     if (request.fHelp || request.params.size() < 1 ||
         request.params.size() > 2) {
         throw std::runtime_error(
             "getrawtransaction \"txid\" ( verbose )\n"
 
             "\nNOTE: By default this function only works for mempool "
             "transactions. If the -txindex option is\n"
             "enabled, it also works for blockchain transactions.\n"
             "DEPRECATED: for now, it also works for transactions with unspent "
             "outputs.\n"
 
             "\nReturn the raw transaction data.\n"
             "\nIf verbose is 'true', returns an Object with information about "
             "'txid'.\n"
             "If verbose is 'false' or omitted, returns a string that is "
             "serialized, hex-encoded data for 'txid'.\n"
 
             "\nArguments:\n"
             "1. \"txid\"      (string, required) The transaction id\n"
             "2. verbose       (bool, optional, default=false) If false, return "
             "a string, otherwise return a json object\n"
 
             "\nResult (if verbose is not set or set to false):\n"
             "\"data\"      (string) The serialized, hex-encoded data for "
             "'txid'\n"
 
             "\nResult (if verbose is set to true):\n"
             "{\n"
             "  \"hex\" : \"data\",       (string) The serialized, hex-encoded "
             "data for 'txid'\n"
             "  \"txid\" : \"id\",        (string) The transaction id (same as "
             "provided)\n"
             "  \"hash\" : \"id\",        (string) The transaction hash "
             "(differs from txid for witness transactions)\n"
             "  \"size\" : n,             (numeric) The serialized transaction "
             "size\n"
             "  \"version\" : n,          (numeric) The version\n"
             "  \"locktime\" : ttt,       (numeric) The lock time\n"
             "  \"vin\" : [               (array of json objects)\n"
             "     {\n"
             "       \"txid\": \"id\",    (string) The transaction id\n"
             "       \"vout\": n,         (numeric) \n"
             "       \"scriptSig\": {     (json object) The script\n"
             "         \"asm\": \"asm\",  (string) asm\n"
             "         \"hex\": \"hex\"   (string) hex\n"
             "       },\n"
             "       \"sequence\": n      (numeric) The script sequence number\n"
             "     }\n"
             "     ,...\n"
             "  ],\n"
             "  \"vout\" : [              (array of json objects)\n"
             "     {\n"
             "       \"value\" : x.xxx,            (numeric) The value in " +
             CURRENCY_UNIT +
             "\n"
             "       \"n\" : n,                    (numeric) index\n"
             "       \"scriptPubKey\" : {          (json object)\n"
             "         \"asm\" : \"asm\",          (string) the asm\n"
             "         \"hex\" : \"hex\",          (string) the hex\n"
             "         \"reqSigs\" : n,            (numeric) The required sigs\n"
             "         \"type\" : \"pubkeyhash\",  (string) The type, eg "
             "'pubkeyhash'\n"
             "         \"addresses\" : [           (json array of string)\n"
             "           \"address\"        (string) bitcoin address\n"
             "           ,...\n"
             "         ]\n"
             "       }\n"
             "     }\n"
             "     ,...\n"
             "  ],\n"
             "  \"blockhash\" : \"hash\",   (string) the block hash\n"
             "  \"confirmations\" : n,      (numeric) The confirmations\n"
             "  \"time\" : ttt,             (numeric) The transaction time in "
             "seconds since epoch (Jan 1 1970 GMT)\n"
             "  \"blocktime\" : ttt         (numeric) The block time in seconds "
             "since epoch (Jan 1 1970 GMT)\n"
             "}\n"
 
             "\nExamples:\n" +
             HelpExampleCli("getrawtransaction", "\"mytxid\"") +
             HelpExampleCli("getrawtransaction", "\"mytxid\" true") +
             HelpExampleRpc("getrawtransaction", "\"mytxid\", true"));
     }
 
     LOCK(cs_main);
 
     uint256 hash = ParseHashV(request.params[0], "parameter 1");
 
     // Accept either a bool (true) or a num (>=1) to indicate verbose output.
     bool fVerbose = false;
     if (request.params.size() > 1) {
         if (request.params[1].isNum()) {
             if (request.params[1].get_int() != 0) {
                 fVerbose = true;
             }
         } else if (request.params[1].isBool()) {
             if (request.params[1].isTrue()) {
                 fVerbose = true;
             }
         } else {
             throw JSONRPCError(
                 RPC_TYPE_ERROR,
                 "Invalid type provided. Verbose parameter must be a boolean.");
         }
     }
 
     CTransactionRef tx;
     uint256 hashBlock;
     if (!GetTransaction(config, hash, tx, hashBlock, true)) {
         throw JSONRPCError(
             RPC_INVALID_ADDRESS_OR_KEY,
             std::string(fTxIndex ? "No such mempool or blockchain transaction"
                                  : "No such mempool transaction. Use -txindex "
                                    "to enable blockchain transaction queries") +
                 ". Use gettransaction for wallet transactions.");
     }
 
     std::string strHex = EncodeHexTx(*tx, RPCSerializationFlags());
 
     if (!fVerbose) {
         return strHex;
     }
 
     UniValue result(UniValue::VOBJ);
     result.push_back(Pair("hex", strHex));
     TxToJSON(*tx, hashBlock, result);
     return result;
 }
 
 static UniValue gettxoutproof(const Config &config,
                               const JSONRPCRequest &request) {
     if (request.fHelp ||
         (request.params.size() != 1 && request.params.size() != 2)) {
         throw std::runtime_error(
             "gettxoutproof [\"txid\",...] ( blockhash )\n"
             "\nReturns a hex-encoded proof that \"txid\" was included in a "
             "block.\n"
             "\nNOTE: By default this function only works sometimes. This is "
             "when there is an\n"
             "unspent output in the utxo for this transaction. To make it "
             "always work,\n"
             "you need to maintain a transaction index, using the -txindex "
             "command line option or\n"
             "specify the block in which the transaction is included manually "
             "(by blockhash).\n"
             "\nArguments:\n"
             "1. \"txids\"       (string) A json array of txids to filter\n"
             "    [\n"
             "      \"txid\"     (string) A transaction hash\n"
             "      ,...\n"
             "    ]\n"
             "2. \"blockhash\"   (string, optional) If specified, looks for "
             "txid in the block with this hash\n"
             "\nResult:\n"
             "\"data\"           (string) A string that is a serialized, "
             "hex-encoded data for the proof.\n");
     }
 
     std::set<uint256> setTxids;
     uint256 oneTxid;
     UniValue txids = request.params[0].get_array();
     for (unsigned int idx = 0; idx < txids.size(); idx++) {
         const UniValue &txid = txids[idx];
         if (txid.get_str().length() != 64 || !IsHex(txid.get_str())) {
             throw JSONRPCError(RPC_INVALID_PARAMETER,
                                std::string("Invalid txid ") + txid.get_str());
         }
 
         uint256 hash(uint256S(txid.get_str()));
         if (setTxids.count(hash)) {
             throw JSONRPCError(
                 RPC_INVALID_PARAMETER,
                 std::string("Invalid parameter, duplicated txid: ") +
                     txid.get_str());
         }
 
         setTxids.insert(hash);
         oneTxid = hash;
     }
 
     LOCK(cs_main);
 
     CBlockIndex *pblockindex = nullptr;
 
     uint256 hashBlock;
     if (request.params.size() > 1) {
         hashBlock = uint256S(request.params[1].get_str());
         if (!mapBlockIndex.count(hashBlock))
             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
         pblockindex = mapBlockIndex[hashBlock];
     } else {
         CCoins coins;
         if (pcoinsTip->GetCoins_DONOTUSE(oneTxid, coins) && coins.nHeight > 0 &&
             coins.nHeight <= chainActive.Height())
             pblockindex = chainActive[coins.nHeight];
     }
 
     if (pblockindex == nullptr) {
         CTransactionRef tx;
         if (!GetTransaction(config, oneTxid, tx, hashBlock, false) ||
             hashBlock.IsNull()) {
             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                                "Transaction not yet in block");
         }
 
         if (!mapBlockIndex.count(hashBlock)) {
             throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt");
         }
 
         pblockindex = mapBlockIndex[hashBlock];
     }
 
     CBlock block;
     if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) {
         throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
     }
 
     unsigned int ntxFound = 0;
     for (const auto &tx : block.vtx) {
         if (setTxids.count(tx->GetId())) {
             ntxFound++;
         }
     }
 
     if (ntxFound != setTxids.size()) {
         throw JSONRPCError(
             RPC_INVALID_ADDRESS_OR_KEY,
             "(Not all) transactions not found in specified block");
     }
 
     CDataStream ssMB(SER_NETWORK, PROTOCOL_VERSION);
     CMerkleBlock mb(block, setTxids);
     ssMB << mb;
     std::string strHex = HexStr(ssMB.begin(), ssMB.end());
     return strHex;
 }
 
 static UniValue verifytxoutproof(const Config &config,
                                  const JSONRPCRequest &request) {
     if (request.fHelp || request.params.size() != 1) {
         throw std::runtime_error(
             "verifytxoutproof \"proof\"\n"
             "\nVerifies that a proof points to a transaction in a block, "
             "returning the transaction it commits to\n"
             "and throwing an RPC error if the block is not in our best chain\n"
             "\nArguments:\n"
             "1. \"proof\"    (string, required) The hex-encoded proof "
             "generated by gettxoutproof\n"
             "\nResult:\n"
             "[\"txid\"]      (array, strings) The txid(s) which the proof "
             "commits to, or empty array if the proof is invalid\n");
     }
 
     CDataStream ssMB(ParseHexV(request.params[0], "proof"), SER_NETWORK,
                      PROTOCOL_VERSION);
     CMerkleBlock merkleBlock;
     ssMB >> merkleBlock;
 
     UniValue res(UniValue::VARR);
 
     std::vector<uint256> vMatch;
     std::vector<unsigned int> vIndex;
     if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) !=
         merkleBlock.header.hashMerkleRoot) {
         return res;
     }
 
     LOCK(cs_main);
 
     if (!mapBlockIndex.count(merkleBlock.header.GetHash()) ||
         !chainActive.Contains(mapBlockIndex[merkleBlock.header.GetHash()])) {
         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                            "Block not found in chain");
     }
 
     for (const uint256 &hash : vMatch) {
         res.push_back(hash.GetHex());
     }
 
     return res;
 }
 
 static UniValue createrawtransaction(const Config &config,
                                      const JSONRPCRequest &request) {
     if (request.fHelp || request.params.size() < 2 ||
         request.params.size() > 3) {
         throw std::runtime_error(
             "createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] "
             "{\"address\":amount,\"data\":\"hex\",...} ( locktime )\n"
             "\nCreate a transaction spending the given inputs and creating new "
             "outputs.\n"
             "Outputs can be addresses or data.\n"
             "Returns hex-encoded raw transaction.\n"
             "Note that the transaction's inputs are not signed, and\n"
             "it is not stored in the wallet or transmitted to the network.\n"
 
             "\nArguments:\n"
             "1. \"inputs\"                (array, required) A json array of "
             "json objects\n"
             "     [\n"
             "       {\n"
             "         \"txid\":\"id\",    (string, required) The transaction "
             "id\n"
             "         \"vout\":n,         (numeric, required) The output "
             "number\n"
             "         \"sequence\":n      (numeric, optional) The sequence "
             "number\n"
             "       } \n"
             "       ,...\n"
             "     ]\n"
             "2. \"outputs\"               (object, required) a json object "
             "with outputs\n"
             "    {\n"
             "      \"address\": x.xxx,    (numeric or string, required) The "
             "key is the bitcoin address, the numeric value (can be string) is "
             "the " +
             CURRENCY_UNIT +
             " amount\n"
             "      \"data\": \"hex\"      (string, required) The key is "
             "\"data\", the value is hex encoded data\n"
             "      ,...\n"
             "    }\n"
             "3. locktime                  (numeric, optional, default=0) Raw "
             "locktime. Non-0 value also locktime-activates inputs\n"
             "\nResult:\n"
             "\"transaction\"              (string) hex string of the "
             "transaction\n"
 
             "\nExamples:\n" +
             HelpExampleCli("createrawtransaction",
                            "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" "
                            "\"{\\\"address\\\":0.01}\"") +
             HelpExampleCli("createrawtransaction",
                            "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" "
                            "\"{\\\"data\\\":\\\"00010203\\\"}\"") +
             HelpExampleRpc("createrawtransaction",
                            "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", "
                            "\"{\\\"address\\\":0.01}\"") +
             HelpExampleRpc("createrawtransaction",
                            "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", "
                            "\"{\\\"data\\\":\\\"00010203\\\"}\""));
     }
 
     RPCTypeCheck(request.params,
                  {UniValue::VARR, UniValue::VOBJ, UniValue::VNUM}, true);
     if (request.params[0].isNull() || request.params[1].isNull()) {
         throw JSONRPCError(
             RPC_INVALID_PARAMETER,
             "Invalid parameter, arguments 1 and 2 must be non-null");
     }
 
     UniValue inputs = request.params[0].get_array();
     UniValue sendTo = request.params[1].get_obj();
 
     CMutableTransaction rawTx;
 
     if (request.params.size() > 2 && !request.params[2].isNull()) {
         int64_t nLockTime = request.params[2].get_int64();
         if (nLockTime < 0 || nLockTime > std::numeric_limits<uint32_t>::max()) {
             throw JSONRPCError(RPC_INVALID_PARAMETER,
                                "Invalid parameter, locktime out of range");
         }
 
         rawTx.nLockTime = nLockTime;
     }
 
     for (unsigned int idx = 0; idx < inputs.size(); idx++) {
         const UniValue &input = inputs[idx];
         const UniValue &o = input.get_obj();
 
         uint256 txid = ParseHashO(o, "txid");
 
         const UniValue &vout_v = find_value(o, "vout");
         if (!vout_v.isNum()) {
             throw JSONRPCError(RPC_INVALID_PARAMETER,
                                "Invalid parameter, missing vout key");
         }
 
         int nOutput = vout_v.get_int();
         if (nOutput < 0) {
             throw JSONRPCError(RPC_INVALID_PARAMETER,
                                "Invalid parameter, vout must be positive");
         }
 
         uint32_t nSequence =
             (rawTx.nLockTime ? std::numeric_limits<uint32_t>::max() - 1
                              : std::numeric_limits<uint32_t>::max());
 
         // Set the sequence number if passed in the parameters object.
         const UniValue &sequenceObj = find_value(o, "sequence");
         if (sequenceObj.isNum()) {
             int64_t seqNr64 = sequenceObj.get_int64();
             if (seqNr64 < 0 || seqNr64 > std::numeric_limits<uint32_t>::max()) {
                 throw JSONRPCError(
                     RPC_INVALID_PARAMETER,
                     "Invalid parameter, sequence number is out of range");
             } else {
                 nSequence = (uint32_t)seqNr64;
             }
         }
 
         CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence);
 
         rawTx.vin.push_back(in);
     }
 
     std::set<CBitcoinAddress> setAddress;
     std::vector<std::string> addrList = sendTo.getKeys();
     for (const std::string &name_ : addrList) {
         if (name_ == "data") {
-            std::vector<unsigned char> data =
+            std::vector<uint8_t> data =
                 ParseHexV(sendTo[name_].getValStr(), "Data");
 
             CTxOut out(0, CScript() << OP_RETURN << data);
             rawTx.vout.push_back(out);
         } else {
             CBitcoinAddress address(name_);
             if (!address.IsValid()) {
                 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                                    std::string("Invalid Bitcoin address: ") +
                                        name_);
             }
 
             if (setAddress.count(address)) {
                 throw JSONRPCError(
                     RPC_INVALID_PARAMETER,
                     std::string("Invalid parameter, duplicated address: ") +
                         name_);
             }
 
             setAddress.insert(address);
 
             CScript scriptPubKey = GetScriptForDestination(address.Get());
             CAmount nAmount = AmountFromValue(sendTo[name_]);
 
             CTxOut out(nAmount, scriptPubKey);
             rawTx.vout.push_back(out);
         }
     }
 
     return EncodeHexTx(rawTx);
 }
 
 static UniValue decoderawtransaction(const Config &config,
                                      const JSONRPCRequest &request) {
     if (request.fHelp || request.params.size() != 1) {
         throw std::runtime_error(
             "decoderawtransaction \"hexstring\"\n"
             "\nReturn a JSON object representing the serialized, hex-encoded "
             "transaction.\n"
 
             "\nArguments:\n"
             "1. \"hexstring\"      (string, required) The transaction hex "
             "string\n"
 
             "\nResult:\n"
             "{\n"
             "  \"txid\" : \"id\",        (string) The transaction id\n"
             "  \"hash\" : \"id\",        (string) The transaction hash "
             "(differs from txid for witness transactions)\n"
             "  \"size\" : n,             (numeric) The transaction size\n"
             "  \"version\" : n,          (numeric) The version\n"
             "  \"locktime\" : ttt,       (numeric) The lock time\n"
             "  \"vin\" : [               (array of json objects)\n"
             "     {\n"
             "       \"txid\": \"id\",    (string) The transaction id\n"
             "       \"vout\": n,         (numeric) The output number\n"
             "       \"scriptSig\": {     (json object) The script\n"
             "         \"asm\": \"asm\",  (string) asm\n"
             "         \"hex\": \"hex\"   (string) hex\n"
             "       },\n"
             "       \"sequence\": n     (numeric) The script sequence number\n"
             "     }\n"
             "     ,...\n"
             "  ],\n"
             "  \"vout\" : [             (array of json objects)\n"
             "     {\n"
             "       \"value\" : x.xxx,            (numeric) The value in " +
             CURRENCY_UNIT +
             "\n"
             "       \"n\" : n,                    (numeric) index\n"
             "       \"scriptPubKey\" : {          (json object)\n"
             "         \"asm\" : \"asm\",          (string) the asm\n"
             "         \"hex\" : \"hex\",          (string) the hex\n"
             "         \"reqSigs\" : n,            (numeric) The required sigs\n"
             "         \"type\" : \"pubkeyhash\",  (string) The type, eg "
             "'pubkeyhash'\n"
             "         \"addresses\" : [           (json array of string)\n"
             "           \"12tvKAXCxZjSmdNbao16dKXC8tRWfcF5oc\"   (string) "
             "bitcoin address\n"
             "           ,...\n"
             "         ]\n"
             "       }\n"
             "     }\n"
             "     ,...\n"
             "  ],\n"
             "}\n"
 
             "\nExamples:\n" +
             HelpExampleCli("decoderawtransaction", "\"hexstring\"") +
             HelpExampleRpc("decoderawtransaction", "\"hexstring\""));
     }
 
     LOCK(cs_main);
     RPCTypeCheck(request.params, {UniValue::VSTR});
 
     CMutableTransaction mtx;
 
     if (!DecodeHexTx(mtx, request.params[0].get_str())) {
         throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
     }
 
     UniValue result(UniValue::VOBJ);
     TxToJSON(CTransaction(std::move(mtx)), uint256(), result);
 
     return result;
 }
 
 static UniValue decodescript(const Config &config,
                              const JSONRPCRequest &request) {
     if (request.fHelp || request.params.size() != 1) {
         throw std::runtime_error(
             "decodescript \"hexstring\"\n"
             "\nDecode a hex-encoded script.\n"
             "\nArguments:\n"
             "1. \"hexstring\"     (string) the hex encoded script\n"
             "\nResult:\n"
             "{\n"
             "  \"asm\":\"asm\",   (string) Script public key\n"
             "  \"hex\":\"hex\",   (string) hex encoded public key\n"
             "  \"type\":\"type\", (string) The output type\n"
             "  \"reqSigs\": n,    (numeric) The required signatures\n"
             "  \"addresses\": [   (json array of string)\n"
             "     \"address\"     (string) bitcoin address\n"
             "     ,...\n"
             "  ],\n"
             "  \"p2sh\",\"address\" (string) address of P2SH script wrapping "
             "this redeem script (not returned if the script is already a "
             "P2SH).\n"
             "}\n"
             "\nExamples:\n" +
             HelpExampleCli("decodescript", "\"hexstring\"") +
             HelpExampleRpc("decodescript", "\"hexstring\""));
     }
 
     RPCTypeCheck(request.params, {UniValue::VSTR});
 
     UniValue r(UniValue::VOBJ);
     CScript script;
     if (request.params[0].get_str().size() > 0) {
-        std::vector<unsigned char> scriptData(
+        std::vector<uint8_t> scriptData(
             ParseHexV(request.params[0], "argument"));
         script = CScript(scriptData.begin(), scriptData.end());
     } else {
         // Empty scripts are valid.
     }
 
     ScriptPubKeyToJSON(script, r, false);
 
     UniValue type;
     type = find_value(r, "type");
 
     if (type.isStr() && type.get_str() != "scripthash") {
         // P2SH cannot be wrapped in a P2SH. If this script is already a P2SH,
         // don't return the address for a P2SH of the P2SH.
         r.push_back(
             Pair("p2sh", CBitcoinAddress(CScriptID(script)).ToString()));
     }
 
     return r;
 }
 
 /**
  * Pushes a JSON object for script verification or signing errors to vErrorsRet.
  */
 static void TxInErrorToJSON(const CTxIn &txin, UniValue &vErrorsRet,
                             const std::string &strMessage) {
     UniValue entry(UniValue::VOBJ);
     entry.push_back(Pair("txid", txin.prevout.hash.ToString()));
     entry.push_back(Pair("vout", (uint64_t)txin.prevout.n));
     entry.push_back(Pair("scriptSig",
                          HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
     entry.push_back(Pair("sequence", (uint64_t)txin.nSequence));
     entry.push_back(Pair("error", strMessage));
     vErrorsRet.push_back(entry);
 }
 
 static UniValue signrawtransaction(const Config &config,
                                    const JSONRPCRequest &request) {
     if (request.fHelp || request.params.size() < 1 ||
         request.params.size() > 4) {
         throw std::runtime_error(
             "signrawtransaction \"hexstring\" ( "
             "[{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\","
             "\"redeemScript\":\"hex\"},...] [\"privatekey1\",...] sighashtype "
             ")\n"
             "\nSign inputs for raw transaction (serialized, hex-encoded).\n"
             "The second optional argument (may be null) is an array of "
             "previous transaction outputs that\n"
             "this transaction depends on but may not yet be in the block "
             "chain.\n"
             "The third optional argument (may be null) is an array of "
             "base58-encoded private\n"
             "keys that, if given, will be the only keys used to sign the "
             "transaction.\n"
 #ifdef ENABLE_WALLET
             + HelpRequiringPassphrase() +
             "\n"
 #endif
 
             "\nArguments:\n"
             "1. \"hexstring\"     (string, required) The transaction hex "
             "string\n"
             "2. \"prevtxs\"       (string, optional) An json array of previous "
             "dependent transaction outputs\n"
             "     [               (json array of json objects, or 'null' if "
             "none provided)\n"
             "       {\n"
             "         \"txid\":\"id\",             (string, required) The "
             "transaction id\n"
             "         \"vout\":n,                  (numeric, required) The "
             "output number\n"
             "         \"scriptPubKey\": \"hex\",   (string, required) script "
             "key\n"
             "         \"redeemScript\": \"hex\",   (string, required for P2SH "
             "or P2WSH) redeem script\n"
             "         \"amount\": value            (numeric, required) The "
             "amount spent\n"
             "       }\n"
             "       ,...\n"
             "    ]\n"
             "3. \"privkeys\"     (string, optional) A json array of "
             "base58-encoded private keys for signing\n"
             "    [                  (json array of strings, or 'null' if none "
             "provided)\n"
             "      \"privatekey\"   (string) private key in base58-encoding\n"
             "      ,...\n"
             "    ]\n"
             "4. \"sighashtype\"     (string, optional, default=ALL) The "
             "signature hash type. Must be one of\n"
             "       \"ALL\"\n"
             "       \"NONE\"\n"
             "       \"SINGLE\"\n"
             "       \"ALL|ANYONECANPAY\"\n"
             "       \"NONE|ANYONECANPAY\"\n"
             "       \"SINGLE|ANYONECANPAY\"\n"
             "       \"ALL|FORKID\"\n"
             "       \"NONE|FORKID\"\n"
             "       \"SINGLE|FORKID\"\n"
             "       \"ALL|FORKID|ANYONECANPAY\"\n"
             "       \"NONE|FORKID|ANYONECANPAY\"\n"
             "       \"SINGLE|FORKID|ANYONECANPAY\"\n"
 
             "\nResult:\n"
             "{\n"
             "  \"hex\" : \"value\",           (string) The hex-encoded raw "
             "transaction with signature(s)\n"
             "  \"complete\" : true|false,   (boolean) If the transaction has a "
             "complete set of signatures\n"
             "  \"errors\" : [                 (json array of objects) Script "
             "verification errors (if there are any)\n"
             "    {\n"
             "      \"txid\" : \"hash\",           (string) The hash of the "
             "referenced, previous transaction\n"
             "      \"vout\" : n,                (numeric) The index of the "
             "output to spent and used as input\n"
             "      \"scriptSig\" : \"hex\",       (string) The hex-encoded "
             "signature script\n"
             "      \"sequence\" : n,            (numeric) Script sequence "
             "number\n"
             "      \"error\" : \"text\"           (string) Verification or "
             "signing error related to the input\n"
             "    }\n"
             "    ,...\n"
             "  ]\n"
             "}\n"
 
             "\nExamples:\n" +
             HelpExampleCli("signrawtransaction", "\"myhex\"") +
             HelpExampleRpc("signrawtransaction", "\"myhex\""));
     }
 
 #ifdef ENABLE_WALLET
     LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : nullptr);
 #else
     LOCK(cs_main);
 #endif
     RPCTypeCheck(
         request.params,
         {UniValue::VSTR, UniValue::VARR, UniValue::VARR, UniValue::VSTR}, true);
 
-    std::vector<unsigned char> txData(
-        ParseHexV(request.params[0], "argument 1"));
+    std::vector<uint8_t> txData(ParseHexV(request.params[0], "argument 1"));
     CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
     std::vector<CMutableTransaction> txVariants;
     while (!ssData.empty()) {
         try {
             CMutableTransaction tx;
             ssData >> tx;
             txVariants.push_back(tx);
         } catch (const std::exception &) {
             throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
         }
     }
 
     if (txVariants.empty()) {
         throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transaction");
     }
 
     // mergedTx will end up with all the signatures; it starts as a clone of the
     // rawtx:
     CMutableTransaction mergedTx(txVariants[0]);
 
     // Fetch previous transactions (inputs):
     CCoinsView viewDummy;
     CCoinsViewCache view(&viewDummy);
     {
         LOCK(mempool.cs);
         CCoinsViewCache &viewChain = *pcoinsTip;
         CCoinsViewMemPool viewMempool(&viewChain, mempool);
         // Temporarily switch cache backend to db+mempool view.
         view.SetBackend(viewMempool);
 
         for (const CTxIn &txin : mergedTx.vin) {
             // Load entries from viewChain into view; can fail.
             view.AccessCoin(txin.prevout);
         }
 
         // Switch back to avoid locking mempool for too long.
         view.SetBackend(viewDummy);
     }
 
     bool fGivenKeys = false;
     CBasicKeyStore tempKeystore;
     if (request.params.size() > 2 && !request.params[2].isNull()) {
         fGivenKeys = true;
         UniValue keys = request.params[2].get_array();
         for (size_t idx = 0; idx < keys.size(); idx++) {
             UniValue k = keys[idx];
             CBitcoinSecret vchSecret;
             bool fGood = vchSecret.SetString(k.get_str());
             if (!fGood) {
                 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                                    "Invalid private key");
             }
 
             CKey key = vchSecret.GetKey();
             if (!key.IsValid()) {
                 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                                    "Private key outside allowed range");
             }
 
             tempKeystore.AddKey(key);
         }
 #ifdef ENABLE_WALLET
     } else if (pwalletMain) {
         EnsureWalletIsUnlocked();
 #endif
     }
 
     // Add previous txouts given in the RPC call:
     if (request.params.size() > 1 && !request.params[1].isNull()) {
         UniValue prevTxs = request.params[1].get_array();
         for (size_t idx = 0; idx < prevTxs.size(); idx++) {
             const UniValue &p = prevTxs[idx];
             if (!p.isObject()) {
                 throw JSONRPCError(RPC_DESERIALIZATION_ERROR,
                                    "expected object with "
                                    "{\"txid'\",\"vout\",\"scriptPubKey\"}");
             }
 
             UniValue prevOut = p.get_obj();
 
             RPCTypeCheckObj(prevOut,
                             {
                                 {"txid", UniValueType(UniValue::VSTR)},
                                 {"vout", UniValueType(UniValue::VNUM)},
                                 {"scriptPubKey", UniValueType(UniValue::VSTR)},
                                 // "amount" is also required but check is done
                                 // below due to UniValue::VNUM erroneously
                                 // not accepting quoted numerics
                                 // (which are valid JSON)
                             });
 
             uint256 txid = ParseHashO(prevOut, "txid");
 
             int nOut = find_value(prevOut, "vout").get_int();
             if (nOut < 0) {
                 throw JSONRPCError(RPC_DESERIALIZATION_ERROR,
                                    "vout must be positive");
             }
 
-            std::vector<unsigned char> pkData(
-                ParseHexO(prevOut, "scriptPubKey"));
+            std::vector<uint8_t> pkData(ParseHexO(prevOut, "scriptPubKey"));
             CScript scriptPubKey(pkData.begin(), pkData.end());
 
             {
                 CCoinsModifier coins = view.ModifyCoins(txid);
                 if (coins->IsAvailable(nOut) &&
                     coins->vout[nOut].scriptPubKey != scriptPubKey) {
                     std::string err("Previous output scriptPubKey mismatch:\n");
                     err = err + ScriptToAsmStr(coins->vout[nOut].scriptPubKey) +
                           "\nvs:\n" + ScriptToAsmStr(scriptPubKey);
                     throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err);
                 }
 
                 if ((unsigned int)nOut >= coins->vout.size()) {
                     coins->vout.resize(nOut + 1);
                 }
 
                 coins->vout[nOut].scriptPubKey = scriptPubKey;
                 coins->vout[nOut].nValue = 0;
                 if (prevOut.exists("amount")) {
                     coins->vout[nOut].nValue =
                         AmountFromValue(find_value(prevOut, "amount"));
                 } else {
                     // amount param is required in replay-protected txs.
                     // Note that we must check for its presence here rather
                     // than use RPCTypeCheckObj() above, since UniValue::VNUM
                     // parser incorrectly parses numerics with quotes, eg
                     // "3.12" as a string when JSON allows it to also parse
                     // as numeric. And we have to accept numerics with quotes
                     // because our own dogfood (our rpc results) always
                     // produces decimal numbers that are quoted
                     // eg getbalance returns "3.14152" rather than 3.14152
                     throw JSONRPCError(RPC_INVALID_PARAMETER, "Missing amount");
                 }
             }
 
             // If redeemScript given and not using the local wallet (private
             // keys given), add redeemScript to the tempKeystore so it can be
             // signed:
             if (fGivenKeys && scriptPubKey.IsPayToScriptHash()) {
                 RPCTypeCheckObj(
                     prevOut, {
                                  {"txid", UniValueType(UniValue::VSTR)},
                                  {"vout", UniValueType(UniValue::VNUM)},
                                  {"scriptPubKey", UniValueType(UniValue::VSTR)},
                                  {"redeemScript", UniValueType(UniValue::VSTR)},
                              });
                 UniValue v = find_value(prevOut, "redeemScript");
                 if (!v.isNull()) {
-                    std::vector<unsigned char> rsData(
-                        ParseHexV(v, "redeemScript"));
+                    std::vector<uint8_t> rsData(ParseHexV(v, "redeemScript"));
                     CScript redeemScript(rsData.begin(), rsData.end());
                     tempKeystore.AddCScript(redeemScript);
                 }
             }
         }
     }
 
 #ifdef ENABLE_WALLET
     const CKeyStore &keystore =
         ((fGivenKeys || !pwalletMain) ? tempKeystore : *pwalletMain);
 #else
     const CKeyStore &keystore = tempKeystore;
 #endif
 
     int nHashType = SIGHASH_ALL | SIGHASH_FORKID;
     if (request.params.size() > 3 && !request.params[3].isNull()) {
         static std::map<std::string, int> mapSigHashValues = {
             {std::string("ALL"), int(SIGHASH_ALL)},
             {std::string("ALL|ANYONECANPAY"),
              int(SIGHASH_ALL | SIGHASH_ANYONECANPAY)},
             {std::string("ALL|FORKID"), int(SIGHASH_ALL | SIGHASH_FORKID)},
             {std::string("ALL|FORKID|ANYONECANPAY"),
              int(SIGHASH_ALL | SIGHASH_FORKID | SIGHASH_ANYONECANPAY)},
             {std::string("NONE"), int(SIGHASH_NONE)},
             {std::string("NONE|ANYONECANPAY"),
              int(SIGHASH_NONE | SIGHASH_ANYONECANPAY)},
             {std::string("NONE|FORKID"), int(SIGHASH_NONE | SIGHASH_FORKID)},
             {std::string("NONE|FORKID|ANYONECANPAY"),
              int(SIGHASH_NONE | SIGHASH_FORKID | SIGHASH_ANYONECANPAY)},
             {std::string("SINGLE"), int(SIGHASH_SINGLE)},
             {std::string("SINGLE|ANYONECANPAY"),
              int(SIGHASH_SINGLE | SIGHASH_ANYONECANPAY)},
             {std::string("SINGLE|FORKID"),
              int(SIGHASH_SINGLE | SIGHASH_FORKID)},
             {std::string("SINGLE|FORKID|ANYONECANPAY"),
              int(SIGHASH_SINGLE | SIGHASH_FORKID | SIGHASH_ANYONECANPAY)},
         };
         std::string strHashType = request.params[3].get_str();
         if (!mapSigHashValues.count(strHashType)) {
             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param");
         }
 
         nHashType = mapSigHashValues[strHashType];
         if ((nHashType & SIGHASH_FORKID) == 0) {
             throw JSONRPCError(RPC_INVALID_PARAMETER,
                                "Signature must use SIGHASH_FORKID");
         }
     }
 
     bool fHashSingle =
         ((nHashType & ~(SIGHASH_ANYONECANPAY | SIGHASH_FORKID)) ==
          SIGHASH_SINGLE);
 
     // Script verification errors.
     UniValue vErrors(UniValue::VARR);
 
     // Use CTransaction for the constant parts of the transaction to avoid
     // rehashing.
     const CTransaction txConst(mergedTx);
     // Sign what we can:
     for (size_t i = 0; i < mergedTx.vin.size(); i++) {
         CTxIn &txin = mergedTx.vin[i];
         const Coin &coin = view.AccessCoin(txin.prevout);
         if (coin.IsSpent()) {
             TxInErrorToJSON(txin, vErrors, "Input not found or already spent");
             continue;
         }
 
         const CScript &prevPubKey = coin.GetTxOut().scriptPubKey;
         const CAmount &amount = coin.GetTxOut().nValue;
 
         SignatureData sigdata;
         // Only sign SIGHASH_SINGLE if there's a corresponding output:
         if (!fHashSingle || (i < mergedTx.vout.size())) {
             ProduceSignature(MutableTransactionSignatureCreator(
                                  &keystore, &mergedTx, i, amount, nHashType),
                              prevPubKey, sigdata);
         }
 
         // ... and merge in other signatures:
         for (const CMutableTransaction &txv : txVariants) {
             if (txv.vin.size() > i) {
                 sigdata = CombineSignatures(
                     prevPubKey,
                     TransactionSignatureChecker(&txConst, i, amount), sigdata,
                     DataFromTransaction(txv, i));
             }
         }
 
         UpdateTransaction(mergedTx, i, sigdata);
 
         ScriptError serror = SCRIPT_ERR_OK;
         if (!VerifyScript(
                 txin.scriptSig, prevPubKey,
                 STANDARD_SCRIPT_VERIFY_FLAGS | SCRIPT_ENABLE_SIGHASH_FORKID,
                 TransactionSignatureChecker(&txConst, i, amount), &serror)) {
             TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror));
         }
     }
 
     bool fComplete = vErrors.empty();
 
     UniValue result(UniValue::VOBJ);
     result.push_back(Pair("hex", EncodeHexTx(mergedTx)));
     result.push_back(Pair("complete", fComplete));
     if (!vErrors.empty()) {
         result.push_back(Pair("errors", vErrors));
     }
 
     return result;
 }
 
 static UniValue sendrawtransaction(const Config &config,
                                    const JSONRPCRequest &request) {
     if (request.fHelp || request.params.size() < 1 ||
         request.params.size() > 2) {
         throw std::runtime_error(
             "sendrawtransaction \"hexstring\" ( allowhighfees )\n"
             "\nSubmits raw transaction (serialized, hex-encoded) to local node "
             "and network.\n"
             "\nAlso see createrawtransaction and signrawtransaction calls.\n"
             "\nArguments:\n"
             "1. \"hexstring\"    (string, required) The hex string of the raw "
             "transaction)\n"
             "2. allowhighfees    (boolean, optional, default=false) Allow high "
             "fees\n"
             "\nResult:\n"
             "\"hex\"             (string) The transaction hash in hex\n"
             "\nExamples:\n"
             "\nCreate a transaction\n" +
             HelpExampleCli("createrawtransaction",
                            "\"[{\\\"txid\\\" : "
                            "\\\"mytxid\\\",\\\"vout\\\":0}]\" "
                            "\"{\\\"myaddress\\\":0.01}\"") +
             "Sign the transaction, and get back the hex\n" +
             HelpExampleCli("signrawtransaction", "\"myhex\"") +
             "\nSend the transaction (signed hex)\n" +
             HelpExampleCli("sendrawtransaction", "\"signedhex\"") +
             "\nAs a json rpc call\n" +
             HelpExampleRpc("sendrawtransaction", "\"signedhex\""));
     }
 
     LOCK(cs_main);
     RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL});
 
     // parse hex string from parameter
     CMutableTransaction mtx;
     if (!DecodeHexTx(mtx, request.params[0].get_str())) {
         throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
     }
 
     CTransactionRef tx(MakeTransactionRef(std::move(mtx)));
     const uint256 &txid = tx->GetId();
 
     bool fLimitFree = false;
     CAmount nMaxRawTxFee = maxTxFee;
     if (request.params.size() > 1 && request.params[1].get_bool()) {
         nMaxRawTxFee = 0;
     }
 
     CCoinsViewCache &view = *pcoinsTip;
     bool fHaveChain = false;
     for (size_t o = 0; !fHaveChain && o < tx->vout.size(); o++) {
         const Coin &existingCoin = view.AccessCoin(COutPoint(txid, o));
         fHaveChain = !existingCoin.IsSpent();
     }
 
     bool fHaveMempool = mempool.exists(txid);
     if (!fHaveMempool && !fHaveChain) {
         // Push to local node and sync with wallets.
         CValidationState state;
         bool fMissingInputs;
         if (!AcceptToMemoryPool(config, mempool, state, std::move(tx),
                                 fLimitFree, &fMissingInputs, nullptr, false,
                                 nMaxRawTxFee)) {
             if (state.IsInvalid()) {
                 throw JSONRPCError(RPC_TRANSACTION_REJECTED,
                                    strprintf("%i: %s", state.GetRejectCode(),
                                              state.GetRejectReason()));
             } else {
                 if (fMissingInputs) {
                     throw JSONRPCError(RPC_TRANSACTION_ERROR, "Missing inputs");
                 }
 
                 throw JSONRPCError(RPC_TRANSACTION_ERROR,
                                    state.GetRejectReason());
             }
         }
     } else if (fHaveChain) {
         throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN,
                            "transaction already in block chain");
     }
 
     if (!g_connman) {
         throw JSONRPCError(
             RPC_CLIENT_P2P_DISABLED,
             "Error: Peer-to-peer functionality missing or disabled");
     }
 
     CInv inv(MSG_TX, txid);
     g_connman->ForEachNode([&inv](CNode *pnode) { pnode->PushInventory(inv); });
     return txid.GetHex();
 }
 
 // clang-format off
 static const CRPCCommand commands[] = {
     //  category            name                      actor (function)        okSafeMode
     //  ------------------- ------------------------  ----------------------  ----------
     { "rawtransactions",    "getrawtransaction",      getrawtransaction,      true,  {"txid","verbose"} },
     { "rawtransactions",    "createrawtransaction",   createrawtransaction,   true,  {"inputs","outputs","locktime"} },
     { "rawtransactions",    "decoderawtransaction",   decoderawtransaction,   true,  {"hexstring"} },
     { "rawtransactions",    "decodescript",           decodescript,           true,  {"hexstring"} },
     { "rawtransactions",    "sendrawtransaction",     sendrawtransaction,     false, {"hexstring","allowhighfees"} },
     { "rawtransactions",    "signrawtransaction",     signrawtransaction,     false, {"hexstring","prevtxs","privkeys","sighashtype"} }, /* uses wallet if enabled */
 
     { "blockchain",         "gettxoutproof",          gettxoutproof,          true,  {"txids", "blockhash"} },
     { "blockchain",         "verifytxoutproof",       verifytxoutproof,       true,  {"proof"} },
 };
 // clang-format on
 
 void RegisterRawTransactionRPCCommands(CRPCTable &t) {
     for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) {
         t.appendCommand(commands[vcidx].name, &commands[vcidx]);
     }
 }
diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp
index ddf857101..3c2a6e6d4 100644
--- a/src/rpc/server.cpp
+++ b/src/rpc/server.cpp
@@ -1,522 +1,522 @@
 // Copyright (c) 2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #include "rpc/server.h"
 
 #include "base58.h"
 #include "config.h"
 #include "init.h"
 #include "random.h"
 #include "sync.h"
 #include "ui_interface.h"
 #include "util.h"
 #include "utilstrencodings.h"
 
 #include <univalue.h>
 
 #include <boost/algorithm/string/case_conv.hpp> // for to_upper()
 #include <boost/bind.hpp>
 #include <boost/filesystem.hpp>
 #include <boost/shared_ptr.hpp>
 #include <boost/signals2/signal.hpp>
 #include <boost/thread.hpp>
 
 #include <memory> // for unique_ptr
 #include <set>
 #include <unordered_map>
 
 using namespace RPCServer;
 
 static bool fRPCRunning = false;
 static bool fRPCInWarmup = true;
 static std::string rpcWarmupStatus("RPC server started");
 static CCriticalSection cs_rpcWarmup;
 /* Timer-creating functions */
 static RPCTimerInterface *timerInterface = nullptr;
 /* Map of name to timer. */
 static std::map<std::string, std::unique_ptr<RPCTimerBase>> deadlineTimers;
 
 static struct CRPCSignals {
     boost::signals2::signal<void()> Started;
     boost::signals2::signal<void()> Stopped;
     boost::signals2::signal<void(const CRPCCommand &)> PreCommand;
     boost::signals2::signal<void(const CRPCCommand &)> PostCommand;
 } g_rpcSignals;
 
 void RPCServer::OnStarted(boost::function<void()> slot) {
     g_rpcSignals.Started.connect(slot);
 }
 
 void RPCServer::OnStopped(boost::function<void()> slot) {
     g_rpcSignals.Stopped.connect(slot);
 }
 
 void RPCServer::OnPreCommand(boost::function<void(const CRPCCommand &)> slot) {
     g_rpcSignals.PreCommand.connect(boost::bind(slot, _1));
 }
 
 void RPCServer::OnPostCommand(boost::function<void(const CRPCCommand &)> slot) {
     g_rpcSignals.PostCommand.connect(boost::bind(slot, _1));
 }
 
 void RPCTypeCheck(const UniValue &params,
                   const std::list<UniValue::VType> &typesExpected,
                   bool fAllowNull) {
     unsigned int i = 0;
     for (UniValue::VType t : typesExpected) {
         if (params.size() <= i) break;
 
         const UniValue &v = params[i];
         if (!(fAllowNull && v.isNull())) {
             RPCTypeCheckArgument(v, t);
         }
         i++;
     }
 }
 
 void RPCTypeCheckArgument(const UniValue &value, UniValue::VType typeExpected) {
     if (value.type() != typeExpected) {
         throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Expected type %s, got %s",
                                                      uvTypeName(typeExpected),
                                                      uvTypeName(value.type())));
     }
 }
 
 void RPCTypeCheckObj(const UniValue &o,
                      const std::map<std::string, UniValueType> &typesExpected,
                      bool fAllowNull, bool fStrict) {
     for (const auto &t : typesExpected) {
         const UniValue &v = find_value(o, t.first);
         if (!fAllowNull && v.isNull())
             throw JSONRPCError(RPC_TYPE_ERROR,
                                strprintf("Missing %s", t.first));
 
         if (!(t.second.typeAny || v.type() == t.second.type ||
               (fAllowNull && v.isNull()))) {
             std::string err = strprintf("Expected type %s for %s, got %s",
                                         uvTypeName(t.second.type), t.first,
                                         uvTypeName(v.type()));
             throw JSONRPCError(RPC_TYPE_ERROR, err);
         }
     }
 
     if (fStrict) {
         for (const std::string &k : o.getKeys()) {
             if (typesExpected.count(k) == 0) {
                 std::string err = strprintf("Unexpected key %s", k);
                 throw JSONRPCError(RPC_TYPE_ERROR, err);
             }
         }
     }
 }
 
 CAmount AmountFromValue(const UniValue &value) {
     if (!value.isNum() && !value.isStr())
         throw JSONRPCError(RPC_TYPE_ERROR, "Amount is not a number or string");
     CAmount amount;
     if (!ParseFixedPoint(value.getValStr(), 8, &amount))
         throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
     if (!MoneyRange(amount))
         throw JSONRPCError(RPC_TYPE_ERROR, "Amount out of range");
     return amount;
 }
 
 UniValue ValueFromAmount(const CAmount &amount) {
     bool sign = amount < 0;
     int64_t n_abs = (sign ? -amount : amount);
     int64_t quotient = n_abs / COIN;
     int64_t remainder = n_abs % COIN;
     return UniValue(UniValue::VNUM, strprintf("%s%d.%08d", sign ? "-" : "",
                                               quotient, remainder));
 }
 
 uint256 ParseHashV(const UniValue &v, std::string strName) {
     std::string strHex;
     if (v.isStr()) strHex = v.get_str();
     // Note: IsHex("") is false
     if (!IsHex(strHex))
         throw JSONRPCError(RPC_INVALID_PARAMETER,
                            strName + " must be hexadecimal string (not '" +
                                strHex + "')");
     if (64 != strHex.length())
         throw JSONRPCError(RPC_INVALID_PARAMETER,
                            strprintf("%s must be of length %d (not %d)",
                                      strName, 64, strHex.length()));
     uint256 result;
     result.SetHex(strHex);
     return result;
 }
 uint256 ParseHashO(const UniValue &o, std::string strKey) {
     return ParseHashV(find_value(o, strKey), strKey);
 }
-std::vector<unsigned char> ParseHexV(const UniValue &v, std::string strName) {
+std::vector<uint8_t> ParseHexV(const UniValue &v, std::string strName) {
     std::string strHex;
     if (v.isStr()) strHex = v.get_str();
     if (!IsHex(strHex))
         throw JSONRPCError(RPC_INVALID_PARAMETER,
                            strName + " must be hexadecimal string (not '" +
                                strHex + "')");
     return ParseHex(strHex);
 }
-std::vector<unsigned char> ParseHexO(const UniValue &o, std::string strKey) {
+std::vector<uint8_t> ParseHexO(const UniValue &o, std::string strKey) {
     return ParseHexV(find_value(o, strKey), strKey);
 }
 
 /**
  * Note: This interface may still be subject to change.
  */
 std::string CRPCTable::help(Config &config,
                             const std::string &strCommand) const {
     std::string strRet;
     std::string category;
     std::set<rpcfn_type> setDone;
     std::vector<std::pair<std::string, const CRPCCommand *>> vCommands;
 
     for (std::map<std::string, const CRPCCommand *>::const_iterator mi =
              mapCommands.begin();
          mi != mapCommands.end(); ++mi)
         vCommands.push_back(
             std::make_pair(mi->second->category + mi->first, mi->second));
     sort(vCommands.begin(), vCommands.end());
 
     for (const std::pair<std::string, const CRPCCommand *> &command :
          vCommands) {
         const CRPCCommand *pcmd = command.second;
         std::string strMethod = pcmd->name;
         // We already filter duplicates, but these deprecated screw up the sort
         // order
         if (strMethod.find("label") != std::string::npos) continue;
         if ((strCommand != "" || pcmd->category == "hidden") &&
             strMethod != strCommand)
             continue;
         try {
             JSONRPCRequest jreq;
             jreq.fHelp = true;
             rpcfn_type pfn = pcmd->actor;
             if (setDone.insert(pfn).second) pfn(config, jreq);
         } catch (const std::exception &e) {
             // Help text is returned in an exception
             std::string strHelp = std::string(e.what());
             if (strCommand == "") {
                 if (strHelp.find('\n') != std::string::npos)
                     strHelp = strHelp.substr(0, strHelp.find('\n'));
 
                 if (category != pcmd->category) {
                     if (!category.empty()) strRet += "\n";
                     category = pcmd->category;
                     std::string firstLetter = category.substr(0, 1);
                     boost::to_upper(firstLetter);
                     strRet +=
                         "== " + firstLetter + category.substr(1) + " ==\n";
                 }
             }
             strRet += strHelp + "\n";
         }
     }
     if (strRet == "")
         strRet = strprintf("help: unknown command: %s\n", strCommand);
     strRet = strRet.substr(0, strRet.size() - 1);
     return strRet;
 }
 
 static UniValue help(Config &config, const JSONRPCRequest &jsonRequest) {
     if (jsonRequest.fHelp || jsonRequest.params.size() > 1)
         throw std::runtime_error(
             "help ( \"command\" )\n"
             "\nList all commands, or get help for a specified command.\n"
             "\nArguments:\n"
             "1. \"command\"     (string, optional) The command to get help on\n"
             "\nResult:\n"
             "\"text\"     (string) The help text\n");
 
     std::string strCommand;
     if (jsonRequest.params.size() > 0)
         strCommand = jsonRequest.params[0].get_str();
 
     return tableRPC.help(config, strCommand);
 }
 
 static UniValue stop(const Config &config, const JSONRPCRequest &jsonRequest) {
     // Accept the deprecated and ignored 'detach' boolean argument
     if (jsonRequest.fHelp || jsonRequest.params.size() > 1)
         throw std::runtime_error("stop\n"
                                  "\nStop Bitcoin server.");
     // Event loop will exit after current HTTP requests have been handled, so
     // this reply will get back to the client.
     StartShutdown();
     return "Bitcoin server stopping";
 }
 
 /**
  * Call Table
  */
 // clang-format off
 static const CRPCCommand vRPCCommands[] = {
     //  category            name                      actor (function)        okSafe argNames
     //  ------------------- ------------------------  ----------------------  ------ ----------
     /* Overall control/query calls */
     { "control",            "help",                   help,                   true,  {"command"}  },
     { "control",            "stop",                   stop,                   true,  {}  },
 };
 // clang-format on
 
 CRPCTable::CRPCTable() {
     unsigned int vcidx;
     for (vcidx = 0; vcidx < (sizeof(vRPCCommands) / sizeof(vRPCCommands[0]));
          vcidx++) {
         const CRPCCommand *pcmd;
 
         pcmd = &vRPCCommands[vcidx];
         mapCommands[pcmd->name] = pcmd;
     }
 }
 
 const CRPCCommand *CRPCTable::operator[](const std::string &name) const {
     std::map<std::string, const CRPCCommand *>::const_iterator it =
         mapCommands.find(name);
     if (it == mapCommands.end()) return nullptr;
     return (*it).second;
 }
 
 bool CRPCTable::appendCommand(const std::string &name,
                               const CRPCCommand *pcmd) {
     if (IsRPCRunning()) return false;
 
     // don't allow overwriting for now
     std::map<std::string, const CRPCCommand *>::const_iterator it =
         mapCommands.find(name);
     if (it != mapCommands.end()) return false;
 
     mapCommands[name] = pcmd;
     return true;
 }
 
 bool StartRPC() {
     LogPrint("rpc", "Starting RPC\n");
     fRPCRunning = true;
     g_rpcSignals.Started();
     return true;
 }
 
 void InterruptRPC() {
     LogPrint("rpc", "Interrupting RPC\n");
     // Interrupt e.g. running longpolls
     fRPCRunning = false;
 }
 
 void StopRPC() {
     LogPrint("rpc", "Stopping RPC\n");
     deadlineTimers.clear();
     DeleteAuthCookie();
     g_rpcSignals.Stopped();
 }
 
 bool IsRPCRunning() {
     return fRPCRunning;
 }
 
 void SetRPCWarmupStatus(const std::string &newStatus) {
     LOCK(cs_rpcWarmup);
     rpcWarmupStatus = newStatus;
 }
 
 void SetRPCWarmupFinished() {
     LOCK(cs_rpcWarmup);
     assert(fRPCInWarmup);
     fRPCInWarmup = false;
 }
 
 bool RPCIsInWarmup(std::string *outStatus) {
     LOCK(cs_rpcWarmup);
     if (outStatus) *outStatus = rpcWarmupStatus;
     return fRPCInWarmup;
 }
 
 void JSONRPCRequest::parse(const UniValue &valRequest) {
     // Parse request
     if (!valRequest.isObject())
         throw JSONRPCError(RPC_INVALID_REQUEST, "Invalid Request object");
     const UniValue &request = valRequest.get_obj();
 
     // Parse id now so errors from here on will have the id
     id = find_value(request, "id");
 
     // Parse method
     UniValue valMethod = find_value(request, "method");
     if (valMethod.isNull())
         throw JSONRPCError(RPC_INVALID_REQUEST, "Missing method");
     if (!valMethod.isStr())
         throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string");
     strMethod = valMethod.get_str();
     if (strMethod != "getblocktemplate")
         LogPrint("rpc", "ThreadRPCServer method=%s\n",
                  SanitizeString(strMethod));
 
     // Parse params
     UniValue valParams = find_value(request, "params");
     if (valParams.isArray() || valParams.isObject())
         params = valParams;
     else if (valParams.isNull())
         params = UniValue(UniValue::VARR);
     else
         throw JSONRPCError(RPC_INVALID_REQUEST,
                            "Params must be an array or object");
 }
 
 static UniValue JSONRPCExecOne(Config &config, const UniValue &req) {
     UniValue rpc_result(UniValue::VOBJ);
 
     JSONRPCRequest jreq;
     try {
         jreq.parse(req);
 
         UniValue result = tableRPC.execute(config, jreq);
         rpc_result = JSONRPCReplyObj(result, NullUniValue, jreq.id);
     } catch (const UniValue &objError) {
         rpc_result = JSONRPCReplyObj(NullUniValue, objError, jreq.id);
     } catch (const std::exception &e) {
         rpc_result = JSONRPCReplyObj(
             NullUniValue, JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);
     }
 
     return rpc_result;
 }
 
 std::string JSONRPCExecBatch(Config &config, const UniValue &vReq) {
     UniValue ret(UniValue::VARR);
     for (unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++) {
         ret.push_back(JSONRPCExecOne(config, vReq[reqIdx]));
     }
 
     return ret.write() + "\n";
 }
 
 /**
  * Process named arguments into a vector of positional arguments, based on the
  * passed-in specification for the RPC call's arguments.
  */
 static inline JSONRPCRequest
 transformNamedArguments(const JSONRPCRequest &in,
                         const std::vector<std::string> &argNames) {
     JSONRPCRequest out = in;
     out.params = UniValue(UniValue::VARR);
     // Build a map of parameters, and remove ones that have been processed, so
     // that we can throw a focused error if there is an unknown one.
     const std::vector<std::string> &keys = in.params.getKeys();
     const std::vector<UniValue> &values = in.params.getValues();
     std::unordered_map<std::string, const UniValue *> argsIn;
     for (size_t i = 0; i < keys.size(); ++i) {
         argsIn[keys[i]] = &values[i];
     }
     // Process expected parameters.
     int hole = 0;
     for (const std::string &argName : argNames) {
         auto fr = argsIn.find(argName);
         if (fr != argsIn.end()) {
             for (int i = 0; i < hole; ++i) {
                 // Fill hole between specified parameters with JSON nulls, but
                 // not at the end (for backwards compatibility with calls that
                 // act based on number of specified parameters).
                 out.params.push_back(UniValue());
             }
             hole = 0;
             out.params.push_back(*fr->second);
             argsIn.erase(fr);
         } else {
             hole += 1;
         }
     }
     // If there are still arguments in the argsIn map, this is an error.
     if (!argsIn.empty()) {
         throw JSONRPCError(RPC_INVALID_PARAMETER,
                            "Unknown named parameter " + argsIn.begin()->first);
     }
     // Return request with named arguments transformed to positional arguments
     return out;
 }
 
 UniValue CRPCTable::execute(Config &config,
                             const JSONRPCRequest &request) const {
     // Return immediately if in warmup
     {
         LOCK(cs_rpcWarmup);
         if (fRPCInWarmup) throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus);
     }
 
     // Find method
     const CRPCCommand *pcmd = tableRPC[request.strMethod];
     if (!pcmd) throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found");
 
     g_rpcSignals.PreCommand(*pcmd);
 
     try {
         // Execute, convert arguments to array if necessary
         if (request.params.isObject()) {
             return pcmd->actor(
                 config, transformNamedArguments(request, pcmd->argNames));
         } else {
             return pcmd->actor(config, request);
         }
     } catch (const std::exception &e) {
         throw JSONRPCError(RPC_MISC_ERROR, e.what());
     }
 
     g_rpcSignals.PostCommand(*pcmd);
 }
 
 std::vector<std::string> CRPCTable::listCommands() const {
     std::vector<std::string> commandList;
     typedef std::map<std::string, const CRPCCommand *> commandMap;
 
     std::transform(mapCommands.begin(), mapCommands.end(),
                    std::back_inserter(commandList),
                    boost::bind(&commandMap::value_type::first, _1));
     return commandList;
 }
 
 std::string HelpExampleCli(const std::string &methodname,
                            const std::string &args) {
     return "> bitcoin-cli " + methodname + " " + args + "\n";
 }
 
 std::string HelpExampleRpc(const std::string &methodname,
                            const std::string &args) {
     return "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", "
            "\"id\":\"curltest\", "
            "\"method\": \"" +
            methodname + "\", \"params\": [" + args +
            "] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/\n";
 }
 
 void RPCSetTimerInterfaceIfUnset(RPCTimerInterface *iface) {
     if (!timerInterface) timerInterface = iface;
 }
 
 void RPCSetTimerInterface(RPCTimerInterface *iface) {
     timerInterface = iface;
 }
 
 void RPCUnsetTimerInterface(RPCTimerInterface *iface) {
     if (timerInterface == iface) timerInterface = nullptr;
 }
 
 void RPCRunLater(const std::string &name, boost::function<void(void)> func,
                  int64_t nSeconds) {
     if (!timerInterface)
         throw JSONRPCError(RPC_INTERNAL_ERROR,
                            "No timer handler registered for RPC");
     deadlineTimers.erase(name);
     LogPrint("rpc", "queue run of timer %s in %i seconds (using %s)\n", name,
              nSeconds, timerInterface->Name());
     deadlineTimers.emplace(
         name, std::unique_ptr<RPCTimerBase>(
                   timerInterface->NewTimer(func, nSeconds * 1000)));
 }
 
 int RPCSerializationFlags() {
     return 0;
 }
 
 CRPCTable tableRPC;
diff --git a/src/rpc/server.h b/src/rpc/server.h
index 5fb6140e1..8abbedcef 100644
--- a/src/rpc/server.h
+++ b/src/rpc/server.h
@@ -1,244 +1,242 @@
 // Copyright (c) 2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_RPCSERVER_H
 #define BITCOIN_RPCSERVER_H
 
 #include "amount.h"
 #include "rpc/protocol.h"
 #include "uint256.h"
 
 #include <cstdint>
 #include <functional>
 #include <list>
 #include <map>
 #include <string>
 
 #include <boost/function.hpp>
 
 #include <univalue.h>
 
 static const unsigned int DEFAULT_RPC_SERIALIZE_VERSION = 1;
 
 class CRPCCommand;
 
 namespace RPCServer {
 void OnStarted(boost::function<void()> slot);
 void OnStopped(boost::function<void()> slot);
 void OnPreCommand(boost::function<void(const CRPCCommand &)> slot);
 void OnPostCommand(boost::function<void(const CRPCCommand &)> slot);
 }
 
 class CBlockIndex;
 class Config;
 class CNetAddr;
 
 /** Wrapper for UniValue::VType, which includes typeAny:
  * Used to denote don't care type. Only used by RPCTypeCheckObj */
 struct UniValueType {
     UniValueType(UniValue::VType _type) : typeAny(false), type(_type) {}
     UniValueType() : typeAny(true) {}
     bool typeAny;
     UniValue::VType type;
 };
 
 class JSONRPCRequest {
 public:
     UniValue id;
     std::string strMethod;
     UniValue params;
     bool fHelp;
     std::string URI;
     std::string authUser;
 
     JSONRPCRequest() {
         id = NullUniValue;
         params = NullUniValue;
         fHelp = false;
     }
 
     void parse(const UniValue &valRequest);
 };
 
 /** Query whether RPC is running */
 bool IsRPCRunning();
 
 /**
  * Set the RPC warmup status.  When this is done, all RPC calls will error out
  * immediately with RPC_IN_WARMUP.
  */
 void SetRPCWarmupStatus(const std::string &newStatus);
 /* Mark warmup as done.  RPC calls will be processed from now on.  */
 void SetRPCWarmupFinished();
 
 /* returns the current warmup state.  */
 bool RPCIsInWarmup(std::string *statusOut);
 
 /**
  * Type-check arguments; throws JSONRPCError if wrong type given. Does not check
  * that the right number of arguments are passed, just that any passed are the
  * correct type.
  */
 void RPCTypeCheck(const UniValue &params,
                   const std::list<UniValue::VType> &typesExpected,
                   bool fAllowNull = false);
 
 /**
  * Type-check one argument; throws JSONRPCError if wrong type given.
  */
 void RPCTypeCheckArgument(const UniValue &value, UniValue::VType typeExpected);
 
 /*
   Check for expected keys/value types in an Object.
 */
 void RPCTypeCheckObj(const UniValue &o,
                      const std::map<std::string, UniValueType> &typesExpected,
                      bool fAllowNull = false, bool fStrict = false);
 
 /** Opaque base class for timers returned by NewTimerFunc.
  * This provides no methods at the moment, but makes sure that delete cleans up
  * the whole state.
  */
 class RPCTimerBase {
 public:
     virtual ~RPCTimerBase() {}
 };
 
 /**
  * RPC timer "driver".
  */
 class RPCTimerInterface {
 public:
     virtual ~RPCTimerInterface() {}
     /** Implementation name */
     virtual const char *Name() = 0;
     /** Factory function for timers.
      * RPC will call the function to create a timer that will call func in
      * *millis* milliseconds.
      * @note As the RPC mechanism is backend-neutral, it can use different
      * implementations of timers.
      * This is needed to cope with the case in which there is no HTTP server,
      * but only GUI RPC console, and to break the dependency of pcserver on
      * httprpc.
      */
     virtual RPCTimerBase *NewTimer(boost::function<void(void)> &func,
                                    int64_t millis) = 0;
 };
 
 /** Set the factory function for timers */
 void RPCSetTimerInterface(RPCTimerInterface *iface);
 /** Set the factory function for timer, but only, if unset */
 void RPCSetTimerInterfaceIfUnset(RPCTimerInterface *iface);
 /** Unset factory function for timers */
 void RPCUnsetTimerInterface(RPCTimerInterface *iface);
 
 /**
  * Run func nSeconds from now.
  * Overrides previous timer <name> (if any).
  */
 void RPCRunLater(const std::string &name, boost::function<void(void)> func,
                  int64_t nSeconds);
 
 typedef UniValue (*rpcfn_type)(Config &config,
                                const JSONRPCRequest &jsonRequest);
 typedef UniValue (*const_rpcfn_type)(const Config &config,
                                      const JSONRPCRequest &jsonRequest);
 
 class CRPCCommand {
 public:
     std::string category;
     std::string name;
     rpcfn_type actor;
     bool okSafeMode;
     std::vector<std::string> argNames;
 
     CRPCCommand(std::string _category, std::string _name, rpcfn_type _actor,
                 bool _okSafeMode, std::vector<std::string> _argNames)
         : category{std::move(_category)}, name{std::move(_name)}, actor{_actor},
           okSafeMode{_okSafeMode}, argNames{std::move(_argNames)} {}
 
     /**
      * It is safe to cast from void(const int*) to void(int*) but C++ do not
      * understand type variance. As a result, we need to do the dirty job
      * ourselves.
      */
     CRPCCommand(std::string _category, std::string _name,
                 const_rpcfn_type _actor, bool _okSafeMode,
                 std::vector<std::string> _argNames)
         : category{std::move(_category)}, name{std::move(_name)},
           actor{reinterpret_cast<rpcfn_type>(_actor)}, okSafeMode{_okSafeMode},
           argNames{std::move(_argNames)} {}
 };
 
 /**
  * Bitcoin RPC command dispatcher.
  */
 class CRPCTable {
 private:
     std::map<std::string, const CRPCCommand *> mapCommands;
 
 public:
     CRPCTable();
     const CRPCCommand *operator[](const std::string &name) const;
     std::string help(Config &config, const std::string &name) const;
 
     /**
      * Execute a method.
      * @param request The JSONRPCRequest to execute
      * @returns Result of the call.
      * @throws an exception (UniValue) when an error happens.
      */
     UniValue execute(Config &config, const JSONRPCRequest &request) const;
 
     /**
     * Returns a list of registered commands
     * @returns List of registered commands.
     */
     std::vector<std::string> listCommands() const;
 
     /**
      * Appends a CRPCCommand to the dispatch table.
      * Returns false if RPC server is already running (dump concurrency
      * protection).
      * Commands cannot be overwritten (returns false).
      */
     bool appendCommand(const std::string &name, const CRPCCommand *pcmd);
 };
 
 extern CRPCTable tableRPC;
 
 /**
  * Utilities: convert hex-encoded Values
  * (throws error if not hex).
  */
 extern uint256 ParseHashV(const UniValue &v, std::string strName);
 extern uint256 ParseHashO(const UniValue &o, std::string strKey);
-extern std::vector<unsigned char> ParseHexV(const UniValue &v,
-                                            std::string strName);
-extern std::vector<unsigned char> ParseHexO(const UniValue &o,
-                                            std::string strKey);
+extern std::vector<uint8_t> ParseHexV(const UniValue &v, std::string strName);
+extern std::vector<uint8_t> ParseHexO(const UniValue &o, std::string strKey);
 
 extern int64_t nWalletUnlockTime;
 extern CAmount AmountFromValue(const UniValue &value);
 extern UniValue ValueFromAmount(const CAmount &amount);
 extern double GetDifficulty(const CBlockIndex *blockindex = nullptr);
 extern std::string HelpRequiringPassphrase();
 extern std::string HelpExampleCli(const std::string &methodname,
                                   const std::string &args);
 extern std::string HelpExampleRpc(const std::string &methodname,
                                   const std::string &args);
 
 extern void EnsureWalletIsUnlocked();
 
 bool StartRPC();
 void InterruptRPC();
 void StopRPC();
 std::string JSONRPCExecBatch(Config &config, const UniValue &vReq);
 void RPCNotifyBlockChange(bool ibd, const CBlockIndex *);
 
 // Retrieves any serialization flags requested in command line argument
 int RPCSerializationFlags();
 
 #endif // BITCOIN_RPCSERVER_H
diff --git a/src/script/bitcoinconsensus.cpp b/src/script/bitcoinconsensus.cpp
index bc4bf095e..de40430c1 100644
--- a/src/script/bitcoinconsensus.cpp
+++ b/src/script/bitcoinconsensus.cpp
@@ -1,132 +1,131 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #include "bitcoinconsensus.h"
 
 #include "primitives/transaction.h"
 #include "pubkey.h"
 #include "script/interpreter.h"
 #include "version.h"
 
 namespace {
 
 /** A class that deserializes a single CTransaction one time. */
 class TxInputStream {
 public:
-    TxInputStream(int nTypeIn, int nVersionIn, const unsigned char *txTo,
+    TxInputStream(int nTypeIn, int nVersionIn, const uint8_t *txTo,
                   size_t txToLen)
         : m_type(nTypeIn), m_version(nVersionIn), m_data(txTo),
           m_remaining(txToLen) {}
 
     void read(char *pch, size_t nSize) {
         if (nSize > m_remaining)
             throw std::ios_base::failure(std::string(__func__) +
                                          ": end of data");
 
         if (pch == nullptr)
             throw std::ios_base::failure(std::string(__func__) +
                                          ": bad destination buffer");
 
         if (m_data == nullptr)
             throw std::ios_base::failure(std::string(__func__) +
                                          ": bad source buffer");
 
         memcpy(pch, m_data, nSize);
         m_remaining -= nSize;
         m_data += nSize;
     }
 
     template <typename T> TxInputStream &operator>>(T &obj) {
         ::Unserialize(*this, obj);
         return *this;
     }
 
     int GetVersion() const { return m_version; }
     int GetType() const { return m_type; }
 
 private:
     const int m_type;
     const int m_version;
-    const unsigned char *m_data;
+    const uint8_t *m_data;
     size_t m_remaining;
 };
 
 inline int set_error(bitcoinconsensus_error *ret,
                      bitcoinconsensus_error serror) {
     if (ret) *ret = serror;
     return 0;
 }
 
 struct ECCryptoClosure {
     ECCVerifyHandle handle;
 };
 
 ECCryptoClosure instance_of_eccryptoclosure;
 }
 
 /** Check that all specified flags are part of the libconsensus interface. */
 static bool verify_flags(unsigned int flags) {
     return (flags & ~(bitcoinconsensus_SCRIPT_FLAGS_VERIFY_ALL)) == 0;
 }
 
-static int verify_script(const unsigned char *scriptPubKey,
+static int verify_script(const uint8_t *scriptPubKey,
                          unsigned int scriptPubKeyLen, CAmount amount,
-                         const unsigned char *txTo, unsigned int txToLen,
+                         const uint8_t *txTo, unsigned int txToLen,
                          unsigned int nIn, unsigned int flags,
                          bitcoinconsensus_error *err) {
     if (!verify_flags(flags)) {
         return bitcoinconsensus_ERR_INVALID_FLAGS;
     }
     try {
         TxInputStream stream(SER_NETWORK, PROTOCOL_VERSION, txTo, txToLen);
         CTransaction tx(deserialize, stream);
         if (nIn >= tx.vin.size())
             return set_error(err, bitcoinconsensus_ERR_TX_INDEX);
         if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen)
             return set_error(err, bitcoinconsensus_ERR_TX_SIZE_MISMATCH);
 
         // Regardless of the verification result, the tx did not error.
         set_error(err, bitcoinconsensus_ERR_OK);
 
         PrecomputedTransactionData txdata(tx);
         return VerifyScript(
             tx.vin[nIn].scriptSig,
             CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), flags,
             TransactionSignatureChecker(&tx, nIn, amount, txdata), nullptr);
     } catch (const std::exception &) {
         // Error deserializing
         return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE);
     }
 }
 
 int bitcoinconsensus_verify_script_with_amount(
-    const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen,
-    int64_t amount, const unsigned char *txTo, unsigned int txToLen,
-    unsigned int nIn, unsigned int flags, bitcoinconsensus_error *err) {
+    const uint8_t *scriptPubKey, unsigned int scriptPubKeyLen, int64_t amount,
+    const uint8_t *txTo, unsigned int txToLen, unsigned int nIn,
+    unsigned int flags, bitcoinconsensus_error *err) {
     CAmount am(amount);
     return ::verify_script(scriptPubKey, scriptPubKeyLen, am, txTo, txToLen,
                            nIn, flags, err);
 }
 
-int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey,
+int bitcoinconsensus_verify_script(const uint8_t *scriptPubKey,
                                    unsigned int scriptPubKeyLen,
-                                   const unsigned char *txTo,
-                                   unsigned int txToLen, unsigned int nIn,
-                                   unsigned int flags,
+                                   const uint8_t *txTo, unsigned int txToLen,
+                                   unsigned int nIn, unsigned int flags,
                                    bitcoinconsensus_error *err) {
     if (flags & bitcoinconsensus_SCRIPT_ENABLE_SIGHASH_FORKID ||
         flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS_DEPRECATED) {
         return set_error(err, bitcoinconsensus_ERR_AMOUNT_REQUIRED);
     }
 
     CAmount am(0);
     return ::verify_script(scriptPubKey, scriptPubKeyLen, am, txTo, txToLen,
                            nIn, flags, err);
 }
 
 unsigned int bitcoinconsensus_version() {
     // Just use the API version for now
     return BITCOINCONSENSUS_API_VER;
 }
diff --git a/src/script/bitcoinconsensus.h b/src/script/bitcoinconsensus.h
index e6d4cb4fa..021039b73 100644
--- a/src/script/bitcoinconsensus.h
+++ b/src/script/bitcoinconsensus.h
@@ -1,94 +1,94 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_BITCOINCONSENSUS_H
 #define BITCOIN_BITCOINCONSENSUS_H
 
 #include <cstdint>
 
 #if defined(BUILD_BITCOIN_INTERNAL) && defined(HAVE_CONFIG_H)
 #include "config/bitcoin-config.h"
 #if defined(_WIN32)
 #if defined(DLL_EXPORT)
 #if defined(HAVE_FUNC_ATTRIBUTE_DLLEXPORT)
 #define EXPORT_SYMBOL __declspec(dllexport)
 #else
 #define EXPORT_SYMBOL
 #endif
 #endif
 #elif defined(HAVE_FUNC_ATTRIBUTE_VISIBILITY)
 #define EXPORT_SYMBOL __attribute__((visibility("default")))
 #endif
 #elif defined(MSC_VER) && !defined(STATIC_LIBBITCOINCONSENSUS)
 #define EXPORT_SYMBOL __declspec(dllimport)
 #endif
 
 #ifndef EXPORT_SYMBOL
 #define EXPORT_SYMBOL
 #endif
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 #define BITCOINCONSENSUS_API_VER 1
 
 typedef enum bitcoinconsensus_error_t {
     bitcoinconsensus_ERR_OK = 0,
     bitcoinconsensus_ERR_TX_INDEX,
     bitcoinconsensus_ERR_TX_SIZE_MISMATCH,
     bitcoinconsensus_ERR_TX_DESERIALIZE,
     bitcoinconsensus_ERR_AMOUNT_REQUIRED,
     bitcoinconsensus_ERR_INVALID_FLAGS,
 } bitcoinconsensus_error;
 
 /** Script verification flags */
 enum {
     bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NONE = 0,
     // evaluate P2SH (BIP16) subscripts
     bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH = (1U << 0),
     // enforce strict DER (BIP66) compliance
     bitcoinconsensus_SCRIPT_FLAGS_VERIFY_DERSIG = (1U << 2),
     // enforce NULLDUMMY (BIP147)
     bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NULLDUMMY = (1U << 4),
     // enable CHECKLOCKTIMEVERIFY (BIP65)
     bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9),
     // enable CHECKSEQUENCEVERIFY (BIP112)
     bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKSEQUENCEVERIFY = (1U << 10),
     // enable WITNESS (BIP141)
     bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS_DEPRECATED = (1U << 11),
     // enable SIGHASH_FORKID replay protection
     bitcoinconsensus_SCRIPT_ENABLE_SIGHASH_FORKID = (1U << 16),
     bitcoinconsensus_SCRIPT_FLAGS_VERIFY_ALL =
         bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH |
         bitcoinconsensus_SCRIPT_FLAGS_VERIFY_DERSIG |
         bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NULLDUMMY |
         bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY |
         bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKSEQUENCEVERIFY,
 };
 
 /// Returns 1 if the input nIn of the serialized transaction pointed to by txTo
 /// correctly spends the scriptPubKey pointed to by scriptPubKey under the
 /// additional constraints specified by flags.
 /// If not nullptr, err will contain an error/success code for the operation
 EXPORT_SYMBOL int bitcoinconsensus_verify_script(
-    const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen,
-    const unsigned char *txTo, unsigned int txToLen, unsigned int nIn,
+    const uint8_t *scriptPubKey, unsigned int scriptPubKeyLen,
+    const uint8_t *txTo, unsigned int txToLen, unsigned int nIn,
     unsigned int flags, bitcoinconsensus_error *err);
 
 EXPORT_SYMBOL int bitcoinconsensus_verify_script_with_amount(
-    const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen,
-    int64_t amount, const unsigned char *txTo, unsigned int txToLen,
-    unsigned int nIn, unsigned int flags, bitcoinconsensus_error *err);
+    const uint8_t *scriptPubKey, unsigned int scriptPubKeyLen, int64_t amount,
+    const uint8_t *txTo, unsigned int txToLen, unsigned int nIn,
+    unsigned int flags, bitcoinconsensus_error *err);
 
 EXPORT_SYMBOL unsigned int bitcoinconsensus_version();
 
 #ifdef __cplusplus
 } // extern "C"
 #endif
 
 #undef EXPORT_SYMBOL
 
 #endif // BITCOIN_BITCOINCONSENSUS_H
diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
index 2e590d8f5..3005e9830 100644
--- a/src/script/interpreter.cpp
+++ b/src/script/interpreter.cpp
@@ -1,1629 +1,1628 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #include "interpreter.h"
 
 #include "crypto/ripemd160.h"
 #include "crypto/sha1.h"
 #include "crypto/sha256.h"
 #include "primitives/transaction.h"
 #include "pubkey.h"
 #include "script/script.h"
 #include "uint256.h"
 
-typedef std::vector<unsigned char> valtype;
+typedef std::vector<uint8_t> valtype;
 
 namespace {
 
 inline bool set_success(ScriptError *ret) {
     if (ret) {
         *ret = SCRIPT_ERR_OK;
     }
     return true;
 }
 
 inline bool set_error(ScriptError *ret, const ScriptError serror) {
     if (ret) {
         *ret = serror;
     }
     return false;
 }
 
 } // anon namespace
 
 bool CastToBool(const valtype &vch) {
     for (size_t i = 0; i < vch.size(); i++) {
         if (vch[i] != 0) {
             // Can be negative zero
             if (i == vch.size() - 1 && vch[i] == 0x80) {
                 return false;
             }
             return true;
         }
     }
     return false;
 }
 
 /**
  * Script is a stack machine (like Forth) that evaluates a predicate
  * returning a bool indicating valid or not.  There are no loops.
  */
 #define stacktop(i) (stack.at(stack.size() + (i)))
 #define altstacktop(i) (altstack.at(altstack.size() + (i)))
 static inline void popstack(std::vector<valtype> &stack) {
     if (stack.empty()) {
         throw std::runtime_error("popstack(): stack empty");
     }
     stack.pop_back();
 }
 
 static bool IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) {
     if (vchPubKey.size() < 33) {
         //  Non-canonical public key: too short
         return false;
     }
     if (vchPubKey[0] == 0x04) {
         if (vchPubKey.size() != 65) {
             //  Non-canonical public key: invalid length for uncompressed key
             return false;
         }
     } else if (vchPubKey[0] == 0x02 || vchPubKey[0] == 0x03) {
         if (vchPubKey.size() != 33) {
             //  Non-canonical public key: invalid length for compressed key
             return false;
         }
     } else {
         //  Non-canonical public key: neither compressed nor uncompressed
         return false;
     }
     return true;
 }
 
 static bool IsCompressedPubKey(const valtype &vchPubKey) {
     if (vchPubKey.size() != 33) {
         //  Non-canonical public key: invalid length for compressed key
         return false;
     }
     if (vchPubKey[0] != 0x02 && vchPubKey[0] != 0x03) {
         //  Non-canonical public key: invalid prefix for compressed key
         return false;
     }
     return true;
 }
 
 /**
  * A canonical signature exists of: <30> <total len> <02> <len R> <R> <02> <len
  * S> <S> <hashtype>, where R and S are not negative (their first byte has its
  * highest bit not set), and not excessively padded (do not start with a 0 byte,
  * unless an otherwise negative number follows, in which case a single 0 byte is
  * necessary and even required).
  *
  * See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623
  *
  * This function is consensus-critical since BIP66.
  */
-static bool IsValidSignatureEncoding(const std::vector<unsigned char> &sig) {
+static bool IsValidSignatureEncoding(const std::vector<uint8_t> &sig) {
     // Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S]
     // [sighash]
     // * total-length: 1-byte length descriptor of everything that follows,
     // excluding the sighash byte.
     // * R-length: 1-byte length descriptor of the R value that follows.
     // * R: arbitrary-length big-endian encoded R value. It must use the
     // shortest possible encoding for a positive integers (which means no null
     // bytes at the start, except a single one when the next byte has its
     // highest bit set).
     // * S-length: 1-byte length descriptor of the S value that follows.
     // * S: arbitrary-length big-endian encoded S value. The same rules apply.
     // * sighash: 1-byte value indicating what data is hashed (not part of the
     // DER signature)
 
     // Minimum and maximum size constraints.
     if (sig.size() < 9) return false;
     if (sig.size() > 73) return false;
 
     // A signature is of type 0x30 (compound).
     if (sig[0] != 0x30) return false;
 
     // Make sure the length covers the entire signature.
     if (sig[1] != sig.size() - 3) return false;
 
     // Extract the length of the R element.
     unsigned int lenR = sig[3];
 
     // Make sure the length of the S element is still inside the signature.
     if (5 + lenR >= sig.size()) return false;
 
     // Extract the length of the S element.
     unsigned int lenS = sig[5 + lenR];
 
     // Verify that the length of the signature matches the sum of the length
     // of the elements.
     if ((size_t)(lenR + lenS + 7) != sig.size()) return false;
 
     // Check whether the R element is an integer.
     if (sig[2] != 0x02) return false;
 
     // Zero-length integers are not allowed for R.
     if (lenR == 0) return false;
 
     // Negative numbers are not allowed for R.
     if (sig[4] & 0x80) return false;
 
     // Null bytes at the start of R are not allowed, unless R would otherwise be
     // interpreted as a negative number.
     if (lenR > 1 && (sig[4] == 0x00) && !(sig[5] & 0x80)) return false;
 
     // Check whether the S element is an integer.
     if (sig[lenR + 4] != 0x02) return false;
 
     // Zero-length integers are not allowed for S.
     if (lenS == 0) return false;
 
     // Negative numbers are not allowed for S.
     if (sig[lenR + 6] & 0x80) return false;
 
     // Null bytes at the start of S are not allowed, unless S would otherwise be
     // interpreted as a negative number.
     if (lenS > 1 && (sig[lenR + 6] == 0x00) && !(sig[lenR + 7] & 0x80)) {
         return false;
     }
 
     return true;
 }
 
 static bool IsLowDERSignature(const valtype &vchSig, ScriptError *serror) {
     if (!IsValidSignatureEncoding(vchSig)) {
         return set_error(serror, SCRIPT_ERR_SIG_DER);
     }
-    std::vector<unsigned char> vchSigCopy(vchSig.begin(),
-                                          vchSig.begin() + vchSig.size() - 1);
+    std::vector<uint8_t> vchSigCopy(vchSig.begin(),
+                                    vchSig.begin() + vchSig.size() - 1);
     if (!CPubKey::CheckLowS(vchSigCopy)) {
         return set_error(serror, SCRIPT_ERR_SIG_HIGH_S);
     }
     return true;
 }
 
 static uint32_t GetHashType(const valtype &vchSig) {
     if (vchSig.size() == 0) {
         return 0;
     }
 
     return vchSig[vchSig.size() - 1];
 }
 
 static void CleanupScriptCode(CScript &scriptCode,
-                              const std::vector<unsigned char> &vchSig,
+                              const std::vector<uint8_t> &vchSig,
                               uint32_t flags) {
     // Drop the signature in scripts when SIGHASH_FORKID is not used.
     uint32_t nHashType = GetHashType(vchSig);
     if (!(flags & SCRIPT_ENABLE_SIGHASH_FORKID) ||
         !(nHashType & SIGHASH_FORKID)) {
         scriptCode.FindAndDelete(CScript(vchSig));
     }
 }
 
 static bool IsDefinedHashtypeSignature(const valtype &vchSig) {
     if (vchSig.size() == 0) {
         return false;
     }
     uint32_t nHashType =
         GetHashType(vchSig) & ~(SIGHASH_ANYONECANPAY | SIGHASH_FORKID);
     if (nHashType < SIGHASH_ALL || nHashType > SIGHASH_SINGLE) {
         return false;
     }
 
     return true;
 }
 
-bool CheckSignatureEncoding(const std::vector<unsigned char> &vchSig,
-                            uint32_t flags, ScriptError *serror) {
+bool CheckSignatureEncoding(const std::vector<uint8_t> &vchSig, uint32_t flags,
+                            ScriptError *serror) {
     // Empty signature. Not strictly DER encoded, but allowed to provide a
     // compact way to provide an invalid signature for use with CHECK(MULTI)SIG
     if (vchSig.size() == 0) {
         return true;
     }
     if ((flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S |
                   SCRIPT_VERIFY_STRICTENC)) != 0 &&
         !IsValidSignatureEncoding(vchSig)) {
         return set_error(serror, SCRIPT_ERR_SIG_DER);
     }
     if ((flags & SCRIPT_VERIFY_LOW_S) != 0 &&
         !IsLowDERSignature(vchSig, serror)) {
         // serror is set
         return false;
     }
     if ((flags & SCRIPT_VERIFY_STRICTENC) != 0) {
         if (!IsDefinedHashtypeSignature(vchSig)) {
             return set_error(serror, SCRIPT_ERR_SIG_HASHTYPE);
         }
         bool usesForkId = GetHashType(vchSig) & SIGHASH_FORKID;
         bool forkIdEnabled = flags & SCRIPT_ENABLE_SIGHASH_FORKID;
         if (!forkIdEnabled && usesForkId) {
             return set_error(serror, SCRIPT_ERR_ILLEGAL_FORKID);
         }
         if (forkIdEnabled && !usesForkId) {
             return set_error(serror, SCRIPT_ERR_MUST_USE_FORKID);
         }
     }
     return true;
 }
 
 static bool CheckPubKeyEncoding(const valtype &vchPubKey, uint32_t flags,
                                 ScriptError *serror) {
     if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 &&
         !IsCompressedOrUncompressedPubKey(vchPubKey)) {
         return set_error(serror, SCRIPT_ERR_PUBKEYTYPE);
     }
     // Only compressed keys are accepted when
     // SCRIPT_VERIFY_COMPRESSED_PUBKEYTYPE is enabled.
     if (flags & SCRIPT_VERIFY_COMPRESSED_PUBKEYTYPE &&
         !IsCompressedPubKey(vchPubKey)) {
         return set_error(serror, SCRIPT_ERR_NONCOMPRESSED_PUBKEY);
     }
     return true;
 }
 
 static bool CheckMinimalPush(const valtype &data, opcodetype opcode) {
     if (data.size() == 0) {
         // Could have used OP_0.
         return opcode == OP_0;
     }
     if (data.size() == 1 && data[0] >= 1 && data[0] <= 16) {
         // Could have used OP_1 .. OP_16.
         return opcode == OP_1 + (data[0] - 1);
     }
     if (data.size() == 1 && data[0] == 0x81) {
         // Could have used OP_1NEGATE.
         return opcode == OP_1NEGATE;
     }
     if (data.size() <= 75) {
         // Could have used a direct push (opcode indicating number of bytes
         // pushed + those bytes).
         return opcode == data.size();
     }
     if (data.size() <= 255) {
         // Could have used OP_PUSHDATA.
         return opcode == OP_PUSHDATA1;
     }
     if (data.size() <= 65535) {
         // Could have used OP_PUSHDATA2.
         return opcode == OP_PUSHDATA2;
     }
     return true;
 }
 
 bool EvalScript(std::vector<valtype> &stack, const CScript &script,
                 uint32_t flags, const BaseSignatureChecker &checker,
                 ScriptError *serror) {
     static const CScriptNum bnZero(0);
     static const CScriptNum bnOne(1);
     static const CScriptNum bnFalse(0);
     static const CScriptNum bnTrue(1);
     static const valtype vchFalse(0);
     static const valtype vchZero(0);
     static const valtype vchTrue(1, 1);
 
     CScript::const_iterator pc = script.begin();
     CScript::const_iterator pend = script.end();
     CScript::const_iterator pbegincodehash = script.begin();
     opcodetype opcode;
     valtype vchPushValue;
     std::vector<bool> vfExec;
     std::vector<valtype> altstack;
     set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR);
     if (script.size() > MAX_SCRIPT_SIZE) {
         return set_error(serror, SCRIPT_ERR_SCRIPT_SIZE);
     }
     int nOpCount = 0;
     bool fRequireMinimal = (flags & SCRIPT_VERIFY_MINIMALDATA) != 0;
 
     try {
         while (pc < pend) {
             bool fExec = !count(vfExec.begin(), vfExec.end(), false);
 
             //
             // Read instruction
             //
             if (!script.GetOp(pc, opcode, vchPushValue)) {
                 return set_error(serror, SCRIPT_ERR_BAD_OPCODE);
             }
             if (vchPushValue.size() > MAX_SCRIPT_ELEMENT_SIZE) {
                 return set_error(serror, SCRIPT_ERR_PUSH_SIZE);
             }
 
             // Note how OP_RESERVED does not count towards the opcode limit.
             if (opcode > OP_16 && ++nOpCount > MAX_OPS_PER_SCRIPT) {
                 return set_error(serror, SCRIPT_ERR_OP_COUNT);
             }
 
             if (opcode == OP_CAT || opcode == OP_SUBSTR || opcode == OP_LEFT ||
                 opcode == OP_RIGHT || opcode == OP_INVERT || opcode == OP_AND ||
                 opcode == OP_OR || opcode == OP_XOR || opcode == OP_2MUL ||
                 opcode == OP_2DIV || opcode == OP_MUL || opcode == OP_DIV ||
                 opcode == OP_MOD || opcode == OP_LSHIFT ||
                 opcode == OP_RSHIFT) {
                 // Disabled opcodes.
                 return set_error(serror, SCRIPT_ERR_DISABLED_OPCODE);
             }
 
             if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4) {
                 if (fRequireMinimal &&
                     !CheckMinimalPush(vchPushValue, opcode)) {
                     return set_error(serror, SCRIPT_ERR_MINIMALDATA);
                 }
                 stack.push_back(vchPushValue);
             } else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF))
                 switch (opcode) {
                     //
                     // Push value
                     //
                     case OP_1NEGATE:
                     case OP_1:
                     case OP_2:
                     case OP_3:
                     case OP_4:
                     case OP_5:
                     case OP_6:
                     case OP_7:
                     case OP_8:
                     case OP_9:
                     case OP_10:
                     case OP_11:
                     case OP_12:
                     case OP_13:
                     case OP_14:
                     case OP_15:
                     case OP_16: {
                         // ( -- value)
                         CScriptNum bn((int)opcode - (int)(OP_1 - 1));
                         stack.push_back(bn.getvch());
                         // The result of these opcodes should always be the
                         // minimal way to push the data they push, so no need
                         // for a CheckMinimalPush here.
                     } break;
 
                     //
                     // Control
                     //
                     case OP_NOP:
                         break;
 
                     case OP_CHECKLOCKTIMEVERIFY: {
                         if (!(flags & SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY)) {
                             // not enabled; treat as a NOP2
                             if (flags &
                                 SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) {
                                 return set_error(
                                     serror,
                                     SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);
                             }
                             break;
                         }
 
                         if (stack.size() < 1) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
 
                         // Note that elsewhere numeric opcodes are limited to
                         // operands in the range -2**31+1 to 2**31-1, however it
                         // is legal for opcodes to produce results exceeding
                         // that range. This limitation is implemented by
                         // CScriptNum's default 4-byte limit.
                         //
                         // If we kept to that limit we'd have a year 2038
                         // problem, even though the nLockTime field in
                         // transactions themselves is uint32 which only becomes
                         // meaningless after the year 2106.
                         //
                         // Thus as a special case we tell CScriptNum to accept
                         // up to 5-byte bignums, which are good until 2**39-1,
                         // well beyond the 2**32-1 limit of the nLockTime field
                         // itself.
                         const CScriptNum nLockTime(stacktop(-1),
                                                    fRequireMinimal, 5);
 
                         // In the rare event that the argument may be < 0 due to
                         // some arithmetic being done first, you can always use
                         // 0 MAX CHECKLOCKTIMEVERIFY.
                         if (nLockTime < 0) {
                             return set_error(serror,
                                              SCRIPT_ERR_NEGATIVE_LOCKTIME);
                         }
 
                         // Actually compare the specified lock time with the
                         // transaction.
                         if (!checker.CheckLockTime(nLockTime)) {
                             return set_error(serror,
                                              SCRIPT_ERR_UNSATISFIED_LOCKTIME);
                         }
 
                         break;
                     }
 
                     case OP_CHECKSEQUENCEVERIFY: {
                         if (!(flags & SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)) {
                             // not enabled; treat as a NOP3
                             if (flags &
                                 SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) {
                                 return set_error(
                                     serror,
                                     SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);
                             }
                             break;
                         }
 
                         if (stack.size() < 1) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
 
                         // nSequence, like nLockTime, is a 32-bit unsigned
                         // integer field. See the comment in CHECKLOCKTIMEVERIFY
                         // regarding 5-byte numeric operands.
                         const CScriptNum nSequence(stacktop(-1),
                                                    fRequireMinimal, 5);
 
                         // In the rare event that the argument may be < 0 due to
                         // some arithmetic being done first, you can always use
                         // 0 MAX CHECKSEQUENCEVERIFY.
                         if (nSequence < 0) {
                             return set_error(serror,
                                              SCRIPT_ERR_NEGATIVE_LOCKTIME);
                         }
 
                         // To provide for future soft-fork extensibility, if the
                         // operand has the disabled lock-time flag set,
                         // CHECKSEQUENCEVERIFY behaves as a NOP.
                         if ((nSequence &
                              CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) != 0) {
                             break;
                         }
 
                         // Compare the specified sequence number with the input.
                         if (!checker.CheckSequence(nSequence)) {
                             return set_error(serror,
                                              SCRIPT_ERR_UNSATISFIED_LOCKTIME);
                         }
 
                         break;
                     }
 
                     case OP_NOP1:
                     case OP_NOP4:
                     case OP_NOP5:
                     case OP_NOP6:
                     case OP_NOP7:
                     case OP_NOP8:
                     case OP_NOP9:
                     case OP_NOP10: {
                         if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) {
                             return set_error(
                                 serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);
                         }
                     } break;
 
                     case OP_IF:
                     case OP_NOTIF: {
                         // <expression> if [statements] [else [statements]]
                         // endif
                         bool fValue = false;
                         if (fExec) {
                             if (stack.size() < 1) {
                                 return set_error(
                                     serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL);
                             }
                             valtype &vch = stacktop(-1);
                             if (flags & SCRIPT_VERIFY_MINIMALIF) {
                                 if (vch.size() > 1) {
                                     return set_error(serror,
                                                      SCRIPT_ERR_MINIMALIF);
                                 }
                                 if (vch.size() == 1 && vch[0] != 1) {
                                     return set_error(serror,
                                                      SCRIPT_ERR_MINIMALIF);
                                 }
                             }
                             fValue = CastToBool(vch);
                             if (opcode == OP_NOTIF) {
                                 fValue = !fValue;
                             }
                             popstack(stack);
                         }
                         vfExec.push_back(fValue);
                     } break;
 
                     case OP_ELSE: {
                         if (vfExec.empty()) {
                             return set_error(serror,
                                              SCRIPT_ERR_UNBALANCED_CONDITIONAL);
                         }
                         vfExec.back() = !vfExec.back();
                     } break;
 
                     case OP_ENDIF: {
                         if (vfExec.empty()) {
                             return set_error(serror,
                                              SCRIPT_ERR_UNBALANCED_CONDITIONAL);
                         }
                         vfExec.pop_back();
                     } break;
 
                     case OP_VERIFY: {
                         // (true -- ) or
                         // (false -- false) and return
                         if (stack.size() < 1) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
                         bool fValue = CastToBool(stacktop(-1));
                         if (fValue) {
                             popstack(stack);
                         } else {
                             return set_error(serror, SCRIPT_ERR_VERIFY);
                         }
                     } break;
 
                     case OP_RETURN: {
                         return set_error(serror, SCRIPT_ERR_OP_RETURN);
                     } break;
 
                     //
                     // Stack ops
                     //
                     case OP_TOALTSTACK: {
                         if (stack.size() < 1) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
                         altstack.push_back(stacktop(-1));
                         popstack(stack);
                     } break;
 
                     case OP_FROMALTSTACK: {
                         if (altstack.size() < 1) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_ALTSTACK_OPERATION);
                         }
                         stack.push_back(altstacktop(-1));
                         popstack(altstack);
                     } break;
 
                     case OP_2DROP: {
                         // (x1 x2 -- )
                         if (stack.size() < 2) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
                         popstack(stack);
                         popstack(stack);
                     } break;
 
                     case OP_2DUP: {
                         // (x1 x2 -- x1 x2 x1 x2)
                         if (stack.size() < 2) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
                         valtype vch1 = stacktop(-2);
                         valtype vch2 = stacktop(-1);
                         stack.push_back(vch1);
                         stack.push_back(vch2);
                     } break;
 
                     case OP_3DUP: {
                         // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3)
                         if (stack.size() < 3) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
                         valtype vch1 = stacktop(-3);
                         valtype vch2 = stacktop(-2);
                         valtype vch3 = stacktop(-1);
                         stack.push_back(vch1);
                         stack.push_back(vch2);
                         stack.push_back(vch3);
                     } break;
 
                     case OP_2OVER: {
                         // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2)
                         if (stack.size() < 4) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
                         valtype vch1 = stacktop(-4);
                         valtype vch2 = stacktop(-3);
                         stack.push_back(vch1);
                         stack.push_back(vch2);
                     } break;
 
                     case OP_2ROT: {
                         // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2)
                         if (stack.size() < 6) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
                         valtype vch1 = stacktop(-6);
                         valtype vch2 = stacktop(-5);
                         stack.erase(stack.end() - 6, stack.end() - 4);
                         stack.push_back(vch1);
                         stack.push_back(vch2);
                     } break;
 
                     case OP_2SWAP: {
                         // (x1 x2 x3 x4 -- x3 x4 x1 x2)
                         if (stack.size() < 4) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
                         swap(stacktop(-4), stacktop(-2));
                         swap(stacktop(-3), stacktop(-1));
                     } break;
 
                     case OP_IFDUP: {
                         // (x - 0 | x x)
                         if (stack.size() < 1) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
                         valtype vch = stacktop(-1);
                         if (CastToBool(vch)) {
                             stack.push_back(vch);
                         }
                     } break;
 
                     case OP_DEPTH: {
                         // -- stacksize
                         CScriptNum bn(stack.size());
                         stack.push_back(bn.getvch());
                     } break;
 
                     case OP_DROP: {
                         // (x -- )
                         if (stack.size() < 1) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
                         popstack(stack);
                     } break;
 
                     case OP_DUP: {
                         // (x -- x x)
                         if (stack.size() < 1) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
                         valtype vch = stacktop(-1);
                         stack.push_back(vch);
                     } break;
 
                     case OP_NIP: {
                         // (x1 x2 -- x2)
                         if (stack.size() < 2) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
                         stack.erase(stack.end() - 2);
                     } break;
 
                     case OP_OVER: {
                         // (x1 x2 -- x1 x2 x1)
                         if (stack.size() < 2) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
                         valtype vch = stacktop(-2);
                         stack.push_back(vch);
                     } break;
 
                     case OP_PICK:
                     case OP_ROLL: {
                         // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn)
                         // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn)
                         if (stack.size() < 2) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
                         int n =
                             CScriptNum(stacktop(-1), fRequireMinimal).getint();
                         popstack(stack);
                         if (n < 0 || n >= (int)stack.size()) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
                         valtype vch = stacktop(-n - 1);
                         if (opcode == OP_ROLL) {
                             stack.erase(stack.end() - n - 1);
                         }
                         stack.push_back(vch);
                     } break;
 
                     case OP_ROT: {
                         // (x1 x2 x3 -- x2 x3 x1)
                         //  x2 x1 x3  after first swap
                         //  x2 x3 x1  after second swap
                         if (stack.size() < 3) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
                         swap(stacktop(-3), stacktop(-2));
                         swap(stacktop(-2), stacktop(-1));
                     } break;
 
                     case OP_SWAP: {
                         // (x1 x2 -- x2 x1)
                         if (stack.size() < 2) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
                         swap(stacktop(-2), stacktop(-1));
                     } break;
 
                     case OP_TUCK: {
                         // (x1 x2 -- x2 x1 x2)
                         if (stack.size() < 2) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
                         valtype vch = stacktop(-1);
                         stack.insert(stack.end() - 2, vch);
                     } break;
 
                     case OP_SIZE: {
                         // (in -- in size)
                         if (stack.size() < 1) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
                         CScriptNum bn(stacktop(-1).size());
                         stack.push_back(bn.getvch());
                     } break;
 
                     //
                     // Bitwise logic
                     //
                     case OP_EQUAL:
                     case OP_EQUALVERIFY:
                         // case OP_NOTEQUAL: // use OP_NUMNOTEQUAL
                         {
                             // (x1 x2 - bool)
                             if (stack.size() < 2) {
                                 return set_error(
                                     serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                             }
                             valtype &vch1 = stacktop(-2);
                             valtype &vch2 = stacktop(-1);
                             bool fEqual = (vch1 == vch2);
                             // OP_NOTEQUAL is disabled because it would be too
                             // easy to say something like n != 1 and have some
                             // wiseguy pass in 1 with extra zero bytes after it
                             // (numerically, 0x01 == 0x0001 == 0x000001)
                             // if (opcode == OP_NOTEQUAL)
                             //    fEqual = !fEqual;
                             popstack(stack);
                             popstack(stack);
                             stack.push_back(fEqual ? vchTrue : vchFalse);
                             if (opcode == OP_EQUALVERIFY) {
                                 if (fEqual) {
                                     popstack(stack);
                                 } else {
                                     return set_error(serror,
                                                      SCRIPT_ERR_EQUALVERIFY);
                                 }
                             }
                         }
                         break;
 
                     //
                     // Numeric
                     //
                     case OP_1ADD:
                     case OP_1SUB:
                     case OP_NEGATE:
                     case OP_ABS:
                     case OP_NOT:
                     case OP_0NOTEQUAL: {
                         // (in -- out)
                         if (stack.size() < 1) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
                         CScriptNum bn(stacktop(-1), fRequireMinimal);
                         switch (opcode) {
                             case OP_1ADD:
                                 bn += bnOne;
                                 break;
                             case OP_1SUB:
                                 bn -= bnOne;
                                 break;
                             case OP_NEGATE:
                                 bn = -bn;
                                 break;
                             case OP_ABS:
                                 if (bn < bnZero) {
                                     bn = -bn;
                                 }
                                 break;
                             case OP_NOT:
                                 bn = (bn == bnZero);
                                 break;
                             case OP_0NOTEQUAL:
                                 bn = (bn != bnZero);
                                 break;
                             default:
                                 assert(!"invalid opcode");
                                 break;
                         }
                         popstack(stack);
                         stack.push_back(bn.getvch());
                     } break;
 
                     case OP_ADD:
                     case OP_SUB:
                     case OP_BOOLAND:
                     case OP_BOOLOR:
                     case OP_NUMEQUAL:
                     case OP_NUMEQUALVERIFY:
                     case OP_NUMNOTEQUAL:
                     case OP_LESSTHAN:
                     case OP_GREATERTHAN:
                     case OP_LESSTHANOREQUAL:
                     case OP_GREATERTHANOREQUAL:
                     case OP_MIN:
                     case OP_MAX: {
                         // (x1 x2 -- out)
                         if (stack.size() < 2) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
                         CScriptNum bn1(stacktop(-2), fRequireMinimal);
                         CScriptNum bn2(stacktop(-1), fRequireMinimal);
                         CScriptNum bn(0);
                         switch (opcode) {
                             case OP_ADD:
                                 bn = bn1 + bn2;
                                 break;
 
                             case OP_SUB:
                                 bn = bn1 - bn2;
                                 break;
 
                             case OP_BOOLAND:
                                 bn = (bn1 != bnZero && bn2 != bnZero);
                                 break;
                             case OP_BOOLOR:
                                 bn = (bn1 != bnZero || bn2 != bnZero);
                                 break;
                             case OP_NUMEQUAL:
                                 bn = (bn1 == bn2);
                                 break;
                             case OP_NUMEQUALVERIFY:
                                 bn = (bn1 == bn2);
                                 break;
                             case OP_NUMNOTEQUAL:
                                 bn = (bn1 != bn2);
                                 break;
                             case OP_LESSTHAN:
                                 bn = (bn1 < bn2);
                                 break;
                             case OP_GREATERTHAN:
                                 bn = (bn1 > bn2);
                                 break;
                             case OP_LESSTHANOREQUAL:
                                 bn = (bn1 <= bn2);
                                 break;
                             case OP_GREATERTHANOREQUAL:
                                 bn = (bn1 >= bn2);
                                 break;
                             case OP_MIN:
                                 bn = (bn1 < bn2 ? bn1 : bn2);
                                 break;
                             case OP_MAX:
                                 bn = (bn1 > bn2 ? bn1 : bn2);
                                 break;
                             default:
                                 assert(!"invalid opcode");
                                 break;
                         }
                         popstack(stack);
                         popstack(stack);
                         stack.push_back(bn.getvch());
 
                         if (opcode == OP_NUMEQUALVERIFY) {
                             if (CastToBool(stacktop(-1))) {
                                 popstack(stack);
                             } else {
                                 return set_error(serror,
                                                  SCRIPT_ERR_NUMEQUALVERIFY);
                             }
                         }
                     } break;
 
                     case OP_WITHIN: {
                         // (x min max -- out)
                         if (stack.size() < 3) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
                         CScriptNum bn1(stacktop(-3), fRequireMinimal);
                         CScriptNum bn2(stacktop(-2), fRequireMinimal);
                         CScriptNum bn3(stacktop(-1), fRequireMinimal);
                         bool fValue = (bn2 <= bn1 && bn1 < bn3);
                         popstack(stack);
                         popstack(stack);
                         popstack(stack);
                         stack.push_back(fValue ? vchTrue : vchFalse);
                     } break;
 
                     //
                     // Crypto
                     //
                     case OP_RIPEMD160:
                     case OP_SHA1:
                     case OP_SHA256:
                     case OP_HASH160:
                     case OP_HASH256: {
                         // (in -- hash)
                         if (stack.size() < 1) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
                         valtype &vch = stacktop(-1);
                         valtype vchHash((opcode == OP_RIPEMD160 ||
                                          opcode == OP_SHA1 ||
                                          opcode == OP_HASH160)
                                             ? 20
                                             : 32);
                         if (opcode == OP_RIPEMD160) {
                             CRIPEMD160()
                                 .Write(vch.data(), vch.size())
                                 .Finalize(vchHash.data());
                         } else if (opcode == OP_SHA1) {
                             CSHA1()
                                 .Write(vch.data(), vch.size())
                                 .Finalize(vchHash.data());
                         } else if (opcode == OP_SHA256) {
                             CSHA256()
                                 .Write(vch.data(), vch.size())
                                 .Finalize(vchHash.data());
                         } else if (opcode == OP_HASH160) {
                             CHash160()
                                 .Write(vch.data(), vch.size())
                                 .Finalize(vchHash.data());
                         } else if (opcode == OP_HASH256) {
                             CHash256()
                                 .Write(vch.data(), vch.size())
                                 .Finalize(vchHash.data());
                         }
                         popstack(stack);
                         stack.push_back(vchHash);
                     } break;
 
                     case OP_CODESEPARATOR: {
                         // Hash starts after the code separator
                         pbegincodehash = pc;
                     } break;
 
                     case OP_CHECKSIG:
                     case OP_CHECKSIGVERIFY: {
                         // (sig pubkey -- bool)
                         if (stack.size() < 2) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
                         valtype &vchSig = stacktop(-2);
                         valtype &vchPubKey = stacktop(-1);
 
                         if (!CheckSignatureEncoding(vchSig, flags, serror) ||
                             !CheckPubKeyEncoding(vchPubKey, flags, serror)) {
                             // serror is set
                             return false;
                         }
 
                         // Subset of script starting at the most recent
                         // codeseparator
                         CScript scriptCode(pbegincodehash, pend);
                         CleanupScriptCode(scriptCode, vchSig, flags);
 
                         bool fSuccess = checker.CheckSig(vchSig, vchPubKey,
                                                          scriptCode, flags);
 
                         if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) &&
                             vchSig.size()) {
                             return set_error(serror, SCRIPT_ERR_SIG_NULLFAIL);
                         }
 
                         popstack(stack);
                         popstack(stack);
                         stack.push_back(fSuccess ? vchTrue : vchFalse);
                         if (opcode == OP_CHECKSIGVERIFY) {
                             if (fSuccess) {
                                 popstack(stack);
                             } else {
                                 return set_error(serror,
                                                  SCRIPT_ERR_CHECKSIGVERIFY);
                             }
                         }
                     } break;
 
                     case OP_CHECKMULTISIG:
                     case OP_CHECKMULTISIGVERIFY: {
                         // ([sig ...] num_of_signatures [pubkey ...]
                         // num_of_pubkeys -- bool)
 
                         int i = 1;
                         if ((int)stack.size() < i) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
 
                         int nKeysCount =
                             CScriptNum(stacktop(-i), fRequireMinimal).getint();
                         if (nKeysCount < 0 ||
                             nKeysCount > MAX_PUBKEYS_PER_MULTISIG) {
                             return set_error(serror, SCRIPT_ERR_PUBKEY_COUNT);
                         }
                         nOpCount += nKeysCount;
                         if (nOpCount > MAX_OPS_PER_SCRIPT) {
                             return set_error(serror, SCRIPT_ERR_OP_COUNT);
                         }
                         int ikey = ++i;
                         // ikey2 is the position of last non-signature item in
                         // the stack. Top stack item = 1. With
                         // SCRIPT_VERIFY_NULLFAIL, this is used for cleanup if
                         // operation fails.
                         int ikey2 = nKeysCount + 2;
                         i += nKeysCount;
                         if ((int)stack.size() < i) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
 
                         int nSigsCount =
                             CScriptNum(stacktop(-i), fRequireMinimal).getint();
                         if (nSigsCount < 0 || nSigsCount > nKeysCount) {
                             return set_error(serror, SCRIPT_ERR_SIG_COUNT);
                         }
                         int isig = ++i;
                         i += nSigsCount;
                         if ((int)stack.size() < i) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
 
                         // Subset of script starting at the most recent
                         // codeseparator
                         CScript scriptCode(pbegincodehash, pend);
 
                         // Drop the signature in pre-segwit scripts but not
                         // segwit scripts
                         for (int k = 0; k < nSigsCount; k++) {
                             valtype &vchSig = stacktop(-isig - k);
                             CleanupScriptCode(scriptCode, vchSig, flags);
                         }
 
                         bool fSuccess = true;
                         while (fSuccess && nSigsCount > 0) {
                             valtype &vchSig = stacktop(-isig);
                             valtype &vchPubKey = stacktop(-ikey);
 
                             // Note how this makes the exact order of
                             // pubkey/signature evaluation distinguishable by
                             // CHECKMULTISIG NOT if the STRICTENC flag is set.
                             // See the script_(in)valid tests for details.
                             if (!CheckSignatureEncoding(vchSig, flags,
                                                         serror) ||
                                 !CheckPubKeyEncoding(vchPubKey, flags,
                                                      serror)) {
                                 // serror is set
                                 return false;
                             }
 
                             // Check signature
                             bool fOk = checker.CheckSig(vchSig, vchPubKey,
                                                         scriptCode, flags);
 
                             if (fOk) {
                                 isig++;
                                 nSigsCount--;
                             }
                             ikey++;
                             nKeysCount--;
 
                             // If there are more signatures left than keys left,
                             // then too many signatures have failed. Exit early,
                             // without checking any further signatures.
                             if (nSigsCount > nKeysCount) {
                                 fSuccess = false;
                             }
                         }
 
                         // Clean up stack of actual arguments
                         while (i-- > 1) {
                             // If the operation failed, we require that all
                             // signatures must be empty vector
                             if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) &&
                                 !ikey2 && stacktop(-1).size()) {
                                 return set_error(serror,
                                                  SCRIPT_ERR_SIG_NULLFAIL);
                             }
                             if (ikey2 > 0) {
                                 ikey2--;
                             }
                             popstack(stack);
                         }
 
                         // A bug causes CHECKMULTISIG to consume one extra
                         // argument whose contents were not checked in any way.
                         //
                         // Unfortunately this is a potential source of
                         // mutability, so optionally verify it is exactly equal
                         // to zero prior to removing it from the stack.
                         if (stack.size() < 1) {
                             return set_error(
                                 serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                         }
                         if ((flags & SCRIPT_VERIFY_NULLDUMMY) &&
                             stacktop(-1).size()) {
                             return set_error(serror, SCRIPT_ERR_SIG_NULLDUMMY);
                         }
                         popstack(stack);
 
                         stack.push_back(fSuccess ? vchTrue : vchFalse);
 
                         if (opcode == OP_CHECKMULTISIGVERIFY) {
                             if (fSuccess) {
                                 popstack(stack);
                             } else {
                                 return set_error(
                                     serror, SCRIPT_ERR_CHECKMULTISIGVERIFY);
                             }
                         }
                     } break;
 
                     default:
                         return set_error(serror, SCRIPT_ERR_BAD_OPCODE);
                 }
 
             // Size limits
             if (stack.size() + altstack.size() > 1000) {
                 return set_error(serror, SCRIPT_ERR_STACK_SIZE);
             }
         }
     } catch (...) {
         return set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR);
     }
 
     if (!vfExec.empty()) {
         return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL);
     }
 
     return set_success(serror);
 }
 
 namespace {
 
 /**
  * Wrapper that serializes like CTransaction, but with the modifications
  *  required for the signature hash done in-place
  */
 class CTransactionSignatureSerializer {
 private:
     //!< reference to the spending transaction (the one being serialized)
     const CTransaction &txTo;
     //!< output script being consumed
     const CScript &scriptCode;
     //!< input index of txTo being signed
     const unsigned int nIn;
     //!< whether the hashtype has the SIGHASH_ANYONECANPAY flag set
     const bool fAnyoneCanPay;
     //!< whether the hashtype is SIGHASH_SINGLE
     const bool fHashSingle;
     //!< whether the hashtype is SIGHASH_NONE
     const bool fHashNone;
 
 public:
     CTransactionSignatureSerializer(const CTransaction &txToIn,
                                     const CScript &scriptCodeIn,
                                     unsigned int nInIn, uint32_t nHashTypeIn)
         : txTo(txToIn), scriptCode(scriptCodeIn), nIn(nInIn),
           fAnyoneCanPay(!!(nHashTypeIn & SIGHASH_ANYONECANPAY)),
           fHashSingle((nHashTypeIn & 0x1f) == SIGHASH_SINGLE),
           fHashNone((nHashTypeIn & 0x1f) == SIGHASH_NONE) {}
 
     /** Serialize the passed scriptCode, skipping OP_CODESEPARATORs */
     template <typename S> void SerializeScriptCode(S &s) const {
         CScript::const_iterator it = scriptCode.begin();
         CScript::const_iterator itBegin = it;
         opcodetype opcode;
         unsigned int nCodeSeparators = 0;
         while (scriptCode.GetOp(it, opcode)) {
             if (opcode == OP_CODESEPARATOR) {
                 nCodeSeparators++;
             }
         }
         ::WriteCompactSize(s, scriptCode.size() - nCodeSeparators);
         it = itBegin;
         while (scriptCode.GetOp(it, opcode)) {
             if (opcode == OP_CODESEPARATOR) {
                 s.write((char *)&itBegin[0], it - itBegin - 1);
                 itBegin = it;
             }
         }
         if (itBegin != scriptCode.end()) {
             s.write((char *)&itBegin[0], it - itBegin);
         }
     }
 
     /** Serialize an input of txTo */
     template <typename S> void SerializeInput(S &s, unsigned int nInput) const {
         // In case of SIGHASH_ANYONECANPAY, only the input being signed is
         // serialized
         if (fAnyoneCanPay) {
             nInput = nIn;
         }
         // Serialize the prevout
         ::Serialize(s, txTo.vin[nInput].prevout);
         // Serialize the script
         if (nInput != nIn) {
             // Blank out other inputs' signatures
             ::Serialize(s, CScriptBase());
         } else {
             SerializeScriptCode(s);
         }
         // Serialize the nSequence
         if (nInput != nIn && (fHashSingle || fHashNone)) {
             // let the others update at will
             ::Serialize(s, (int)0);
         } else {
             ::Serialize(s, txTo.vin[nInput].nSequence);
         }
     }
 
     /** Serialize an output of txTo */
     template <typename S>
     void SerializeOutput(S &s, unsigned int nOutput) const {
         if (fHashSingle && nOutput != nIn) {
             // Do not lock-in the txout payee at other indices as txin
             ::Serialize(s, CTxOut());
         } else {
             ::Serialize(s, txTo.vout[nOutput]);
         }
     }
 
     /** Serialize txTo */
     template <typename S> void Serialize(S &s) const {
         // Serialize nVersion
         ::Serialize(s, txTo.nVersion);
         // Serialize vin
         unsigned int nInputs = fAnyoneCanPay ? 1 : txTo.vin.size();
         ::WriteCompactSize(s, nInputs);
         for (unsigned int nInput = 0; nInput < nInputs; nInput++) {
             SerializeInput(s, nInput);
         }
         // Serialize vout
         unsigned int nOutputs =
             fHashNone ? 0 : (fHashSingle ? nIn + 1 : txTo.vout.size());
         ::WriteCompactSize(s, nOutputs);
         for (unsigned int nOutput = 0; nOutput < nOutputs; nOutput++) {
             SerializeOutput(s, nOutput);
         }
         // Serialize nLockTime
         ::Serialize(s, txTo.nLockTime);
     }
 };
 
 uint256 GetPrevoutHash(const CTransaction &txTo) {
     CHashWriter ss(SER_GETHASH, 0);
     for (size_t n = 0; n < txTo.vin.size(); n++) {
         ss << txTo.vin[n].prevout;
     }
     return ss.GetHash();
 }
 
 uint256 GetSequenceHash(const CTransaction &txTo) {
     CHashWriter ss(SER_GETHASH, 0);
     for (size_t n = 0; n < txTo.vin.size(); n++) {
         ss << txTo.vin[n].nSequence;
     }
     return ss.GetHash();
 }
 
 uint256 GetOutputsHash(const CTransaction &txTo) {
     CHashWriter ss(SER_GETHASH, 0);
     for (size_t n = 0; n < txTo.vout.size(); n++) {
         ss << txTo.vout[n];
     }
     return ss.GetHash();
 }
 
 } // anon namespace
 
 PrecomputedTransactionData::PrecomputedTransactionData(
     const CTransaction &txTo) {
     hashPrevouts = GetPrevoutHash(txTo);
     hashSequence = GetSequenceHash(txTo);
     hashOutputs = GetOutputsHash(txTo);
 }
 
 uint256 SignatureHash(const CScript &scriptCode, const CTransaction &txTo,
                       unsigned int nIn, uint32_t nHashType,
                       const CAmount &amount,
                       const PrecomputedTransactionData *cache, uint32_t flags) {
     if ((nHashType & SIGHASH_FORKID) &&
         (flags & SCRIPT_ENABLE_SIGHASH_FORKID)) {
         uint256 hashPrevouts;
         uint256 hashSequence;
         uint256 hashOutputs;
 
         if (!(nHashType & SIGHASH_ANYONECANPAY)) {
             hashPrevouts = cache ? cache->hashPrevouts : GetPrevoutHash(txTo);
         }
 
         if (!(nHashType & SIGHASH_ANYONECANPAY) &&
             (nHashType & 0x1f) != SIGHASH_SINGLE &&
             (nHashType & 0x1f) != SIGHASH_NONE) {
             hashSequence = cache ? cache->hashSequence : GetSequenceHash(txTo);
         }
 
         if ((nHashType & 0x1f) != SIGHASH_SINGLE &&
             (nHashType & 0x1f) != SIGHASH_NONE) {
             hashOutputs = cache ? cache->hashOutputs : GetOutputsHash(txTo);
         } else if ((nHashType & 0x1f) == SIGHASH_SINGLE &&
                    nIn < txTo.vout.size()) {
             CHashWriter ss(SER_GETHASH, 0);
             ss << txTo.vout[nIn];
             hashOutputs = ss.GetHash();
         }
 
         CHashWriter ss(SER_GETHASH, 0);
         // Version
         ss << txTo.nVersion;
         // Input prevouts/nSequence (none/all, depending on flags)
         ss << hashPrevouts;
         ss << hashSequence;
         // The input being signed (replacing the scriptSig with scriptCode +
         // amount). The prevout may already be contained in hashPrevout, and the
         // nSequence may already be contain in hashSequence.
         ss << txTo.vin[nIn].prevout;
         ss << static_cast<const CScriptBase &>(scriptCode);
         ss << amount;
         ss << txTo.vin[nIn].nSequence;
         // Outputs (none/one/all, depending on flags)
         ss << hashOutputs;
         // Locktime
         ss << txTo.nLockTime;
         // Sighash type
         ss << nHashType;
 
         return ss.GetHash();
     }
 
     static const uint256 one(uint256S(
         "0000000000000000000000000000000000000000000000000000000000000001"));
     if (nIn >= txTo.vin.size()) {
         //  nIn out of range
         return one;
     }
 
     // Check for invalid use of SIGHASH_SINGLE
     if ((nHashType & 0x1f) == SIGHASH_SINGLE) {
         if (nIn >= txTo.vout.size()) {
             //  nOut out of range
             return one;
         }
     }
 
     // Wrapper to serialize only the necessary parts of the transaction being
     // signed
     CTransactionSignatureSerializer txTmp(txTo, scriptCode, nIn, nHashType);
 
     // Serialize and hash
     CHashWriter ss(SER_GETHASH, 0);
     ss << txTmp << nHashType;
     return ss.GetHash();
 }
 
 bool TransactionSignatureChecker::VerifySignature(
-    const std::vector<unsigned char> &vchSig, const CPubKey &pubkey,
+    const std::vector<uint8_t> &vchSig, const CPubKey &pubkey,
     const uint256 &sighash) const {
     return pubkey.Verify(sighash, vchSig);
 }
 
 bool TransactionSignatureChecker::CheckSig(
-    const std::vector<unsigned char> &vchSigIn,
-    const std::vector<unsigned char> &vchPubKey, const CScript &scriptCode,
-    uint32_t flags) const {
+    const std::vector<uint8_t> &vchSigIn, const std::vector<uint8_t> &vchPubKey,
+    const CScript &scriptCode, uint32_t flags) const {
     CPubKey pubkey(vchPubKey);
     if (!pubkey.IsValid()) {
         return false;
     }
 
     // Hash type is one byte tacked on to the end of the signature
-    std::vector<unsigned char> vchSig(vchSigIn);
+    std::vector<uint8_t> vchSig(vchSigIn);
     if (vchSig.empty()) {
         return false;
     }
     uint32_t nHashType = GetHashType(vchSig);
     vchSig.pop_back();
 
     uint256 sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount,
                                     this->txdata, flags);
 
     if (!VerifySignature(vchSig, pubkey, sighash)) {
         return false;
     }
 
     return true;
 }
 
 bool TransactionSignatureChecker::CheckLockTime(
     const CScriptNum &nLockTime) const {
     // There are two kinds of nLockTime: lock-by-blockheight and
     // lock-by-blocktime, distinguished by whether nLockTime <
     // LOCKTIME_THRESHOLD.
     //
     // We want to compare apples to apples, so fail the script unless the type
     // of nLockTime being tested is the same as the nLockTime in the
     // transaction.
     if (!((txTo->nLockTime < LOCKTIME_THRESHOLD &&
            nLockTime < LOCKTIME_THRESHOLD) ||
           (txTo->nLockTime >= LOCKTIME_THRESHOLD &&
            nLockTime >= LOCKTIME_THRESHOLD))) {
         return false;
     }
 
     // Now that we know we're comparing apples-to-apples, the comparison is a
     // simple numeric one.
     if (nLockTime > int64_t(txTo->nLockTime)) {
         return false;
     }
 
     // Finally the nLockTime feature can be disabled and thus
     // CHECKLOCKTIMEVERIFY bypassed if every txin has been finalized by setting
     // nSequence to maxint. The transaction would be allowed into the
     // blockchain, making the opcode ineffective.
     //
     // Testing if this vin is not final is sufficient to prevent this condition.
     // Alternatively we could test all inputs, but testing just this input
     // minimizes the data required to prove correct CHECKLOCKTIMEVERIFY
     // execution.
     if (CTxIn::SEQUENCE_FINAL == txTo->vin[nIn].nSequence) {
         return false;
     }
 
     return true;
 }
 
 bool TransactionSignatureChecker::CheckSequence(
     const CScriptNum &nSequence) const {
     // Relative lock times are supported by comparing the passed in operand to
     // the sequence number of the input.
     const int64_t txToSequence = int64_t(txTo->vin[nIn].nSequence);
 
     // Fail if the transaction's version number is not set high enough to
     // trigger BIP 68 rules.
     if (static_cast<uint32_t>(txTo->nVersion) < 2) {
         return false;
     }
 
     // Sequence numbers with their most significant bit set are not consensus
     // constrained. Testing that the transaction's sequence number do not have
     // this bit set prevents using this property to get around a
     // CHECKSEQUENCEVERIFY check.
     if (txToSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) {
         return false;
     }
 
     // Mask off any bits that do not have consensus-enforced meaning before
     // doing the integer comparisons
     const uint32_t nLockTimeMask =
         CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | CTxIn::SEQUENCE_LOCKTIME_MASK;
     const int64_t txToSequenceMasked = txToSequence & nLockTimeMask;
     const CScriptNum nSequenceMasked = nSequence & nLockTimeMask;
 
     // There are two kinds of nSequence: lock-by-blockheight and
     // lock-by-blocktime, distinguished by whether nSequenceMasked <
     // CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG.
     //
     // We want to compare apples to apples, so fail the script unless the type
     // of nSequenceMasked being tested is the same as the nSequenceMasked in the
     // transaction.
     if (!((txToSequenceMasked < CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG &&
            nSequenceMasked < CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) ||
           (txToSequenceMasked >= CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG &&
            nSequenceMasked >= CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG))) {
         return false;
     }
 
     // Now that we know we're comparing apples-to-apples, the comparison is a
     // simple numeric one.
     if (nSequenceMasked > txToSequenceMasked) {
         return false;
     }
 
     return true;
 }
 
 bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey,
                   uint32_t flags, const BaseSignatureChecker &checker,
                   ScriptError *serror) {
     set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR);
 
     // If FORKID is enabled, we also ensure strict encoding.
     if (flags & SCRIPT_ENABLE_SIGHASH_FORKID) {
         flags |= SCRIPT_VERIFY_STRICTENC;
     }
 
     if ((flags & SCRIPT_VERIFY_SIGPUSHONLY) != 0 && !scriptSig.IsPushOnly()) {
         return set_error(serror, SCRIPT_ERR_SIG_PUSHONLY);
     }
 
     std::vector<valtype> stack, stackCopy;
     if (!EvalScript(stack, scriptSig, flags, checker, serror)) {
         // serror is set
         return false;
     }
     if (flags & SCRIPT_VERIFY_P2SH) {
         stackCopy = stack;
     }
     if (!EvalScript(stack, scriptPubKey, flags, checker, serror)) {
         // serror is set
         return false;
     }
     if (stack.empty()) {
         return set_error(serror, SCRIPT_ERR_EVAL_FALSE);
     }
     if (CastToBool(stack.back()) == false) {
         return set_error(serror, SCRIPT_ERR_EVAL_FALSE);
     }
 
     // Additional validation for spend-to-script-hash transactions:
     if ((flags & SCRIPT_VERIFY_P2SH) && scriptPubKey.IsPayToScriptHash()) {
         // scriptSig must be literals-only or validation fails
         if (!scriptSig.IsPushOnly()) {
             return set_error(serror, SCRIPT_ERR_SIG_PUSHONLY);
         }
 
         // Restore stack.
         swap(stack, stackCopy);
 
         // stack cannot be empty here, because if it was the P2SH  HASH <> EQUAL
         // scriptPubKey would be evaluated with an empty stack and the
         // EvalScript above would return false.
         assert(!stack.empty());
 
         const valtype &pubKeySerialized = stack.back();
         CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end());
         popstack(stack);
 
         if (!EvalScript(stack, pubKey2, flags, checker, serror)) {
             // serror is set
             return false;
         }
         if (stack.empty()) {
             return set_error(serror, SCRIPT_ERR_EVAL_FALSE);
         }
         if (!CastToBool(stack.back())) {
             return set_error(serror, SCRIPT_ERR_EVAL_FALSE);
         }
     }
 
     // The CLEANSTACK check is only performed after potential P2SH evaluation,
     // as the non-P2SH evaluation of a P2SH script will obviously not result in
     // a clean stack (the P2SH inputs remain). The same holds for witness
     // evaluation.
     if ((flags & SCRIPT_VERIFY_CLEANSTACK) != 0) {
         // Disallow CLEANSTACK without P2SH, as otherwise a switch
         // CLEANSTACK->P2SH+CLEANSTACK would be possible, which is not a
         // softfork (and P2SH should be one).
         assert((flags & SCRIPT_VERIFY_P2SH) != 0);
         if (stack.size() != 1) {
             return set_error(serror, SCRIPT_ERR_CLEANSTACK);
         }
     }
 
     return set_success(serror);
 }
diff --git a/src/script/interpreter.h b/src/script/interpreter.h
index 5e235cdf5..6fe07b7d4 100644
--- a/src/script/interpreter.h
+++ b/src/script/interpreter.h
@@ -1,194 +1,193 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_SCRIPT_INTERPRETER_H
 #define BITCOIN_SCRIPT_INTERPRETER_H
 
 #include "primitives/transaction.h"
 #include "script_error.h"
 
 #include <cstdint>
 #include <string>
 #include <vector>
 
 class CPubKey;
 class CScript;
 class CTransaction;
 class uint256;
 
 /** Signature hash types/flags */
 enum {
     SIGHASH_ALL = 1,
     SIGHASH_NONE = 2,
     SIGHASH_SINGLE = 3,
     SIGHASH_FORKID = 0x40,
     SIGHASH_ANYONECANPAY = 0x80,
 };
 
 /** Script verification flags */
 enum {
     SCRIPT_VERIFY_NONE = 0,
 
     // Evaluate P2SH subscripts (softfork safe, BIP16).
     SCRIPT_VERIFY_P2SH = (1U << 0),
 
     // Passing a non-strict-DER signature or one with undefined hashtype to a
     // checksig operation causes script failure. Evaluating a pubkey that is not
     // (0x04 + 64 bytes) or (0x02 or 0x03 + 32 bytes) by checksig causes script
     // failure.
     SCRIPT_VERIFY_STRICTENC = (1U << 1),
 
     // Passing a non-strict-DER signature to a checksig operation causes script
     // failure (softfork safe, BIP62 rule 1)
     SCRIPT_VERIFY_DERSIG = (1U << 2),
 
     // Passing a non-strict-DER signature or one with S > order/2 to a checksig
     // operation causes script failure
     // (softfork safe, BIP62 rule 5).
     SCRIPT_VERIFY_LOW_S = (1U << 3),
 
     // verify dummy stack item consumed by CHECKMULTISIG is of zero-length
     // (softfork safe, BIP62 rule 7).
     SCRIPT_VERIFY_NULLDUMMY = (1U << 4),
 
     // Using a non-push operator in the scriptSig causes script failure
     // (softfork safe, BIP62 rule 2).
     SCRIPT_VERIFY_SIGPUSHONLY = (1U << 5),
 
     // Require minimal encodings for all push operations (OP_0... OP_16,
     // OP_1NEGATE where possible, direct pushes up to 75 bytes, OP_PUSHDATA up
     // to 255 bytes, OP_PUSHDATA2 for anything larger). Evaluating any other
     // push causes the script to fail (BIP62 rule 3). In addition, whenever a
     // stack element is interpreted as a number, it must be of minimal length
     // (BIP62 rule 4).
     // (softfork safe)
     SCRIPT_VERIFY_MINIMALDATA = (1U << 6),
 
     // Discourage use of NOPs reserved for upgrades (NOP1-10)
     //
     // Provided so that nodes can avoid accepting or mining transactions
     // containing executed NOP's whose meaning may change after a soft-fork,
     // thus rendering the script invalid; with this flag set executing
     // discouraged NOPs fails the script. This verification flag will never be a
     // mandatory flag applied to scripts in a block. NOPs that are not executed,
     // e.g.  within an unexecuted IF ENDIF block, are *not* rejected.
     SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1U << 7),
 
     // Require that only a single stack element remains after evaluation. This
     // changes the success criterion from "At least one stack element must
     // remain, and when interpreted as a boolean, it must be true" to "Exactly
     // one stack element must remain, and when interpreted as a boolean, it must
     // be true".
     // (softfork safe, BIP62 rule 6)
     // Note: CLEANSTACK should never be used without P2SH or WITNESS.
     SCRIPT_VERIFY_CLEANSTACK = (1U << 8),
 
     // Verify CHECKLOCKTIMEVERIFY
     //
     // See BIP65 for details.
     SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9),
 
     // support CHECKSEQUENCEVERIFY opcode
     //
     // See BIP112 for details
     SCRIPT_VERIFY_CHECKSEQUENCEVERIFY = (1U << 10),
 
     // Making v1-v16 witness program non-standard
     //
     SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM = (1U << 12),
 
     // Segwit script only: Require the argument of OP_IF/NOTIF to be exactly
     // 0x01 or empty vector
     //
     SCRIPT_VERIFY_MINIMALIF = (1U << 13),
 
     // Signature(s) must be empty vector if an CHECK(MULTI)SIG operation failed
     //
     SCRIPT_VERIFY_NULLFAIL = (1U << 14),
 
     // Public keys in scripts must be compressed
     //
     SCRIPT_VERIFY_COMPRESSED_PUBKEYTYPE = (1U << 15),
 
     // Do we accept signature using SIGHASH_FORKID
     //
     SCRIPT_ENABLE_SIGHASH_FORKID = (1U << 16),
 };
 
-bool CheckSignatureEncoding(const std::vector<unsigned char> &vchSig,
-                            uint32_t flags, ScriptError *serror);
+bool CheckSignatureEncoding(const std::vector<uint8_t> &vchSig, uint32_t flags,
+                            ScriptError *serror);
 
 uint256 SignatureHash(const CScript &scriptCode, const CTransaction &txTo,
                       unsigned int nIn, uint32_t nHashType,
                       const CAmount &amount,
                       const PrecomputedTransactionData *cache = nullptr,
                       uint32_t flags = SCRIPT_ENABLE_SIGHASH_FORKID);
 
 class BaseSignatureChecker {
 public:
-    virtual bool CheckSig(const std::vector<unsigned char> &scriptSig,
-                          const std::vector<unsigned char> &vchPubKey,
+    virtual bool CheckSig(const std::vector<uint8_t> &scriptSig,
+                          const std::vector<uint8_t> &vchPubKey,
                           const CScript &scriptCode, uint32_t flags) const {
         return false;
     }
 
     virtual bool CheckLockTime(const CScriptNum &nLockTime) const {
         return false;
     }
 
     virtual bool CheckSequence(const CScriptNum &nSequence) const {
         return false;
     }
 
     virtual ~BaseSignatureChecker() {}
 };
 
 class TransactionSignatureChecker : public BaseSignatureChecker {
 private:
     const CTransaction *txTo;
     unsigned int nIn;
     const CAmount amount;
     const PrecomputedTransactionData *txdata;
 
 protected:
-    virtual bool VerifySignature(const std::vector<unsigned char> &vchSig,
+    virtual bool VerifySignature(const std::vector<uint8_t> &vchSig,
                                  const CPubKey &vchPubKey,
                                  const uint256 &sighash) const;
 
 public:
     TransactionSignatureChecker(const CTransaction *txToIn, unsigned int nInIn,
                                 const CAmount &amountIn)
         : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(nullptr) {}
     TransactionSignatureChecker(const CTransaction *txToIn, unsigned int nInIn,
                                 const CAmount &amountIn,
                                 const PrecomputedTransactionData &txdataIn)
         : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(&txdataIn) {}
-    bool CheckSig(const std::vector<unsigned char> &scriptSig,
-                  const std::vector<unsigned char> &vchPubKey,
+    bool CheckSig(const std::vector<uint8_t> &scriptSig,
+                  const std::vector<uint8_t> &vchPubKey,
                   const CScript &scriptCode, uint32_t flags) const;
     bool CheckLockTime(const CScriptNum &nLockTime) const;
     bool CheckSequence(const CScriptNum &nSequence) const;
 };
 
 class MutableTransactionSignatureChecker : public TransactionSignatureChecker {
 private:
     const CTransaction txTo;
 
 public:
     MutableTransactionSignatureChecker(const CMutableTransaction *txToIn,
                                        unsigned int nInIn,
                                        const CAmount &amount)
         : TransactionSignatureChecker(&txTo, nInIn, amount), txTo(*txToIn) {}
 };
 
-bool EvalScript(std::vector<std::vector<unsigned char>> &stack,
-                const CScript &script, uint32_t flags,
-                const BaseSignatureChecker &checker,
+bool EvalScript(std::vector<std::vector<uint8_t>> &stack, const CScript &script,
+                uint32_t flags, const BaseSignatureChecker &checker,
                 ScriptError *error = nullptr);
 bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey,
                   uint32_t flags, const BaseSignatureChecker &checker,
                   ScriptError *serror = nullptr);
 
 #endif // BITCOIN_SCRIPT_INTERPRETER_H
diff --git a/src/script/ismine.cpp b/src/script/ismine.cpp
index da5133dee..d7bcb1b8c 100644
--- a/src/script/ismine.cpp
+++ b/src/script/ismine.cpp
@@ -1,101 +1,101 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #include "ismine.h"
 
 #include "key.h"
 #include "keystore.h"
 #include "script/script.h"
 #include "script/sign.h"
 #include "script/standard.h"
 
-typedef std::vector<unsigned char> valtype;
+typedef std::vector<uint8_t> valtype;
 
 unsigned int HaveKeys(const std::vector<valtype> &pubkeys,
                       const CKeyStore &keystore) {
     unsigned int nResult = 0;
     for (const valtype &pubkey : pubkeys) {
         CKeyID keyID = CPubKey(pubkey).GetID();
         if (keystore.HaveKey(keyID)) ++nResult;
     }
     return nResult;
 }
 
 isminetype IsMine(const CKeyStore &keystore, const CScript &scriptPubKey) {
     bool isInvalid = false;
     return IsMine(keystore, scriptPubKey, isInvalid);
 }
 
 isminetype IsMine(const CKeyStore &keystore, const CTxDestination &dest) {
     bool isInvalid = false;
     return IsMine(keystore, dest, isInvalid);
 }
 
 isminetype IsMine(const CKeyStore &keystore, const CTxDestination &dest,
                   bool &isInvalid) {
     CScript script = GetScriptForDestination(dest);
     return IsMine(keystore, script, isInvalid);
 }
 
 isminetype IsMine(const CKeyStore &keystore, const CScript &scriptPubKey,
                   bool &isInvalid) {
     std::vector<valtype> vSolutions;
     txnouttype whichType;
     if (!Solver(scriptPubKey, whichType, vSolutions)) {
         if (keystore.HaveWatchOnly(scriptPubKey))
             return ISMINE_WATCH_UNSOLVABLE;
         return ISMINE_NO;
     }
 
     CKeyID keyID;
     switch (whichType) {
         case TX_NONSTANDARD:
         case TX_NULL_DATA:
             break;
         case TX_PUBKEY:
             keyID = CPubKey(vSolutions[0]).GetID();
             if (keystore.HaveKey(keyID)) return ISMINE_SPENDABLE;
             break;
         case TX_PUBKEYHASH:
             keyID = CKeyID(uint160(vSolutions[0]));
             if (keystore.HaveKey(keyID)) return ISMINE_SPENDABLE;
             break;
         case TX_SCRIPTHASH: {
             CScriptID scriptID = CScriptID(uint160(vSolutions[0]));
             CScript subscript;
             if (keystore.GetCScript(scriptID, subscript)) {
                 isminetype ret = IsMine(keystore, subscript, isInvalid);
                 if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE ||
                     (ret == ISMINE_NO && isInvalid))
                     return ret;
             }
             break;
         }
         case TX_MULTISIG: {
             // Only consider transactions "mine" if we own ALL the keys
             // involved. Multi-signature transactions that are partially owned
             // (somebody else has a key that can spend them) enable
             // spend-out-from-under-you attacks, especially in shared-wallet
             // situations.
             std::vector<valtype> keys(vSolutions.begin() + 1,
                                       vSolutions.begin() + vSolutions.size() -
                                           1);
             if (HaveKeys(keys, keystore) == keys.size())
                 return ISMINE_SPENDABLE;
             break;
         }
     }
 
     if (keystore.HaveWatchOnly(scriptPubKey)) {
         // TODO: This could be optimized some by doing some work after the above
         // solver
         SignatureData sigs;
         return ProduceSignature(DummySignatureCreator(&keystore), scriptPubKey,
                                 sigs)
                    ? ISMINE_WATCH_SOLVABLE
                    : ISMINE_WATCH_UNSOLVABLE;
     }
     return ISMINE_NO;
 }
diff --git a/src/script/script.cpp b/src/script/script.cpp
index 87135509b..f2627647e 100644
--- a/src/script/script.cpp
+++ b/src/script/script.cpp
@@ -1,381 +1,381 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #include "script.h"
 
 #include "tinyformat.h"
 #include "utilstrencodings.h"
 
 const char *GetOpName(opcodetype opcode) {
     switch (opcode) {
         // push value
         case OP_0:
             return "0";
         case OP_PUSHDATA1:
             return "OP_PUSHDATA1";
         case OP_PUSHDATA2:
             return "OP_PUSHDATA2";
         case OP_PUSHDATA4:
             return "OP_PUSHDATA4";
         case OP_1NEGATE:
             return "-1";
         case OP_RESERVED:
             return "OP_RESERVED";
         case OP_1:
             return "1";
         case OP_2:
             return "2";
         case OP_3:
             return "3";
         case OP_4:
             return "4";
         case OP_5:
             return "5";
         case OP_6:
             return "6";
         case OP_7:
             return "7";
         case OP_8:
             return "8";
         case OP_9:
             return "9";
         case OP_10:
             return "10";
         case OP_11:
             return "11";
         case OP_12:
             return "12";
         case OP_13:
             return "13";
         case OP_14:
             return "14";
         case OP_15:
             return "15";
         case OP_16:
             return "16";
 
         // control
         case OP_NOP:
             return "OP_NOP";
         case OP_VER:
             return "OP_VER";
         case OP_IF:
             return "OP_IF";
         case OP_NOTIF:
             return "OP_NOTIF";
         case OP_VERIF:
             return "OP_VERIF";
         case OP_VERNOTIF:
             return "OP_VERNOTIF";
         case OP_ELSE:
             return "OP_ELSE";
         case OP_ENDIF:
             return "OP_ENDIF";
         case OP_VERIFY:
             return "OP_VERIFY";
         case OP_RETURN:
             return "OP_RETURN";
 
         // stack ops
         case OP_TOALTSTACK:
             return "OP_TOALTSTACK";
         case OP_FROMALTSTACK:
             return "OP_FROMALTSTACK";
         case OP_2DROP:
             return "OP_2DROP";
         case OP_2DUP:
             return "OP_2DUP";
         case OP_3DUP:
             return "OP_3DUP";
         case OP_2OVER:
             return "OP_2OVER";
         case OP_2ROT:
             return "OP_2ROT";
         case OP_2SWAP:
             return "OP_2SWAP";
         case OP_IFDUP:
             return "OP_IFDUP";
         case OP_DEPTH:
             return "OP_DEPTH";
         case OP_DROP:
             return "OP_DROP";
         case OP_DUP:
             return "OP_DUP";
         case OP_NIP:
             return "OP_NIP";
         case OP_OVER:
             return "OP_OVER";
         case OP_PICK:
             return "OP_PICK";
         case OP_ROLL:
             return "OP_ROLL";
         case OP_ROT:
             return "OP_ROT";
         case OP_SWAP:
             return "OP_SWAP";
         case OP_TUCK:
             return "OP_TUCK";
 
         // splice ops
         case OP_CAT:
             return "OP_CAT";
         case OP_SUBSTR:
             return "OP_SUBSTR";
         case OP_LEFT:
             return "OP_LEFT";
         case OP_RIGHT:
             return "OP_RIGHT";
         case OP_SIZE:
             return "OP_SIZE";
 
         // bit logic
         case OP_INVERT:
             return "OP_INVERT";
         case OP_AND:
             return "OP_AND";
         case OP_OR:
             return "OP_OR";
         case OP_XOR:
             return "OP_XOR";
         case OP_EQUAL:
             return "OP_EQUAL";
         case OP_EQUALVERIFY:
             return "OP_EQUALVERIFY";
         case OP_RESERVED1:
             return "OP_RESERVED1";
         case OP_RESERVED2:
             return "OP_RESERVED2";
 
         // numeric
         case OP_1ADD:
             return "OP_1ADD";
         case OP_1SUB:
             return "OP_1SUB";
         case OP_2MUL:
             return "OP_2MUL";
         case OP_2DIV:
             return "OP_2DIV";
         case OP_NEGATE:
             return "OP_NEGATE";
         case OP_ABS:
             return "OP_ABS";
         case OP_NOT:
             return "OP_NOT";
         case OP_0NOTEQUAL:
             return "OP_0NOTEQUAL";
         case OP_ADD:
             return "OP_ADD";
         case OP_SUB:
             return "OP_SUB";
         case OP_MUL:
             return "OP_MUL";
         case OP_DIV:
             return "OP_DIV";
         case OP_MOD:
             return "OP_MOD";
         case OP_LSHIFT:
             return "OP_LSHIFT";
         case OP_RSHIFT:
             return "OP_RSHIFT";
         case OP_BOOLAND:
             return "OP_BOOLAND";
         case OP_BOOLOR:
             return "OP_BOOLOR";
         case OP_NUMEQUAL:
             return "OP_NUMEQUAL";
         case OP_NUMEQUALVERIFY:
             return "OP_NUMEQUALVERIFY";
         case OP_NUMNOTEQUAL:
             return "OP_NUMNOTEQUAL";
         case OP_LESSTHAN:
             return "OP_LESSTHAN";
         case OP_GREATERTHAN:
             return "OP_GREATERTHAN";
         case OP_LESSTHANOREQUAL:
             return "OP_LESSTHANOREQUAL";
         case OP_GREATERTHANOREQUAL:
             return "OP_GREATERTHANOREQUAL";
         case OP_MIN:
             return "OP_MIN";
         case OP_MAX:
             return "OP_MAX";
         case OP_WITHIN:
             return "OP_WITHIN";
 
         // crypto
         case OP_RIPEMD160:
             return "OP_RIPEMD160";
         case OP_SHA1:
             return "OP_SHA1";
         case OP_SHA256:
             return "OP_SHA256";
         case OP_HASH160:
             return "OP_HASH160";
         case OP_HASH256:
             return "OP_HASH256";
         case OP_CODESEPARATOR:
             return "OP_CODESEPARATOR";
         case OP_CHECKSIG:
             return "OP_CHECKSIG";
         case OP_CHECKSIGVERIFY:
             return "OP_CHECKSIGVERIFY";
         case OP_CHECKMULTISIG:
             return "OP_CHECKMULTISIG";
         case OP_CHECKMULTISIGVERIFY:
             return "OP_CHECKMULTISIGVERIFY";
 
         // expansion
         case OP_NOP1:
             return "OP_NOP1";
         case OP_CHECKLOCKTIMEVERIFY:
             return "OP_CHECKLOCKTIMEVERIFY";
         case OP_CHECKSEQUENCEVERIFY:
             return "OP_CHECKSEQUENCEVERIFY";
         case OP_NOP4:
             return "OP_NOP4";
         case OP_NOP5:
             return "OP_NOP5";
         case OP_NOP6:
             return "OP_NOP6";
         case OP_NOP7:
             return "OP_NOP7";
         case OP_NOP8:
             return "OP_NOP8";
         case OP_NOP9:
             return "OP_NOP9";
         case OP_NOP10:
             return "OP_NOP10";
 
         case OP_INVALIDOPCODE:
             return "OP_INVALIDOPCODE";
 
         // Note:
         //  The template matching params OP_SMALLINTEGER/etc are defined in
         //  opcodetype enum as kind of implementation hack, they are *NOT* real
         //  opcodes. If found in real Script, just let the default: case deal
         //  with them.
 
         default:
             return "OP_UNKNOWN";
     }
 }
 
 unsigned int CScript::GetSigOpCount(bool fAccurate) const {
     unsigned int n = 0;
     const_iterator pc = begin();
     opcodetype lastOpcode = OP_INVALIDOPCODE;
     while (pc < end()) {
         opcodetype opcode;
         if (!GetOp(pc, opcode)) break;
         if (opcode == OP_CHECKSIG || opcode == OP_CHECKSIGVERIFY)
             n++;
         else if (opcode == OP_CHECKMULTISIG ||
                  opcode == OP_CHECKMULTISIGVERIFY) {
             if (fAccurate && lastOpcode >= OP_1 && lastOpcode <= OP_16)
                 n += DecodeOP_N(lastOpcode);
             else
                 n += MAX_PUBKEYS_PER_MULTISIG;
         }
         lastOpcode = opcode;
     }
     return n;
 }
 
 unsigned int CScript::GetSigOpCount(const CScript &scriptSig) const {
     if (!IsPayToScriptHash()) return GetSigOpCount(true);
 
     // This is a pay-to-script-hash scriptPubKey;
     // get the last item that the scriptSig
     // pushes onto the stack:
     const_iterator pc = scriptSig.begin();
-    std::vector<unsigned char> data;
+    std::vector<uint8_t> data;
     while (pc < scriptSig.end()) {
         opcodetype opcode;
         if (!scriptSig.GetOp(pc, opcode, data)) return 0;
         if (opcode > OP_16) return 0;
     }
 
     /// ... and return its opcount:
     CScript subscript(data.begin(), data.end());
     return subscript.GetSigOpCount(true);
 }
 
 bool CScript::IsPayToScriptHash() const {
     // Extra-fast test for pay-to-script-hash CScripts:
     return (this->size() == 23 && (*this)[0] == OP_HASH160 &&
             (*this)[1] == 0x14 && (*this)[22] == OP_EQUAL);
 }
 
 bool CScript::IsPayToWitnessScriptHash() const {
     // Extra-fast test for pay-to-witness-script-hash CScripts:
     return (this->size() == 34 && (*this)[0] == OP_0 && (*this)[1] == 0x20);
 }
 
-bool CScript::IsCommitment(const std::vector<unsigned char> &data) const {
+bool CScript::IsCommitment(const std::vector<uint8_t> &data) const {
     // To ensure we have an immediate push, we limit the commitment size to 64
     // bytes. In addition to the data themselves, we have 2 extra bytes:
     // OP_RETURN and the push opcode itself.
     if (data.size() > 64 || this->size() != data.size() + 2) {
         return false;
     }
 
     if ((*this)[0] != OP_RETURN || (*this)[1] != data.size()) {
         return false;
     }
 
     for (size_t i = 0; i < data.size(); i++) {
         if ((*this)[i + 2] != data[i]) {
             return false;
         }
     }
 
     return true;
 }
 
 // A witness program is any valid CScript that consists of a 1-byte push opcode
 // followed by a data push between 2 and 40 bytes.
 bool CScript::IsWitnessProgram(int &version,
-                               std::vector<unsigned char> &program) const {
+                               std::vector<uint8_t> &program) const {
     if (this->size() < 4 || this->size() > 42) {
         return false;
     }
     if ((*this)[0] != OP_0 && ((*this)[0] < OP_1 || (*this)[0] > OP_16)) {
         return false;
     }
     if ((size_t)((*this)[1] + 2) == this->size()) {
         version = DecodeOP_N((opcodetype)(*this)[0]);
-        program = std::vector<unsigned char>(this->begin() + 2, this->end());
+        program = std::vector<uint8_t>(this->begin() + 2, this->end());
         return true;
     }
     return false;
 }
 
 bool CScript::IsPushOnly(const_iterator pc) const {
     while (pc < end()) {
         opcodetype opcode;
         if (!GetOp(pc, opcode)) return false;
         // Note that IsPushOnly() *does* consider OP_RESERVED to be a push-type
         // opcode, however execution of OP_RESERVED fails, so it's not relevant
         // to P2SH/BIP62 as the scriptSig would fail prior to the P2SH special
         // validation code being executed.
         if (opcode > OP_16) return false;
     }
     return true;
 }
 
 bool CScript::IsPushOnly() const {
     return this->IsPushOnly(begin());
 }
 
 std::string CScriptWitness::ToString() const {
     std::string ret = "CScriptWitness(";
     for (unsigned int i = 0; i < stack.size(); i++) {
         if (i) {
             ret += ", ";
         }
         ret += HexStr(stack[i]);
     }
     return ret + ")";
 }
diff --git a/src/script/script.h b/src/script/script.h
index f73e9f206..ff5edc196 100644
--- a/src/script/script.h
+++ b/src/script/script.h
@@ -1,644 +1,642 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_SCRIPT_SCRIPT_H
 #define BITCOIN_SCRIPT_SCRIPT_H
 
 #include "crypto/common.h"
 #include "prevector.h"
 
 #include <cassert>
 #include <climits>
 #include <cstdint>
 #include <cstring>
 #include <limits>
 #include <stdexcept>
 #include <string>
 #include <vector>
 
 // Maximum number of bytes pushable to the stack
 static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520;
 
 // Maximum number of non-push operations per script
 static const int MAX_OPS_PER_SCRIPT = 201;
 
 // Maximum number of public keys per multisig
 static const int MAX_PUBKEYS_PER_MULTISIG = 20;
 
 // Maximum script length in bytes
 static const int MAX_SCRIPT_SIZE = 10000;
 
 // Threshold for nLockTime: below this value it is interpreted as block number,
 // otherwise as UNIX timestamp. Thresold is Tue Nov 5 00:53:20 1985 UTC
 static const unsigned int LOCKTIME_THRESHOLD = 500000000;
 
-template <typename T> std::vector<unsigned char> ToByteVector(const T &in) {
-    return std::vector<unsigned char>(in.begin(), in.end());
+template <typename T> std::vector<uint8_t> ToByteVector(const T &in) {
+    return std::vector<uint8_t>(in.begin(), in.end());
 }
 
 /** Script opcodes */
 enum opcodetype {
     // push value
     OP_0 = 0x00,
     OP_FALSE = OP_0,
     OP_PUSHDATA1 = 0x4c,
     OP_PUSHDATA2 = 0x4d,
     OP_PUSHDATA4 = 0x4e,
     OP_1NEGATE = 0x4f,
     OP_RESERVED = 0x50,
     OP_1 = 0x51,
     OP_TRUE = OP_1,
     OP_2 = 0x52,
     OP_3 = 0x53,
     OP_4 = 0x54,
     OP_5 = 0x55,
     OP_6 = 0x56,
     OP_7 = 0x57,
     OP_8 = 0x58,
     OP_9 = 0x59,
     OP_10 = 0x5a,
     OP_11 = 0x5b,
     OP_12 = 0x5c,
     OP_13 = 0x5d,
     OP_14 = 0x5e,
     OP_15 = 0x5f,
     OP_16 = 0x60,
 
     // control
     OP_NOP = 0x61,
     OP_VER = 0x62,
     OP_IF = 0x63,
     OP_NOTIF = 0x64,
     OP_VERIF = 0x65,
     OP_VERNOTIF = 0x66,
     OP_ELSE = 0x67,
     OP_ENDIF = 0x68,
     OP_VERIFY = 0x69,
     OP_RETURN = 0x6a,
 
     // stack ops
     OP_TOALTSTACK = 0x6b,
     OP_FROMALTSTACK = 0x6c,
     OP_2DROP = 0x6d,
     OP_2DUP = 0x6e,
     OP_3DUP = 0x6f,
     OP_2OVER = 0x70,
     OP_2ROT = 0x71,
     OP_2SWAP = 0x72,
     OP_IFDUP = 0x73,
     OP_DEPTH = 0x74,
     OP_DROP = 0x75,
     OP_DUP = 0x76,
     OP_NIP = 0x77,
     OP_OVER = 0x78,
     OP_PICK = 0x79,
     OP_ROLL = 0x7a,
     OP_ROT = 0x7b,
     OP_SWAP = 0x7c,
     OP_TUCK = 0x7d,
 
     // splice ops
     OP_CAT = 0x7e,
     OP_SUBSTR = 0x7f,
     OP_LEFT = 0x80,
     OP_RIGHT = 0x81,
     OP_SIZE = 0x82,
 
     // bit logic
     OP_INVERT = 0x83,
     OP_AND = 0x84,
     OP_OR = 0x85,
     OP_XOR = 0x86,
     OP_EQUAL = 0x87,
     OP_EQUALVERIFY = 0x88,
     OP_RESERVED1 = 0x89,
     OP_RESERVED2 = 0x8a,
 
     // numeric
     OP_1ADD = 0x8b,
     OP_1SUB = 0x8c,
     OP_2MUL = 0x8d,
     OP_2DIV = 0x8e,
     OP_NEGATE = 0x8f,
     OP_ABS = 0x90,
     OP_NOT = 0x91,
     OP_0NOTEQUAL = 0x92,
 
     OP_ADD = 0x93,
     OP_SUB = 0x94,
     OP_MUL = 0x95,
     OP_DIV = 0x96,
     OP_MOD = 0x97,
     OP_LSHIFT = 0x98,
     OP_RSHIFT = 0x99,
 
     OP_BOOLAND = 0x9a,
     OP_BOOLOR = 0x9b,
     OP_NUMEQUAL = 0x9c,
     OP_NUMEQUALVERIFY = 0x9d,
     OP_NUMNOTEQUAL = 0x9e,
     OP_LESSTHAN = 0x9f,
     OP_GREATERTHAN = 0xa0,
     OP_LESSTHANOREQUAL = 0xa1,
     OP_GREATERTHANOREQUAL = 0xa2,
     OP_MIN = 0xa3,
     OP_MAX = 0xa4,
 
     OP_WITHIN = 0xa5,
 
     // crypto
     OP_RIPEMD160 = 0xa6,
     OP_SHA1 = 0xa7,
     OP_SHA256 = 0xa8,
     OP_HASH160 = 0xa9,
     OP_HASH256 = 0xaa,
     OP_CODESEPARATOR = 0xab,
     OP_CHECKSIG = 0xac,
     OP_CHECKSIGVERIFY = 0xad,
     OP_CHECKMULTISIG = 0xae,
     OP_CHECKMULTISIGVERIFY = 0xaf,
 
     // expansion
     OP_NOP1 = 0xb0,
     OP_CHECKLOCKTIMEVERIFY = 0xb1,
     OP_NOP2 = OP_CHECKLOCKTIMEVERIFY,
     OP_CHECKSEQUENCEVERIFY = 0xb2,
     OP_NOP3 = OP_CHECKSEQUENCEVERIFY,
     OP_NOP4 = 0xb3,
     OP_NOP5 = 0xb4,
     OP_NOP6 = 0xb5,
     OP_NOP7 = 0xb6,
     OP_NOP8 = 0xb7,
     OP_NOP9 = 0xb8,
     OP_NOP10 = 0xb9,
 
     // template matching params
     OP_SMALLINTEGER = 0xfa,
     OP_PUBKEYS = 0xfb,
     OP_PUBKEYHASH = 0xfd,
     OP_PUBKEY = 0xfe,
 
     OP_INVALIDOPCODE = 0xff,
 };
 
 const char *GetOpName(opcodetype opcode);
 
 class scriptnum_error : public std::runtime_error {
 public:
     explicit scriptnum_error(const std::string &str)
         : std::runtime_error(str) {}
 };
 
 class CScriptNum {
     /**
      * Numeric opcodes (OP_1ADD, etc) are restricted to operating on 4-byte
      * integers. The semantics are subtle, though: operands must be in the range
      * [-2^31 +1...2^31 -1], but results may overflow (and are valid as long as
      * they are not used in a subsequent numeric operation). CScriptNum enforces
      * those semantics by storing results as an int64 and allowing out-of-range
      * values to be returned as a vector of bytes but throwing an exception if
      * arithmetic is done or the result is interpreted as an integer.
      */
 public:
     explicit CScriptNum(const int64_t &n) { m_value = n; }
 
     static const size_t nDefaultMaxNumSize = 4;
 
-    explicit CScriptNum(const std::vector<unsigned char> &vch,
-                        bool fRequireMinimal,
+    explicit CScriptNum(const std::vector<uint8_t> &vch, bool fRequireMinimal,
                         const size_t nMaxNumSize = nDefaultMaxNumSize) {
         if (vch.size() > nMaxNumSize) {
             throw scriptnum_error("script number overflow");
         }
         if (fRequireMinimal && vch.size() > 0) {
             // Check that the number is encoded with the minimum possible number
             // of bytes.
             //
             // If the most-significant-byte - excluding the sign bit - is zero
             // then we're not minimal. Note how this test also rejects the
             // negative-zero encoding, 0x80.
             if ((vch.back() & 0x7f) == 0) {
                 // One exception: if there's more than one byte and the most
                 // significant bit of the second-most-significant-byte is set it
                 // would conflict with the sign bit. An example of this case is
                 // +-255, which encode to 0xff00 and 0xff80 respectively.
                 // (big-endian).
                 if (vch.size() <= 1 || (vch[vch.size() - 2] & 0x80) == 0) {
                     throw scriptnum_error(
                         "non-minimally encoded script number");
                 }
             }
         }
         m_value = set_vch(vch);
     }
 
     inline bool operator==(const int64_t &rhs) const { return m_value == rhs; }
     inline bool operator!=(const int64_t &rhs) const { return m_value != rhs; }
     inline bool operator<=(const int64_t &rhs) const { return m_value <= rhs; }
     inline bool operator<(const int64_t &rhs) const { return m_value < rhs; }
     inline bool operator>=(const int64_t &rhs) const { return m_value >= rhs; }
     inline bool operator>(const int64_t &rhs) const { return m_value > rhs; }
 
     inline bool operator==(const CScriptNum &rhs) const {
         return operator==(rhs.m_value);
     }
     inline bool operator!=(const CScriptNum &rhs) const {
         return operator!=(rhs.m_value);
     }
     inline bool operator<=(const CScriptNum &rhs) const {
         return operator<=(rhs.m_value);
     }
     inline bool operator<(const CScriptNum &rhs) const {
         return operator<(rhs.m_value);
     }
     inline bool operator>=(const CScriptNum &rhs) const {
         return operator>=(rhs.m_value);
     }
     inline bool operator>(const CScriptNum &rhs) const {
         return operator>(rhs.m_value);
     }
 
     inline CScriptNum operator+(const int64_t &rhs) const {
         return CScriptNum(m_value + rhs);
     }
     inline CScriptNum operator-(const int64_t &rhs) const {
         return CScriptNum(m_value - rhs);
     }
     inline CScriptNum operator+(const CScriptNum &rhs) const {
         return operator+(rhs.m_value);
     }
     inline CScriptNum operator-(const CScriptNum &rhs) const {
         return operator-(rhs.m_value);
     }
 
     inline CScriptNum &operator+=(const CScriptNum &rhs) {
         return operator+=(rhs.m_value);
     }
     inline CScriptNum &operator-=(const CScriptNum &rhs) {
         return operator-=(rhs.m_value);
     }
 
     inline CScriptNum operator&(const int64_t &rhs) const {
         return CScriptNum(m_value & rhs);
     }
     inline CScriptNum operator&(const CScriptNum &rhs) const {
         return operator&(rhs.m_value);
     }
 
     inline CScriptNum &operator&=(const CScriptNum &rhs) {
         return operator&=(rhs.m_value);
     }
 
     inline CScriptNum operator-() const {
         assert(m_value != std::numeric_limits<int64_t>::min());
         return CScriptNum(-m_value);
     }
 
     inline CScriptNum &operator=(const int64_t &rhs) {
         m_value = rhs;
         return *this;
     }
 
     inline CScriptNum &operator+=(const int64_t &rhs) {
         assert(
             rhs == 0 ||
             (rhs > 0 && m_value <= std::numeric_limits<int64_t>::max() - rhs) ||
             (rhs < 0 && m_value >= std::numeric_limits<int64_t>::min() - rhs));
         m_value += rhs;
         return *this;
     }
 
     inline CScriptNum &operator-=(const int64_t &rhs) {
         assert(
             rhs == 0 ||
             (rhs > 0 && m_value >= std::numeric_limits<int64_t>::min() + rhs) ||
             (rhs < 0 && m_value <= std::numeric_limits<int64_t>::max() + rhs));
         m_value -= rhs;
         return *this;
     }
 
     inline CScriptNum &operator&=(const int64_t &rhs) {
         m_value &= rhs;
         return *this;
     }
 
     int getint() const {
         if (m_value > std::numeric_limits<int>::max())
             return std::numeric_limits<int>::max();
         else if (m_value < std::numeric_limits<int>::min())
             return std::numeric_limits<int>::min();
         return m_value;
     }
 
-    std::vector<unsigned char> getvch() const { return serialize(m_value); }
+    std::vector<uint8_t> getvch() const { return serialize(m_value); }
 
-    static std::vector<unsigned char> serialize(const int64_t &value) {
-        if (value == 0) return std::vector<unsigned char>();
+    static std::vector<uint8_t> serialize(const int64_t &value) {
+        if (value == 0) return std::vector<uint8_t>();
 
-        std::vector<unsigned char> result;
+        std::vector<uint8_t> result;
         const bool neg = value < 0;
         uint64_t absvalue = neg ? -value : value;
 
         while (absvalue) {
             result.push_back(absvalue & 0xff);
             absvalue >>= 8;
         }
 
         // - If the most significant byte is >= 0x80 and the value is positive,
         // push a new zero-byte to make the significant byte < 0x80 again.
         // - If the most significant byte is >= 0x80 and the value is negative,
         // push a new 0x80 byte that will be popped off when converting to an
         // integral.
         // - If the most significant byte is < 0x80 and the value is negative,
         // add 0x80 to it, since it will be subtracted and interpreted as a
         // negative when converting to an integral.
         if (result.back() & 0x80) {
             result.push_back(neg ? 0x80 : 0);
         } else if (neg) {
             result.back() |= 0x80;
         }
 
         return result;
     }
 
 private:
-    static int64_t set_vch(const std::vector<unsigned char> &vch) {
+    static int64_t set_vch(const std::vector<uint8_t> &vch) {
         if (vch.empty()) return 0;
 
         int64_t result = 0;
         for (size_t i = 0; i != vch.size(); ++i)
             result |= static_cast<int64_t>(vch[i]) << 8 * i;
 
         // If the input vector's most significant byte is 0x80, remove it from
         // the result's msb and return a negative.
         if (vch.back() & 0x80)
             return -((int64_t)(result & ~(0x80ULL << (8 * (vch.size() - 1)))));
 
         return result;
     }
 
     int64_t m_value;
 };
 
-typedef prevector<28, unsigned char> CScriptBase;
+typedef prevector<28, uint8_t> CScriptBase;
 
 /** Serialized script, used inside transaction inputs and outputs */
 class CScript : public CScriptBase {
 protected:
     CScript &push_int64(int64_t n) {
         if (n == -1 || (n >= 1 && n <= 16)) {
             push_back(n + (OP_1 - 1));
         } else if (n == 0) {
             push_back(OP_0);
         } else {
             *this << CScriptNum::serialize(n);
         }
         return *this;
     }
 
 public:
     CScript() {}
     CScript(const_iterator pbegin, const_iterator pend)
         : CScriptBase(pbegin, pend) {}
-    CScript(std::vector<unsigned char>::const_iterator pbegin,
-            std::vector<unsigned char>::const_iterator pend)
+    CScript(std::vector<uint8_t>::const_iterator pbegin,
+            std::vector<uint8_t>::const_iterator pend)
         : CScriptBase(pbegin, pend) {}
-    CScript(const unsigned char *pbegin, const unsigned char *pend)
+    CScript(const uint8_t *pbegin, const uint8_t *pend)
         : CScriptBase(pbegin, pend) {}
 
     CScript &operator+=(const CScript &b) {
         insert(end(), b.begin(), b.end());
         return *this;
     }
 
     friend CScript operator+(const CScript &a, const CScript &b) {
         CScript ret = a;
         ret += b;
         return ret;
     }
 
     CScript(int64_t b) { operator<<(b); }
 
     explicit CScript(opcodetype b) { operator<<(b); }
     explicit CScript(const CScriptNum &b) { operator<<(b); }
-    explicit CScript(const std::vector<unsigned char> &b) { operator<<(b); }
+    explicit CScript(const std::vector<uint8_t> &b) { operator<<(b); }
 
     CScript &operator<<(int64_t b) { return push_int64(b); }
 
     CScript &operator<<(opcodetype opcode) {
         if (opcode < 0 || opcode > 0xff)
             throw std::runtime_error("CScript::operator<<(): invalid opcode");
-        insert(end(), (unsigned char)opcode);
+        insert(end(), uint8_t(opcode));
         return *this;
     }
 
     CScript &operator<<(const CScriptNum &b) {
         *this << b.getvch();
         return *this;
     }
 
-    CScript &operator<<(const std::vector<unsigned char> &b) {
+    CScript &operator<<(const std::vector<uint8_t> &b) {
         if (b.size() < OP_PUSHDATA1) {
-            insert(end(), (unsigned char)b.size());
+            insert(end(), uint8_t(b.size()));
         } else if (b.size() <= 0xff) {
             insert(end(), OP_PUSHDATA1);
-            insert(end(), (unsigned char)b.size());
+            insert(end(), uint8_t(b.size()));
         } else if (b.size() <= 0xffff) {
             insert(end(), OP_PUSHDATA2);
             uint8_t data[2];
             WriteLE16(data, b.size());
             insert(end(), data, data + sizeof(data));
         } else {
             insert(end(), OP_PUSHDATA4);
             uint8_t data[4];
             WriteLE32(data, b.size());
             insert(end(), data, data + sizeof(data));
         }
         insert(end(), b.begin(), b.end());
         return *this;
     }
 
     CScript &operator<<(const CScript &b) {
         // I'm not sure if this should push the script or concatenate scripts.
         // If there's ever a use for pushing a script onto a script, delete this
         // member fn.
         assert(!"Warning: Pushing a CScript onto a CScript with << is probably "
                 "not intended, use + to concatenate!");
         return *this;
     }
 
     bool GetOp(iterator &pc, opcodetype &opcodeRet,
-               std::vector<unsigned char> &vchRet) {
+               std::vector<uint8_t> &vchRet) {
         // Wrapper so it can be called with either iterator or const_iterator.
         const_iterator pc2 = pc;
         bool fRet = GetOp2(pc2, opcodeRet, &vchRet);
         pc = begin() + (pc2 - begin());
         return fRet;
     }
 
     bool GetOp(iterator &pc, opcodetype &opcodeRet) {
         const_iterator pc2 = pc;
         bool fRet = GetOp2(pc2, opcodeRet, nullptr);
         pc = begin() + (pc2 - begin());
         return fRet;
     }
 
     bool GetOp(const_iterator &pc, opcodetype &opcodeRet,
-               std::vector<unsigned char> &vchRet) const {
+               std::vector<uint8_t> &vchRet) const {
         return GetOp2(pc, opcodeRet, &vchRet);
     }
 
     bool GetOp(const_iterator &pc, opcodetype &opcodeRet) const {
         return GetOp2(pc, opcodeRet, nullptr);
     }
 
     bool GetOp2(const_iterator &pc, opcodetype &opcodeRet,
-                std::vector<unsigned char> *pvchRet) const {
+                std::vector<uint8_t> *pvchRet) const {
         opcodeRet = OP_INVALIDOPCODE;
         if (pvchRet) pvchRet->clear();
         if (pc >= end()) return false;
 
         // Read instruction
         if (end() - pc < 1) return false;
         unsigned int opcode = *pc++;
 
         // Immediate operand
         if (opcode <= OP_PUSHDATA4) {
             unsigned int nSize = 0;
             if (opcode < OP_PUSHDATA1) {
                 nSize = opcode;
             } else if (opcode == OP_PUSHDATA1) {
                 if (end() - pc < 1) return false;
                 nSize = *pc++;
             } else if (opcode == OP_PUSHDATA2) {
                 if (end() - pc < 2) return false;
                 nSize = ReadLE16(&pc[0]);
                 pc += 2;
             } else if (opcode == OP_PUSHDATA4) {
                 if (end() - pc < 4) return false;
                 nSize = ReadLE32(&pc[0]);
                 pc += 4;
             }
             if (end() - pc < 0 || (unsigned int)(end() - pc) < nSize)
                 return false;
             if (pvchRet) pvchRet->assign(pc, pc + nSize);
             pc += nSize;
         }
 
         opcodeRet = (opcodetype)opcode;
         return true;
     }
 
     /** Encode/decode small integers: */
     static int DecodeOP_N(opcodetype opcode) {
         if (opcode == OP_0) return 0;
         assert(opcode >= OP_1 && opcode <= OP_16);
         return (int)opcode - (int)(OP_1 - 1);
     }
     static opcodetype EncodeOP_N(int n) {
         assert(n >= 0 && n <= 16);
         if (n == 0) return OP_0;
         return (opcodetype)(OP_1 + n - 1);
     }
 
     int FindAndDelete(const CScript &b) {
         int nFound = 0;
         if (b.empty()) return nFound;
         CScript result;
         iterator pc = begin(), pc2 = begin();
         opcodetype opcode;
         do {
             result.insert(result.end(), pc2, pc);
             while (static_cast<size_t>(end() - pc) >= b.size() &&
                    std::equal(b.begin(), b.end(), pc)) {
                 pc = pc + b.size();
                 ++nFound;
             }
             pc2 = pc;
         } while (GetOp(pc, opcode));
 
         if (nFound > 0) {
             result.insert(result.end(), pc2, end());
             *this = result;
         }
 
         return nFound;
     }
     int Find(opcodetype op) const {
         int nFound = 0;
         opcodetype opcode;
         for (const_iterator pc = begin(); pc != end() && GetOp(pc, opcode);)
             if (opcode == op) ++nFound;
         return nFound;
     }
 
     /**
      * Pre-version-0.6, Bitcoin always counted CHECKMULTISIGs as 20 sigops. With
      * pay-to-script-hash, that changed: CHECKMULTISIGs serialized in scriptSigs
      * are counted more accurately, assuming they are of the form
      *  ... OP_N CHECKMULTISIG ...
      */
     unsigned int GetSigOpCount(bool fAccurate) const;
 
     /**
      * Accurately count sigOps, including sigOps in pay-to-script-hash
      * transactions:
      */
     unsigned int GetSigOpCount(const CScript &scriptSig) const;
 
     bool IsPayToScriptHash() const;
     bool IsPayToWitnessScriptHash() const;
-    bool IsCommitment(const std::vector<unsigned char> &data) const;
-    bool IsWitnessProgram(int &version,
-                          std::vector<unsigned char> &program) const;
+    bool IsCommitment(const std::vector<uint8_t> &data) const;
+    bool IsWitnessProgram(int &version, std::vector<uint8_t> &program) const;
 
     /** Called by IsStandardTx and P2SH/BIP62 VerifyScript (which makes it
      * consensus-critical). */
     bool IsPushOnly(const_iterator pc) const;
     bool IsPushOnly() const;
 
     /**
      * Returns whether the script is guaranteed to fail at execution, regardless
      * of the initial stack. This allows outputs to be pruned instantly when
      * entering the UTXO set.
      */
     bool IsUnspendable() const {
         return (size() > 0 && *begin() == OP_RETURN) ||
                (size() > MAX_SCRIPT_SIZE);
     }
 
     void clear() {
         // The default std::vector::clear() does not release memory.
         CScriptBase().swap(*this);
     }
 };
 
 struct CScriptWitness {
     // Note that this encodes the data elements being pushed, rather than
     // encoding them as a CScript that pushes them.
-    std::vector<std::vector<unsigned char>> stack;
+    std::vector<std::vector<uint8_t>> stack;
 
     // Some compilers complain without a default constructor
     CScriptWitness() {}
 
     bool IsNull() const { return stack.empty(); }
 
     void SetNull() {
         stack.clear();
         stack.shrink_to_fit();
     }
 
     std::string ToString() const;
 };
 
 class CReserveScript {
 public:
     CScript reserveScript;
     virtual void KeepScript() {}
     CReserveScript() {}
     virtual ~CReserveScript() {}
 };
 
 #endif // BITCOIN_SCRIPT_SCRIPT_H
diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp
index 6798110b6..4c18e9832 100644
--- a/src/script/sigcache.cpp
+++ b/src/script/sigcache.cpp
@@ -1,112 +1,112 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #include "sigcache.h"
 
 #include "memusage.h"
 #include "pubkey.h"
 #include "random.h"
 #include "uint256.h"
 #include "util.h"
 
 #include "cuckoocache.h"
 #include <boost/thread.hpp>
 
 namespace {
 
 /**
  * We're hashing a nonce into the entries themselves, so we don't need extra
  * blinding in the set hash computation.
  *
  * This may exhibit platform endian dependent behavior but because these are
  * nonced hashes (random) and this state is only ever used locally it is safe.
  * All that matters is local consistency.
  */
 class SignatureCacheHasher {
 public:
     template <uint8_t hash_select>
     uint32_t operator()(const uint256 &key) const {
         static_assert(hash_select < 8,
                       "SignatureCacheHasher only has 8 hashes available.");
         uint32_t u;
         std::memcpy(&u, key.begin() + 4 * hash_select, 4);
         return u;
     }
 };
 
 /**
  * Valid signature cache, to avoid doing expensive ECDSA signature checking
  * twice for every transaction (once when accepted into memory pool, and
  * again when accepted into the block chain)
  */
 class CSignatureCache {
 private:
     //! Entries are SHA256(nonce || signature hash || public key || signature):
     uint256 nonce;
     typedef CuckooCache::cache<uint256, SignatureCacheHasher> map_type;
     map_type setValid;
     boost::shared_mutex cs_sigcache;
 
 public:
     CSignatureCache() { GetRandBytes(nonce.begin(), 32); }
 
     void ComputeEntry(uint256 &entry, const uint256 &hash,
-                      const std::vector<unsigned char> &vchSig,
+                      const std::vector<uint8_t> &vchSig,
                       const CPubKey &pubkey) {
         CSHA256()
             .Write(nonce.begin(), 32)
             .Write(hash.begin(), 32)
             .Write(&pubkey[0], pubkey.size())
             .Write(&vchSig[0], vchSig.size())
             .Finalize(entry.begin());
     }
 
     bool Get(const uint256 &entry, const bool erase) {
         boost::shared_lock<boost::shared_mutex> lock(cs_sigcache);
         return setValid.contains(entry, erase);
     }
 
     void Set(uint256 &entry) {
         boost::unique_lock<boost::shared_mutex> lock(cs_sigcache);
         setValid.insert(entry);
     }
     uint32_t setup_bytes(size_t n) { return setValid.setup_bytes(n); }
 };
 
 /* In previous versions of this code, signatureCache was a local static variable
  * in CachingTransactionSignatureChecker::VerifySignature.  We initialize
  * signatureCache outside of VerifySignature to avoid the atomic operation per
  * call overhead associated with local static variables even though
  * signatureCache could be made local to VerifySignature.
 */
 static CSignatureCache signatureCache;
 }
 
 // To be called once in AppInit2/TestingSetup to initialize the signatureCache
 void InitSignatureCache() {
     // nMaxCacheSize is unsigned. If -maxsigcachesize is set to zero,
     // setup_bytes creates the minimum possible cache (2 elements).
     size_t nMaxCacheSize =
         std::min(std::max((int64_t)0, GetArg("-maxsigcachesize",
                                              DEFAULT_MAX_SIG_CACHE_SIZE)),
                  MAX_MAX_SIG_CACHE_SIZE) *
         ((size_t)1 << 20);
     size_t nElems = signatureCache.setup_bytes(nMaxCacheSize);
     LogPrintf("Using %zu MiB out of %zu requested for signature cache, able to "
               "store %zu elements\n",
               (nElems * sizeof(uint256)) >> 20, nMaxCacheSize >> 20, nElems);
 }
 
 bool CachingTransactionSignatureChecker::VerifySignature(
-    const std::vector<unsigned char> &vchSig, const CPubKey &pubkey,
+    const std::vector<uint8_t> &vchSig, const CPubKey &pubkey,
     const uint256 &sighash) const {
     uint256 entry;
     signatureCache.ComputeEntry(entry, sighash, vchSig, pubkey);
     if (signatureCache.Get(entry, !store)) return true;
     if (!TransactionSignatureChecker::VerifySignature(vchSig, pubkey, sighash))
         return false;
     if (store) signatureCache.Set(entry);
     return true;
 }
diff --git a/src/script/sigcache.h b/src/script/sigcache.h
index 9dd609d55..24d9aacbf 100644
--- a/src/script/sigcache.h
+++ b/src/script/sigcache.h
@@ -1,41 +1,41 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_SCRIPT_SIGCACHE_H
 #define BITCOIN_SCRIPT_SIGCACHE_H
 
 #include "script/interpreter.h"
 
 #include <vector>
 
 // DoS prevention: limit cache size to 32MB (over 1000000 entries on 64-bit
 // systems). Due to how we count cache size, actual memory usage is slightly
 // more (~32.25 MB)
 static const unsigned int DEFAULT_MAX_SIG_CACHE_SIZE = 32;
 // Maximum sig cache size allowed
 static const int64_t MAX_MAX_SIG_CACHE_SIZE = 16384;
 
 class CPubKey;
 
 class CachingTransactionSignatureChecker : public TransactionSignatureChecker {
 private:
     bool store;
 
 public:
     CachingTransactionSignatureChecker(const CTransaction *txToIn,
                                        unsigned int nInIn,
                                        const CAmount &amount, bool storeIn,
                                        PrecomputedTransactionData &txdataIn)
         : TransactionSignatureChecker(txToIn, nInIn, amount, txdataIn),
           store(storeIn) {}
 
-    bool VerifySignature(const std::vector<unsigned char> &vchSig,
+    bool VerifySignature(const std::vector<uint8_t> &vchSig,
                          const CPubKey &vchPubKey,
                          const uint256 &sighash) const;
 };
 
 void InitSignatureCache();
 
 #endif // BITCOIN_SCRIPT_SIGCACHE_H
diff --git a/src/script/sign.cpp b/src/script/sign.cpp
index 563ada8da..8c08d1072 100644
--- a/src/script/sign.cpp
+++ b/src/script/sign.cpp
@@ -1,391 +1,391 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #include "script/sign.h"
 
 #include "key.h"
 #include "keystore.h"
 #include "policy/policy.h"
 #include "primitives/transaction.h"
 #include "script/standard.h"
 #include "uint256.h"
 
-typedef std::vector<unsigned char> valtype;
+typedef std::vector<uint8_t> valtype;
 
 TransactionSignatureCreator::TransactionSignatureCreator(
     const CKeyStore *keystoreIn, const CTransaction *txToIn, unsigned int nInIn,
     const CAmount &amountIn, uint32_t nHashTypeIn)
     : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn),
       amount(amountIn), nHashType(nHashTypeIn), checker(txTo, nIn, amountIn) {}
 
-bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char> &vchSig,
+bool TransactionSignatureCreator::CreateSig(std::vector<uint8_t> &vchSig,
                                             const CKeyID &address,
                                             const CScript &scriptCode) const {
     CKey key;
     if (!keystore->GetKey(address, key)) {
         return false;
     }
 
     uint256 hash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount);
     if (!key.Sign(hash, vchSig)) {
         return false;
     }
 
     vchSig.push_back(uint8_t(nHashType));
     return true;
 }
 
 static bool Sign1(const CKeyID &address, const BaseSignatureCreator &creator,
                   const CScript &scriptCode, std::vector<valtype> &ret) {
-    std::vector<unsigned char> vchSig;
+    std::vector<uint8_t> vchSig;
     if (!creator.CreateSig(vchSig, address, scriptCode)) {
         return false;
     }
 
     ret.push_back(vchSig);
     return true;
 }
 
 static bool SignN(const std::vector<valtype> &multisigdata,
                   const BaseSignatureCreator &creator,
                   const CScript &scriptCode, std::vector<valtype> &ret) {
     int nSigned = 0;
     int nRequired = multisigdata.front()[0];
     for (size_t i = 1; i < multisigdata.size() - 1 && nSigned < nRequired;
          i++) {
         const valtype &pubkey = multisigdata[i];
         CKeyID keyID = CPubKey(pubkey).GetID();
         if (Sign1(keyID, creator, scriptCode, ret)) {
             ++nSigned;
         }
     }
 
     return nSigned == nRequired;
 }
 
 /**
  * Sign scriptPubKey using signature made with creator.
  * Signatures are returned in scriptSigRet (or returns false if scriptPubKey
  * can't be signed), unless whichTypeRet is TX_SCRIPTHASH, in which case
  * scriptSigRet is the redemption script.
  * Returns false if scriptPubKey could not be completely satisfied.
  */
 static bool SignStep(const BaseSignatureCreator &creator,
                      const CScript &scriptPubKey, std::vector<valtype> &ret,
                      txnouttype &whichTypeRet) {
     CScript scriptRet;
     uint160 h160;
     ret.clear();
 
     std::vector<valtype> vSolutions;
     if (!Solver(scriptPubKey, whichTypeRet, vSolutions)) {
         return false;
     }
 
     CKeyID keyID;
     switch (whichTypeRet) {
         case TX_NONSTANDARD:
         case TX_NULL_DATA:
             return false;
         case TX_PUBKEY:
             keyID = CPubKey(vSolutions[0]).GetID();
             return Sign1(keyID, creator, scriptPubKey, ret);
         case TX_PUBKEYHASH: {
             keyID = CKeyID(uint160(vSolutions[0]));
             if (!Sign1(keyID, creator, scriptPubKey, ret)) {
                 return false;
             }
 
             CPubKey vch;
             creator.KeyStore().GetPubKey(keyID, vch);
             ret.push_back(ToByteVector(vch));
             return true;
         }
         case TX_SCRIPTHASH:
             if (creator.KeyStore().GetCScript(uint160(vSolutions[0]),
                                               scriptRet)) {
-                ret.push_back(std::vector<unsigned char>(scriptRet.begin(),
-                                                         scriptRet.end()));
+                ret.push_back(
+                    std::vector<uint8_t>(scriptRet.begin(), scriptRet.end()));
                 return true;
             }
 
             return false;
 
         case TX_MULTISIG:
             // workaround CHECKMULTISIG bug
             ret.push_back(valtype());
             return (SignN(vSolutions, creator, scriptPubKey, ret));
 
         default:
             return false;
     }
 }
 
 static CScript PushAll(const std::vector<valtype> &values) {
     CScript result;
     for (const valtype &v : values) {
         if (v.size() == 0) {
             result << OP_0;
         } else if (v.size() == 1 && v[0] >= 1 && v[0] <= 16) {
             result << CScript::EncodeOP_N(v[0]);
         } else {
             result << v;
         }
     }
 
     return result;
 }
 
 bool ProduceSignature(const BaseSignatureCreator &creator,
                       const CScript &fromPubKey, SignatureData &sigdata) {
     CScript script = fromPubKey;
     bool solved = true;
     std::vector<valtype> result;
     txnouttype whichType;
     solved = SignStep(creator, script, result, whichType);
     CScript subscript;
 
     if (solved && whichType == TX_SCRIPTHASH) {
         // Solver returns the subscript that needs to be evaluated; the final
         // scriptSig is the signatures from that and then the serialized
         // subscript:
         script = subscript = CScript(result[0].begin(), result[0].end());
         solved = solved && SignStep(creator, script, result, whichType) &&
                  whichType != TX_SCRIPTHASH;
         result.push_back(
-            std::vector<unsigned char>(subscript.begin(), subscript.end()));
+            std::vector<uint8_t>(subscript.begin(), subscript.end()));
     }
 
     sigdata.scriptSig = PushAll(result);
 
     // Test solution
     return solved && VerifyScript(sigdata.scriptSig, fromPubKey,
                                   STANDARD_SCRIPT_VERIFY_FLAGS |
                                       SCRIPT_ENABLE_SIGHASH_FORKID,
                                   creator.Checker());
 }
 
 SignatureData DataFromTransaction(const CMutableTransaction &tx,
                                   unsigned int nIn) {
     SignatureData data;
     assert(tx.vin.size() > nIn);
     data.scriptSig = tx.vin[nIn].scriptSig;
     return data;
 }
 
 void UpdateTransaction(CMutableTransaction &tx, unsigned int nIn,
                        const SignatureData &data) {
     assert(tx.vin.size() > nIn);
     tx.vin[nIn].scriptSig = data.scriptSig;
 }
 
 bool SignSignature(const CKeyStore &keystore, const CScript &fromPubKey,
                    CMutableTransaction &txTo, unsigned int nIn,
                    const CAmount &amount, uint32_t nHashType) {
     assert(nIn < txTo.vin.size());
 
     CTransaction txToConst(txTo);
     TransactionSignatureCreator creator(&keystore, &txToConst, nIn, amount,
                                         nHashType);
 
     SignatureData sigdata;
     bool ret = ProduceSignature(creator, fromPubKey, sigdata);
     UpdateTransaction(txTo, nIn, sigdata);
     return ret;
 }
 
 bool SignSignature(const CKeyStore &keystore, const CTransaction &txFrom,
                    CMutableTransaction &txTo, unsigned int nIn,
                    uint32_t nHashType) {
     assert(nIn < txTo.vin.size());
     CTxIn &txin = txTo.vin[nIn];
     assert(txin.prevout.n < txFrom.vout.size());
     const CTxOut &txout = txFrom.vout[txin.prevout.n];
 
     return SignSignature(keystore, txout.scriptPubKey, txTo, nIn, txout.nValue,
                          nHashType);
 }
 
 static std::vector<valtype> CombineMultisig(
     const CScript &scriptPubKey, const BaseSignatureChecker &checker,
     const std::vector<valtype> &vSolutions, const std::vector<valtype> &sigs1,
     const std::vector<valtype> &sigs2) {
     // Combine all the signatures we've got:
     std::set<valtype> allsigs;
     for (const valtype &v : sigs1) {
         if (!v.empty()) {
             allsigs.insert(v);
         }
     }
 
     for (const valtype &v : sigs2) {
         if (!v.empty()) {
             allsigs.insert(v);
         }
     }
 
     // Build a map of pubkey -> signature by matching sigs to pubkeys:
     assert(vSolutions.size() > 1);
     unsigned int nSigsRequired = vSolutions.front()[0];
     unsigned int nPubKeys = vSolutions.size() - 2;
     std::map<valtype, valtype> sigs;
     for (const valtype &sig : allsigs) {
         for (unsigned int i = 0; i < nPubKeys; i++) {
             const valtype &pubkey = vSolutions[i + 1];
             // Already got a sig for this pubkey
             if (sigs.count(pubkey)) {
                 continue;
             }
 
             if (checker.CheckSig(sig, pubkey, scriptPubKey,
                                  STANDARD_SCRIPT_VERIFY_FLAGS |
                                      SCRIPT_ENABLE_SIGHASH_FORKID)) {
                 sigs[pubkey] = sig;
                 break;
             }
         }
     }
     // Now build a merged CScript:
     unsigned int nSigsHave = 0;
     // pop-one-too-many workaround
     std::vector<valtype> result;
     result.push_back(valtype());
     for (unsigned int i = 0; i < nPubKeys && nSigsHave < nSigsRequired; i++) {
         if (sigs.count(vSolutions[i + 1])) {
             result.push_back(sigs[vSolutions[i + 1]]);
             ++nSigsHave;
         }
     }
 
     // Fill any missing with OP_0:
     for (unsigned int i = nSigsHave; i < nSigsRequired; i++) {
         result.push_back(valtype());
     }
 
     return result;
 }
 
 namespace {
 struct Stacks {
     std::vector<valtype> script;
 
     Stacks() {}
     explicit Stacks(const std::vector<valtype> &scriptSigStack_)
         : script(scriptSigStack_) {}
     explicit Stacks(const SignatureData &data) {
         EvalScript(script, data.scriptSig,
                    SCRIPT_VERIFY_STRICTENC | SCRIPT_ENABLE_SIGHASH_FORKID,
                    BaseSignatureChecker());
     }
 
     SignatureData Output() const {
         SignatureData result;
         result.scriptSig = PushAll(script);
         return result;
     }
 };
 }
 
 static Stacks CombineSignatures(const CScript &scriptPubKey,
                                 const BaseSignatureChecker &checker,
                                 const txnouttype txType,
                                 const std::vector<valtype> &vSolutions,
                                 Stacks sigs1, Stacks sigs2) {
     switch (txType) {
         case TX_NONSTANDARD:
         case TX_NULL_DATA:
             // Don't know anything about this, assume bigger one is correct:
             if (sigs1.script.size() >= sigs2.script.size()) {
                 return sigs1;
             }
 
             return sigs2;
         case TX_PUBKEY:
         case TX_PUBKEYHASH:
             // Signatures are bigger than placeholders or empty scripts:
             if (sigs1.script.empty() || sigs1.script[0].empty()) {
                 return sigs2;
             }
 
             return sigs1;
         case TX_SCRIPTHASH: {
             if (sigs1.script.empty() || sigs1.script.back().empty()) {
                 return sigs2;
             }
 
             if (sigs2.script.empty() || sigs2.script.back().empty()) {
                 return sigs1;
             }
 
             // Recur to combine:
             valtype spk = sigs1.script.back();
             CScript pubKey2(spk.begin(), spk.end());
 
             txnouttype txType2;
-            std::vector<std::vector<unsigned char>> vSolutions2;
+            std::vector<std::vector<uint8_t>> vSolutions2;
             Solver(pubKey2, txType2, vSolutions2);
             sigs1.script.pop_back();
             sigs2.script.pop_back();
             Stacks result = CombineSignatures(pubKey2, checker, txType2,
                                               vSolutions2, sigs1, sigs2);
             result.script.push_back(spk);
             return result;
         }
         case TX_MULTISIG:
             return Stacks(CombineMultisig(scriptPubKey, checker, vSolutions,
                                           sigs1.script, sigs2.script));
         default:
             return Stacks();
     }
 }
 
 SignatureData CombineSignatures(const CScript &scriptPubKey,
                                 const BaseSignatureChecker &checker,
                                 const SignatureData &scriptSig1,
                                 const SignatureData &scriptSig2) {
     txnouttype txType;
-    std::vector<std::vector<unsigned char>> vSolutions;
+    std::vector<std::vector<uint8_t>> vSolutions;
     Solver(scriptPubKey, txType, vSolutions);
 
     return CombineSignatures(scriptPubKey, checker, txType, vSolutions,
                              Stacks(scriptSig1), Stacks(scriptSig2))
         .Output();
 }
 
 namespace {
 /** Dummy signature checker which accepts all signatures. */
 class DummySignatureChecker : public BaseSignatureChecker {
 public:
     DummySignatureChecker() {}
 
-    bool CheckSig(const std::vector<unsigned char> &scriptSig,
-                  const std::vector<unsigned char> &vchPubKey,
+    bool CheckSig(const std::vector<uint8_t> &scriptSig,
+                  const std::vector<uint8_t> &vchPubKey,
                   const CScript &scriptCode, uint32_t flags) const {
         return true;
     }
 };
 const DummySignatureChecker dummyChecker;
 }
 
 const BaseSignatureChecker &DummySignatureCreator::Checker() const {
     return dummyChecker;
 }
 
-bool DummySignatureCreator::CreateSig(std::vector<unsigned char> &vchSig,
+bool DummySignatureCreator::CreateSig(std::vector<uint8_t> &vchSig,
                                       const CKeyID &keyid,
                                       const CScript &scriptCode) const {
     // Create a dummy signature that is a valid DER-encoding
     vchSig.assign(72, '\000');
     vchSig[0] = 0x30;
     vchSig[1] = 69;
     vchSig[2] = 0x02;
     vchSig[3] = 33;
     vchSig[4] = 0x01;
     vchSig[4 + 33] = 0x02;
     vchSig[5 + 33] = 32;
     vchSig[6 + 33] = 0x01;
     vchSig[6 + 33 + 32] = SIGHASH_ALL | SIGHASH_FORKID;
     return true;
 }
diff --git a/src/script/sign.h b/src/script/sign.h
index 7166faaca..027594c2c 100644
--- a/src/script/sign.h
+++ b/src/script/sign.h
@@ -1,109 +1,108 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_SCRIPT_SIGN_H
 #define BITCOIN_SCRIPT_SIGN_H
 
 #include "script/interpreter.h"
 
 class CKeyID;
 class CKeyStore;
 class CScript;
 class CTransaction;
 
 struct CMutableTransaction;
 
 /** Virtual base class for signature creators. */
 class BaseSignatureCreator {
 protected:
     const CKeyStore *keystore;
 
 public:
     BaseSignatureCreator(const CKeyStore *keystoreIn) : keystore(keystoreIn) {}
     const CKeyStore &KeyStore() const { return *keystore; };
     virtual ~BaseSignatureCreator() {}
     virtual const BaseSignatureChecker &Checker() const = 0;
 
     /** Create a singular (non-script) signature. */
-    virtual bool CreateSig(std::vector<unsigned char> &vchSig,
-                           const CKeyID &keyid,
+    virtual bool CreateSig(std::vector<uint8_t> &vchSig, const CKeyID &keyid,
                            const CScript &scriptCode) const = 0;
 };
 
 /** A signature creator for transactions. */
 class TransactionSignatureCreator : public BaseSignatureCreator {
     const CTransaction *txTo;
     unsigned int nIn;
     CAmount amount;
     uint32_t nHashType;
     const TransactionSignatureChecker checker;
 
 public:
     TransactionSignatureCreator(const CKeyStore *keystoreIn,
                                 const CTransaction *txToIn, unsigned int nInIn,
                                 const CAmount &amountIn,
                                 uint32_t nHashTypeIn = SIGHASH_ALL);
     const BaseSignatureChecker &Checker() const { return checker; }
-    bool CreateSig(std::vector<unsigned char> &vchSig, const CKeyID &keyid,
+    bool CreateSig(std::vector<uint8_t> &vchSig, const CKeyID &keyid,
                    const CScript &scriptCode) const;
 };
 
 class MutableTransactionSignatureCreator : public TransactionSignatureCreator {
     CTransaction tx;
 
 public:
     MutableTransactionSignatureCreator(const CKeyStore *keystoreIn,
                                        const CMutableTransaction *txToIn,
                                        unsigned int nInIn,
                                        const CAmount &amount,
                                        uint32_t nHashTypeIn)
         : TransactionSignatureCreator(keystoreIn, &tx, nInIn, amount,
                                       nHashTypeIn),
           tx(*txToIn) {}
 };
 
 /** A signature creator that just produces 72-byte empty signatures. */
 class DummySignatureCreator : public BaseSignatureCreator {
 public:
     DummySignatureCreator(const CKeyStore *keystoreIn)
         : BaseSignatureCreator(keystoreIn) {}
     const BaseSignatureChecker &Checker() const;
-    bool CreateSig(std::vector<unsigned char> &vchSig, const CKeyID &keyid,
+    bool CreateSig(std::vector<uint8_t> &vchSig, const CKeyID &keyid,
                    const CScript &scriptCode) const;
 };
 
 struct SignatureData {
     CScript scriptSig;
 
     SignatureData() {}
     explicit SignatureData(const CScript &script) : scriptSig(script) {}
 };
 
 /** Produce a script signature using a generic signature creator. */
 bool ProduceSignature(const BaseSignatureCreator &creator,
                       const CScript &scriptPubKey, SignatureData &sigdata);
 
 /** Produce a script signature for a transaction. */
 bool SignSignature(const CKeyStore &keystore, const CScript &fromPubKey,
                    CMutableTransaction &txTo, unsigned int nIn,
                    const CAmount &amount, uint32_t nHashType);
 bool SignSignature(const CKeyStore &keystore, const CTransaction &txFrom,
                    CMutableTransaction &txTo, unsigned int nIn,
                    uint32_t nHashType);
 
 /** Combine two script signatures using a generic signature checker,
  * intelligently, possibly with OP_0 placeholders. */
 SignatureData CombineSignatures(const CScript &scriptPubKey,
                                 const BaseSignatureChecker &checker,
                                 const SignatureData &scriptSig1,
                                 const SignatureData &scriptSig2);
 
 /** Extract signature data from a transaction, and insert it. */
 SignatureData DataFromTransaction(const CMutableTransaction &tx,
                                   unsigned int nIn);
 void UpdateTransaction(CMutableTransaction &tx, unsigned int nIn,
                        const SignatureData &data);
 
 #endif // BITCOIN_SCRIPT_SIGN_H
diff --git a/src/script/standard.cpp b/src/script/standard.cpp
index 137f08909..564588e47 100644
--- a/src/script/standard.cpp
+++ b/src/script/standard.cpp
@@ -1,257 +1,257 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #include "script/standard.h"
 
 #include "pubkey.h"
 #include "script/script.h"
 #include "util.h"
 #include "utilstrencodings.h"
 
 typedef std::vector<uint8_t> valtype;
 
 bool fAcceptDatacarrier = DEFAULT_ACCEPT_DATACARRIER;
 unsigned nMaxDatacarrierBytes = MAX_OP_RETURN_RELAY;
 
 CScriptID::CScriptID(const CScript &in)
     : uint160(Hash160(in.begin(), in.end())) {}
 
 const char *GetTxnOutputType(txnouttype t) {
     switch (t) {
         case TX_NONSTANDARD:
             return "nonstandard";
         case TX_PUBKEY:
             return "pubkey";
         case TX_PUBKEYHASH:
             return "pubkeyhash";
         case TX_SCRIPTHASH:
             return "scripthash";
         case TX_MULTISIG:
             return "multisig";
         case TX_NULL_DATA:
             return "nulldata";
     }
     return nullptr;
 }
 
 /**
  * Return public keys or hashes from scriptPubKey, for 'standard' transaction
  * types.
  */
 bool Solver(const CScript &scriptPubKey, txnouttype &typeRet,
             std::vector<std::vector<uint8_t>> &vSolutionsRet) {
     // Templates
     static std::multimap<txnouttype, CScript> mTemplates;
     if (mTemplates.empty()) {
         // Standard tx, sender provides pubkey, receiver adds signature
         mTemplates.insert(
             std::make_pair(TX_PUBKEY, CScript() << OP_PUBKEY << OP_CHECKSIG));
 
         // Bitcoin address tx, sender provides hash of pubkey, receiver provides
         // signature and pubkey
         mTemplates.insert(std::make_pair(
             TX_PUBKEYHASH, CScript() << OP_DUP << OP_HASH160 << OP_PUBKEYHASH
                                      << OP_EQUALVERIFY << OP_CHECKSIG));
 
         // Sender provides N pubkeys, receivers provides M signatures
         mTemplates.insert(std::make_pair(
             TX_MULTISIG, CScript() << OP_SMALLINTEGER << OP_PUBKEYS
                                    << OP_SMALLINTEGER << OP_CHECKMULTISIG));
     }
 
     vSolutionsRet.clear();
 
     // Shortcut for pay-to-script-hash, which are more constrained than the
     // other types:
     // it is always OP_HASH160 20 [20 byte hash] OP_EQUAL
     if (scriptPubKey.IsPayToScriptHash()) {
         typeRet = TX_SCRIPTHASH;
         std::vector<uint8_t> hashBytes(scriptPubKey.begin() + 2,
                                        scriptPubKey.begin() + 22);
         vSolutionsRet.push_back(hashBytes);
         return true;
     }
 
     // Provably prunable, data-carrying output
     //
     // So long as script passes the IsUnspendable() test and all but the first
     // byte passes the IsPushOnly() test we don't care what exactly is in the
     // script.
     if (scriptPubKey.size() >= 1 && scriptPubKey[0] == OP_RETURN &&
         scriptPubKey.IsPushOnly(scriptPubKey.begin() + 1)) {
         typeRet = TX_NULL_DATA;
         return true;
     }
 
     // Scan templates
     const CScript &script1 = scriptPubKey;
     for (const std::pair<txnouttype, CScript> &tplate : mTemplates) {
         const CScript &script2 = tplate.second;
         vSolutionsRet.clear();
 
         opcodetype opcode1, opcode2;
         std::vector<uint8_t> vch1, vch2;
 
         // Compare
         CScript::const_iterator pc1 = script1.begin();
         CScript::const_iterator pc2 = script2.begin();
         while (true) {
             if (pc1 == script1.end() && pc2 == script2.end()) {
                 // Found a match
                 typeRet = tplate.first;
                 if (typeRet == TX_MULTISIG) {
                     // Additional checks for TX_MULTISIG:
-                    unsigned char m = vSolutionsRet.front()[0];
-                    unsigned char n = vSolutionsRet.back()[0];
+                    uint8_t m = vSolutionsRet.front()[0];
+                    uint8_t n = vSolutionsRet.back()[0];
                     if (m < 1 || n < 1 || m > n ||
                         vSolutionsRet.size() - 2 != n)
                         return false;
                 }
                 return true;
             }
             if (!script1.GetOp(pc1, opcode1, vch1)) break;
             if (!script2.GetOp(pc2, opcode2, vch2)) break;
 
             // Template matching opcodes:
             if (opcode2 == OP_PUBKEYS) {
                 while (vch1.size() >= 33 && vch1.size() <= 65) {
                     vSolutionsRet.push_back(vch1);
                     if (!script1.GetOp(pc1, opcode1, vch1)) break;
                 }
                 if (!script2.GetOp(pc2, opcode2, vch2)) break;
                 // Normal situation is to fall through to other if/else
                 // statements
             }
 
             if (opcode2 == OP_PUBKEY) {
                 if (vch1.size() < 33 || vch1.size() > 65) break;
                 vSolutionsRet.push_back(vch1);
             } else if (opcode2 == OP_PUBKEYHASH) {
                 if (vch1.size() != sizeof(uint160)) break;
                 vSolutionsRet.push_back(vch1);
             } else if (opcode2 == OP_SMALLINTEGER) {
                 // Single-byte small integer pushed onto vSolutions
                 if (opcode1 == OP_0 || (opcode1 >= OP_1 && opcode1 <= OP_16)) {
                     char n = (char)CScript::DecodeOP_N(opcode1);
                     vSolutionsRet.push_back(valtype(1, n));
                 } else
                     break;
             } else if (opcode1 != opcode2 || vch1 != vch2) {
                 // Others must match exactly
                 break;
             }
         }
     }
 
     vSolutionsRet.clear();
     typeRet = TX_NONSTANDARD;
     return false;
 }
 
 bool ExtractDestination(const CScript &scriptPubKey,
                         CTxDestination &addressRet) {
     std::vector<valtype> vSolutions;
     txnouttype whichType;
     if (!Solver(scriptPubKey, whichType, vSolutions)) return false;
 
     if (whichType == TX_PUBKEY) {
         CPubKey pubKey(vSolutions[0]);
         if (!pubKey.IsValid()) return false;
 
         addressRet = pubKey.GetID();
         return true;
     } else if (whichType == TX_PUBKEYHASH) {
         addressRet = CKeyID(uint160(vSolutions[0]));
         return true;
     } else if (whichType == TX_SCRIPTHASH) {
         addressRet = CScriptID(uint160(vSolutions[0]));
         return true;
     }
     // Multisig txns have more than one address...
     return false;
 }
 
 bool ExtractDestinations(const CScript &scriptPubKey, txnouttype &typeRet,
                          std::vector<CTxDestination> &addressRet,
                          int &nRequiredRet) {
     addressRet.clear();
     typeRet = TX_NONSTANDARD;
     std::vector<valtype> vSolutions;
     if (!Solver(scriptPubKey, typeRet, vSolutions)) return false;
     if (typeRet == TX_NULL_DATA) {
         // This is data, not addresses
         return false;
     }
 
     if (typeRet == TX_MULTISIG) {
         nRequiredRet = vSolutions.front()[0];
         for (unsigned int i = 1; i < vSolutions.size() - 1; i++) {
             CPubKey pubKey(vSolutions[i]);
             if (!pubKey.IsValid()) continue;
 
             CTxDestination address = pubKey.GetID();
             addressRet.push_back(address);
         }
 
         if (addressRet.empty()) return false;
     } else {
         nRequiredRet = 1;
         CTxDestination address;
         if (!ExtractDestination(scriptPubKey, address)) return false;
         addressRet.push_back(address);
     }
 
     return true;
 }
 
 namespace {
 class CScriptVisitor : public boost::static_visitor<bool> {
 private:
     CScript *script;
 
 public:
     CScriptVisitor(CScript *scriptin) { script = scriptin; }
 
     bool operator()(const CNoDestination &dest) const {
         script->clear();
         return false;
     }
 
     bool operator()(const CKeyID &keyID) const {
         script->clear();
         *script << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY
                 << OP_CHECKSIG;
         return true;
     }
 
     bool operator()(const CScriptID &scriptID) const {
         script->clear();
         *script << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL;
         return true;
     }
 };
 }
 
 CScript GetScriptForDestination(const CTxDestination &dest) {
     CScript script;
 
     boost::apply_visitor(CScriptVisitor(&script), dest);
     return script;
 }
 
 CScript GetScriptForRawPubKey(const CPubKey &pubKey) {
-    return CScript() << std::vector<unsigned char>(pubKey.begin(), pubKey.end())
+    return CScript() << std::vector<uint8_t>(pubKey.begin(), pubKey.end())
                      << OP_CHECKSIG;
 }
 
 CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey> &keys) {
     CScript script;
 
     script << CScript::EncodeOP_N(nRequired);
     for (const CPubKey &key : keys)
         script << ToByteVector(key);
     script << CScript::EncodeOP_N(keys.size()) << OP_CHECKMULTISIG;
     return script;
 }
diff --git a/src/script/standard.h b/src/script/standard.h
index a68a02131..b779ea4af 100644
--- a/src/script/standard.h
+++ b/src/script/standard.h
@@ -1,89 +1,89 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_SCRIPT_STANDARD_H
 #define BITCOIN_SCRIPT_STANDARD_H
 
 #include "script/interpreter.h"
 #include "uint256.h"
 
 #include <boost/variant.hpp>
 
 #include <cstdint>
 
 static const bool DEFAULT_ACCEPT_DATACARRIER = true;
 
 class CKeyID;
 class CScript;
 
 /** A reference to a CScript: the Hash160 of its serialization (see script.h) */
 class CScriptID : public uint160 {
 public:
     CScriptID() : uint160() {}
     CScriptID(const CScript &in);
     CScriptID(const uint160 &in) : uint160(in) {}
 };
 
 //!< bytes (+1 for OP_RETURN, +2 for the pushdata opcodes)
 static const unsigned int MAX_OP_RETURN_RELAY = 83;
 extern bool fAcceptDatacarrier;
 extern unsigned nMaxDatacarrierBytes;
 
 /**
  * Mandatory script verification flags that all new blocks must comply with for
  * them to be valid. (but old blocks may not comply with) Currently just P2SH,
  * but in the future other flags may be added, such as a soft-fork to enforce
  * strict DER encoding.
  *
  * Failing one of these tests may trigger a DoS ban - see CheckInputs() for
  * details.
  */
 static const unsigned int MANDATORY_SCRIPT_VERIFY_FLAGS =
     SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC;
 
 enum txnouttype {
     TX_NONSTANDARD,
     // 'standard' transaction types:
     TX_PUBKEY,
     TX_PUBKEYHASH,
     TX_SCRIPTHASH,
     TX_MULTISIG,
     TX_NULL_DATA,
 };
 
 class CNoDestination {
 public:
     friend bool operator==(const CNoDestination &a, const CNoDestination &b) {
         return true;
     }
     friend bool operator<(const CNoDestination &a, const CNoDestination &b) {
         return true;
     }
 };
 
 /**
  * A txout script template with a specific destination. It is either:
  *  * CNoDestination: no destination set
  *  * CKeyID: TX_PUBKEYHASH destination
  *  * CScriptID: TX_SCRIPTHASH destination
  *  A CTxDestination is the internal data type encoded in a CBitcoinAddress
  */
 typedef boost::variant<CNoDestination, CKeyID, CScriptID> CTxDestination;
 
 const char *GetTxnOutputType(txnouttype t);
 
 bool Solver(const CScript &scriptPubKey, txnouttype &typeRet,
-            std::vector<std::vector<unsigned char>> &vSolutionsRet);
+            std::vector<std::vector<uint8_t>> &vSolutionsRet);
 bool ExtractDestination(const CScript &scriptPubKey,
                         CTxDestination &addressRet);
 bool ExtractDestinations(const CScript &scriptPubKey, txnouttype &typeRet,
                          std::vector<CTxDestination> &addressRet,
                          int &nRequiredRet);
 
 CScript GetScriptForDestination(const CTxDestination &dest);
 CScript GetScriptForRawPubKey(const CPubKey &pubkey);
 CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey> &keys);
 
 #endif // BITCOIN_SCRIPT_STANDARD_H
diff --git a/src/serialize.h b/src/serialize.h
index 45b2d9675..1b865bd87 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -1,898 +1,894 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_SERIALIZE_H
 #define BITCOIN_SERIALIZE_H
 
 #include "compat/endian.h"
 
 #include <algorithm>
 #include <cassert>
 #include <cstdint>
 #include <cstring>
 #include <ios>
 #include <limits>
 #include <map>
 #include <memory>
 #include <set>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "prevector.h"
 
 static const uint64_t MAX_SIZE = 0x02000000;
 
 /**
  * Dummy data type to identify deserializing constructors.
  *
  * By convention, a constructor of a type T with signature
  *
  *   template <typename Stream> T::T(deserialize_type, Stream& s)
  *
  * is a deserializing constructor, which builds the type by deserializing it
  * from s. If T contains const fields, this is likely the only way to do so.
  */
 struct deserialize_type {};
 constexpr deserialize_type deserialize{};
 
 /**
  * Used to bypass the rule against non-const reference to temporary where it
  * makes sense with wrappers such as CFlatData or CTxDB
  */
 template <typename T> inline T &REF(const T &val) {
     return const_cast<T &>(val);
 }
 
 /**
  * Used to acquire a non-const pointer "this" to generate bodies of const
  * serialization operations from a template
  */
 template <typename T> inline T *NCONST_PTR(const T *val) {
     return const_cast<T *>(val);
 }
 
 /*
  * Lowest-level serialization and conversion.
  * @note Sizes of these types are verified in the tests
  */
 template <typename Stream> inline void ser_writedata8(Stream &s, uint8_t obj) {
     s.write((char *)&obj, 1);
 }
 template <typename Stream>
 inline void ser_writedata16(Stream &s, uint16_t obj) {
     obj = htole16(obj);
     s.write((char *)&obj, 2);
 }
 template <typename Stream>
 inline void ser_writedata32(Stream &s, uint32_t obj) {
     obj = htole32(obj);
     s.write((char *)&obj, 4);
 }
 template <typename Stream>
 inline void ser_writedata64(Stream &s, uint64_t obj) {
     obj = htole64(obj);
     s.write((char *)&obj, 8);
 }
 template <typename Stream> inline uint8_t ser_readdata8(Stream &s) {
     uint8_t obj;
     s.read((char *)&obj, 1);
     return obj;
 }
 template <typename Stream> inline uint16_t ser_readdata16(Stream &s) {
     uint16_t obj;
     s.read((char *)&obj, 2);
     return le16toh(obj);
 }
 template <typename Stream> inline uint32_t ser_readdata32(Stream &s) {
     uint32_t obj;
     s.read((char *)&obj, 4);
     return le32toh(obj);
 }
 template <typename Stream> inline uint64_t ser_readdata64(Stream &s) {
     uint64_t obj;
     s.read((char *)&obj, 8);
     return le64toh(obj);
 }
 inline uint64_t ser_double_to_uint64(double x) {
     union {
         double x;
         uint64_t y;
     } tmp;
     tmp.x = x;
     return tmp.y;
 }
 inline uint32_t ser_float_to_uint32(float x) {
     union {
         float x;
         uint32_t y;
     } tmp;
     tmp.x = x;
     return tmp.y;
 }
 inline double ser_uint64_to_double(uint64_t y) {
     union {
         double x;
         uint64_t y;
     } tmp;
     tmp.y = y;
     return tmp.x;
 }
 inline float ser_uint32_to_float(uint32_t y) {
     union {
         float x;
         uint32_t y;
     } tmp;
     tmp.y = y;
     return tmp.x;
 }
 
 /////////////////////////////////////////////////////////////////
 //
 // Templates for serializing to anything that looks like a stream,
 // i.e. anything that supports .read(char*, size_t) and .write(char*, size_t)
 //
 class CSizeComputer;
 
 enum {
     // primary actions
     SER_NETWORK = (1 << 0),
     SER_DISK = (1 << 1),
     SER_GETHASH = (1 << 2),
 };
 
 #define READWRITE(obj) (::SerReadWrite(s, (obj), ser_action))
 #define READWRITEMANY(...) (::SerReadWriteMany(s, ser_action, __VA_ARGS__))
 
 /**
  * Implement three methods for serializable objects. These are actually wrappers
  * over "SerializationOp" template, which implements the body of each class'
  * serialization code. Adding "ADD_SERIALIZE_METHODS" in the body of the class
  * causes these wrappers to be added as members.
  */
 #define ADD_SERIALIZE_METHODS                                                  \
     template <typename Stream> void Serialize(Stream &s) const {               \
         NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize());           \
     }                                                                          \
     template <typename Stream> void Unserialize(Stream &s) {                   \
         SerializationOp(s, CSerActionUnserialize());                           \
     }
 
 template <typename Stream> inline void Serialize(Stream &s, char a) {
     ser_writedata8(s, a);
 } // TODO Get rid of bare char
 template <typename Stream> inline void Serialize(Stream &s, int8_t a) {
     ser_writedata8(s, a);
 }
 template <typename Stream> inline void Serialize(Stream &s, uint8_t a) {
     ser_writedata8(s, a);
 }
 template <typename Stream> inline void Serialize(Stream &s, int16_t a) {
     ser_writedata16(s, a);
 }
 template <typename Stream> inline void Serialize(Stream &s, uint16_t a) {
     ser_writedata16(s, a);
 }
 template <typename Stream> inline void Serialize(Stream &s, int32_t a) {
     ser_writedata32(s, a);
 }
 template <typename Stream> inline void Serialize(Stream &s, uint32_t a) {
     ser_writedata32(s, a);
 }
 template <typename Stream> inline void Serialize(Stream &s, int64_t a) {
     ser_writedata64(s, a);
 }
 template <typename Stream> inline void Serialize(Stream &s, uint64_t a) {
     ser_writedata64(s, a);
 }
 template <typename Stream> inline void Serialize(Stream &s, float a) {
     ser_writedata32(s, ser_float_to_uint32(a));
 }
 template <typename Stream> inline void Serialize(Stream &s, double a) {
     ser_writedata64(s, ser_double_to_uint64(a));
 }
 // TODO Get rid of bare char
 template <typename Stream> inline void Unserialize(Stream &s, char &a) {
     a = ser_readdata8(s);
 }
 template <typename Stream> inline void Unserialize(Stream &s, int8_t &a) {
     a = ser_readdata8(s);
 }
 template <typename Stream> inline void Unserialize(Stream &s, uint8_t &a) {
     a = ser_readdata8(s);
 }
 template <typename Stream> inline void Unserialize(Stream &s, int16_t &a) {
     a = ser_readdata16(s);
 }
 template <typename Stream> inline void Unserialize(Stream &s, uint16_t &a) {
     a = ser_readdata16(s);
 }
 template <typename Stream> inline void Unserialize(Stream &s, int32_t &a) {
     a = ser_readdata32(s);
 }
 template <typename Stream> inline void Unserialize(Stream &s, uint32_t &a) {
     a = ser_readdata32(s);
 }
 template <typename Stream> inline void Unserialize(Stream &s, int64_t &a) {
     a = ser_readdata64(s);
 }
 template <typename Stream> inline void Unserialize(Stream &s, uint64_t &a) {
     a = ser_readdata64(s);
 }
 template <typename Stream> inline void Unserialize(Stream &s, float &a) {
     a = ser_uint32_to_float(ser_readdata32(s));
 }
 template <typename Stream> inline void Unserialize(Stream &s, double &a) {
     a = ser_uint64_to_double(ser_readdata64(s));
 }
 
 template <typename Stream> inline void Serialize(Stream &s, bool a) {
     char f = a;
     ser_writedata8(s, f);
 }
 template <typename Stream> inline void Unserialize(Stream &s, bool &a) {
     char f = ser_readdata8(s);
     a = f;
 }
 
 /**
  * Compact Size
  * size <  253        -- 1 byte
  * size <= USHRT_MAX  -- 3 bytes  (253 + 2 bytes)
  * size <= UINT_MAX   -- 5 bytes  (254 + 4 bytes)
  * size >  UINT_MAX   -- 9 bytes  (255 + 8 bytes)
  */
 inline unsigned int GetSizeOfCompactSize(uint64_t nSize) {
     if (nSize < 253)
-        return sizeof(unsigned char);
+        return sizeof(uint8_t);
     else if (nSize <= std::numeric_limits<unsigned short>::max())
-        return sizeof(unsigned char) + sizeof(unsigned short);
+        return sizeof(uint8_t) + sizeof(unsigned short);
     else if (nSize <= std::numeric_limits<unsigned int>::max())
-        return sizeof(unsigned char) + sizeof(unsigned int);
+        return sizeof(uint8_t) + sizeof(unsigned int);
     else
-        return sizeof(unsigned char) + sizeof(uint64_t);
+        return sizeof(uint8_t) + sizeof(uint64_t);
 }
 
 inline void WriteCompactSize(CSizeComputer &os, uint64_t nSize);
 
 template <typename Stream> void WriteCompactSize(Stream &os, uint64_t nSize) {
     if (nSize < 253) {
         ser_writedata8(os, nSize);
     } else if (nSize <= std::numeric_limits<unsigned short>::max()) {
         ser_writedata8(os, 253);
         ser_writedata16(os, nSize);
     } else if (nSize <= std::numeric_limits<unsigned int>::max()) {
         ser_writedata8(os, 254);
         ser_writedata32(os, nSize);
     } else {
         ser_writedata8(os, 255);
         ser_writedata64(os, nSize);
     }
     return;
 }
 
 template <typename Stream> uint64_t ReadCompactSize(Stream &is) {
     uint8_t chSize = ser_readdata8(is);
     uint64_t nSizeRet = 0;
     if (chSize < 253) {
         nSizeRet = chSize;
     } else if (chSize == 253) {
         nSizeRet = ser_readdata16(is);
         if (nSizeRet < 253)
             throw std::ios_base::failure("non-canonical ReadCompactSize()");
     } else if (chSize == 254) {
         nSizeRet = ser_readdata32(is);
         if (nSizeRet < 0x10000u)
             throw std::ios_base::failure("non-canonical ReadCompactSize()");
     } else {
         nSizeRet = ser_readdata64(is);
         if (nSizeRet < 0x100000000ULL)
             throw std::ios_base::failure("non-canonical ReadCompactSize()");
     }
     if (nSizeRet > MAX_SIZE) {
         throw std::ios_base::failure("ReadCompactSize(): size too large");
     }
     return nSizeRet;
 }
 
 /**
  * Variable-length integers: bytes are a MSB base-128 encoding of the number.
  * The high bit in each byte signifies whether another digit follows. To make
  * sure the encoding is one-to-one, one is subtracted from all but the last
  * digit. Thus, the byte sequence a[] with length len, where all but the last
  * byte has bit 128 set, encodes the number:
  *
  *  (a[len-1] & 0x7F) + sum(i=1..len-1, 128^i*((a[len-i-1] & 0x7F)+1))
  *
  * Properties:
  * * Very small (0-127: 1 byte, 128-16511: 2 bytes, 16512-2113663: 3 bytes)
  * * Every integer has exactly one encoding
  * * Encoding does not depend on size of original integer type
  * * No redundancy: every (infinite) byte sequence corresponds to a list
  *   of encoded integers.
  *
  * 0:         [0x00]  256:        [0x81 0x00]
  * 1:         [0x01]  16383:      [0xFE 0x7F]
  * 127:       [0x7F]  16384:      [0xFF 0x00]
  * 128:  [0x80 0x00]  16511:      [0xFF 0x7F]
  * 255:  [0x80 0x7F]  65535: [0x82 0xFE 0x7F]
  * 2^32:           [0x8E 0xFE 0xFE 0xFF 0x00]
  */
 template <typename I> inline unsigned int GetSizeOfVarInt(I n) {
     int nRet = 0;
     while (true) {
         nRet++;
         if (n <= 0x7F) break;
         n = (n >> 7) - 1;
     }
     return nRet;
 }
 
 template <typename I> inline void WriteVarInt(CSizeComputer &os, I n);
 
 template <typename Stream, typename I> void WriteVarInt(Stream &os, I n) {
-    unsigned char tmp[(sizeof(n) * 8 + 6) / 7];
+    uint8_t tmp[(sizeof(n) * 8 + 6) / 7];
     int len = 0;
     while (true) {
         tmp[len] = (n & 0x7F) | (len ? 0x80 : 0x00);
         if (n <= 0x7F) break;
         n = (n >> 7) - 1;
         len++;
     }
     do {
         ser_writedata8(os, tmp[len]);
     } while (len--);
 }
 
 template <typename Stream, typename I> I ReadVarInt(Stream &is) {
     I n = 0;
     while (true) {
-        unsigned char chData = ser_readdata8(is);
+        uint8_t chData = ser_readdata8(is);
         n = (n << 7) | (chData & 0x7F);
         if (chData & 0x80)
             n++;
         else
             return n;
     }
 }
 
 #define FLATDATA(obj)                                                          \
     REF(CFlatData((char *)&(obj), (char *)&(obj) + sizeof(obj)))
 #define VARINT(obj) REF(WrapVarInt(REF(obj)))
 #define COMPACTSIZE(obj) REF(CCompactSize(REF(obj)))
 #define LIMITED_STRING(obj, n) REF(LimitedString<n>(REF(obj)))
 
 /**
  * Wrapper for serializing arrays and POD.
  */
 class CFlatData {
 protected:
     char *pbegin;
     char *pend;
 
 public:
     CFlatData(void *pbeginIn, void *pendIn)
         : pbegin((char *)pbeginIn), pend((char *)pendIn) {}
     template <class T, class TAl> explicit CFlatData(std::vector<T, TAl> &v) {
         pbegin = (char *)v.data();
         pend = (char *)(v.data() + v.size());
     }
     template <unsigned int N, typename T, typename S, typename D>
     explicit CFlatData(prevector<N, T, S, D> &v) {
         pbegin = (char *)v.data();
         pend = (char *)(v.data() + v.size());
     }
     char *begin() { return pbegin; }
     const char *begin() const { return pbegin; }
     char *end() { return pend; }
     const char *end() const { return pend; }
 
     template <typename Stream> void Serialize(Stream &s) const {
         s.write(pbegin, pend - pbegin);
     }
 
     template <typename Stream> void Unserialize(Stream &s) {
         s.read(pbegin, pend - pbegin);
     }
 };
 
 template <typename I> class CVarInt {
 protected:
     I &n;
 
 public:
     CVarInt(I &nIn) : n(nIn) {}
 
     template <typename Stream> void Serialize(Stream &s) const {
         WriteVarInt<Stream, I>(s, n);
     }
 
     template <typename Stream> void Unserialize(Stream &s) {
         n = ReadVarInt<Stream, I>(s);
     }
 };
 
 class CCompactSize {
 protected:
     uint64_t &n;
 
 public:
     CCompactSize(uint64_t &nIn) : n(nIn) {}
 
     template <typename Stream> void Serialize(Stream &s) const {
         WriteCompactSize<Stream>(s, n);
     }
 
     template <typename Stream> void Unserialize(Stream &s) {
         n = ReadCompactSize<Stream>(s);
     }
 };
 
 template <size_t Limit> class LimitedString {
 protected:
     std::string &string;
 
 public:
     LimitedString(std::string &_string) : string(_string) {}
 
     template <typename Stream> void Unserialize(Stream &s) {
         size_t size = ReadCompactSize(s);
         if (size > Limit) {
             throw std::ios_base::failure("String length limit exceeded");
         }
         string.resize(size);
         if (size != 0) s.read((char *)&string[0], size);
     }
 
     template <typename Stream> void Serialize(Stream &s) const {
         WriteCompactSize(s, string.size());
         if (!string.empty()) s.write((char *)&string[0], string.size());
     }
 };
 
 template <typename I> CVarInt<I> WrapVarInt(I &n) {
     return CVarInt<I>(n);
 }
 
 /**
  * Forward declarations
  */
 
 /**
  *  string
  */
 template <typename Stream, typename C>
 void Serialize(Stream &os, const std::basic_string<C> &str);
 template <typename Stream, typename C>
 void Unserialize(Stream &is, std::basic_string<C> &str);
 
 /**
  * prevector
- * prevectors of unsigned char are a special case and are intended to be
- * serialized as a single opaque blob.
+ * prevectors of uint8_t are a special case and are intended to be serialized as
+ * a single opaque blob.
  */
 template <typename Stream, unsigned int N, typename T>
-void Serialize_impl(Stream &os, const prevector<N, T> &v,
-                    const unsigned char &);
+void Serialize_impl(Stream &os, const prevector<N, T> &v, const uint8_t &);
 template <typename Stream, unsigned int N, typename T, typename V>
 void Serialize_impl(Stream &os, const prevector<N, T> &v, const V &);
 template <typename Stream, unsigned int N, typename T>
 inline void Serialize(Stream &os, const prevector<N, T> &v);
 template <typename Stream, unsigned int N, typename T>
-void Unserialize_impl(Stream &is, prevector<N, T> &v, const unsigned char &);
+void Unserialize_impl(Stream &is, prevector<N, T> &v, const uint8_t &);
 template <typename Stream, unsigned int N, typename T, typename V>
 void Unserialize_impl(Stream &is, prevector<N, T> &v, const V &);
 template <typename Stream, unsigned int N, typename T>
 inline void Unserialize(Stream &is, prevector<N, T> &v);
 
 /**
  * vector
- * vectors of unsigned char are a special case and are intended to be serialized
- * as a single opaque blob.
+ * vectors of uint8_t are a special case and are intended to be serialized as a
+ * single opaque blob.
  */
 template <typename Stream, typename T, typename A>
-void Serialize_impl(Stream &os, const std::vector<T, A> &v,
-                    const unsigned char &);
+void Serialize_impl(Stream &os, const std::vector<T, A> &v, const uint8_t &);
 template <typename Stream, typename T, typename A, typename V>
 void Serialize_impl(Stream &os, const std::vector<T, A> &v, const V &);
 template <typename Stream, typename T, typename A>
 inline void Serialize(Stream &os, const std::vector<T, A> &v);
 template <typename Stream, typename T, typename A>
-void Unserialize_impl(Stream &is, std::vector<T, A> &v, const unsigned char &);
+void Unserialize_impl(Stream &is, std::vector<T, A> &v, const uint8_t &);
 template <typename Stream, typename T, typename A, typename V>
 void Unserialize_impl(Stream &is, std::vector<T, A> &v, const V &);
 template <typename Stream, typename T, typename A>
 inline void Unserialize(Stream &is, std::vector<T, A> &v);
 
 /**
  * pair
  */
 template <typename Stream, typename K, typename T>
 void Serialize(Stream &os, const std::pair<K, T> &item);
 template <typename Stream, typename K, typename T>
 void Unserialize(Stream &is, std::pair<K, T> &item);
 
 /**
  * map
  */
 template <typename Stream, typename K, typename T, typename Pred, typename A>
 void Serialize(Stream &os, const std::map<K, T, Pred, A> &m);
 template <typename Stream, typename K, typename T, typename Pred, typename A>
 void Unserialize(Stream &is, std::map<K, T, Pred, A> &m);
 
 /**
  * set
  */
 template <typename Stream, typename K, typename Pred, typename A>
 void Serialize(Stream &os, const std::set<K, Pred, A> &m);
 template <typename Stream, typename K, typename Pred, typename A>
 void Unserialize(Stream &is, std::set<K, Pred, A> &m);
 
 /**
  * shared_ptr
  */
 template <typename Stream, typename T>
 void Serialize(Stream &os, const std::shared_ptr<const T> &p);
 template <typename Stream, typename T>
 void Unserialize(Stream &os, std::shared_ptr<const T> &p);
 
 /**
  * unique_ptr
  */
 template <typename Stream, typename T>
 void Serialize(Stream &os, const std::unique_ptr<const T> &p);
 template <typename Stream, typename T>
 void Unserialize(Stream &os, std::unique_ptr<const T> &p);
 
 /**
  * If none of the specialized versions above matched, default to calling member
  * function.
  */
 template <typename Stream, typename T>
 inline void Serialize(Stream &os, const T &a) {
     a.Serialize(os);
 }
 
 template <typename Stream, typename T>
 inline void Unserialize(Stream &is, T &a) {
     a.Unserialize(is);
 }
 
 /**
  * string
  */
 template <typename Stream, typename C>
 void Serialize(Stream &os, const std::basic_string<C> &str) {
     WriteCompactSize(os, str.size());
     if (!str.empty()) os.write((char *)&str[0], str.size() * sizeof(str[0]));
 }
 
 template <typename Stream, typename C>
 void Unserialize(Stream &is, std::basic_string<C> &str) {
     unsigned int nSize = ReadCompactSize(is);
     str.resize(nSize);
     if (nSize != 0) is.read((char *)&str[0], nSize * sizeof(str[0]));
 }
 
 /**
  * prevector
  */
 template <typename Stream, unsigned int N, typename T>
-void Serialize_impl(Stream &os, const prevector<N, T> &v,
-                    const unsigned char &) {
+void Serialize_impl(Stream &os, const prevector<N, T> &v, const uint8_t &) {
     WriteCompactSize(os, v.size());
     if (!v.empty()) os.write((char *)&v[0], v.size() * sizeof(T));
 }
 
 template <typename Stream, unsigned int N, typename T, typename V>
 void Serialize_impl(Stream &os, const prevector<N, T> &v, const V &) {
     WriteCompactSize(os, v.size());
     for (typename prevector<N, T>::const_iterator vi = v.begin(); vi != v.end();
          ++vi)
         ::Serialize(os, (*vi));
 }
 
 template <typename Stream, unsigned int N, typename T>
 inline void Serialize(Stream &os, const prevector<N, T> &v) {
     Serialize_impl(os, v, T());
 }
 
 template <typename Stream, unsigned int N, typename T>
-void Unserialize_impl(Stream &is, prevector<N, T> &v, const unsigned char &) {
+void Unserialize_impl(Stream &is, prevector<N, T> &v, const uint8_t &) {
     // Limit size per read so bogus size value won't cause out of memory
     v.clear();
     unsigned int nSize = ReadCompactSize(is);
     unsigned int i = 0;
     while (i < nSize) {
         unsigned int blk =
             std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
         v.resize(i + blk);
         is.read((char *)&v[i], blk * sizeof(T));
         i += blk;
     }
 }
 
 template <typename Stream, unsigned int N, typename T, typename V>
 void Unserialize_impl(Stream &is, prevector<N, T> &v, const V &) {
     v.clear();
     unsigned int nSize = ReadCompactSize(is);
     unsigned int i = 0;
     unsigned int nMid = 0;
     while (nMid < nSize) {
         nMid += 5000000 / sizeof(T);
         if (nMid > nSize) nMid = nSize;
         v.resize(nMid);
         for (; i < nMid; i++)
             Unserialize(is, v[i]);
     }
 }
 
 template <typename Stream, unsigned int N, typename T>
 inline void Unserialize(Stream &is, prevector<N, T> &v) {
     Unserialize_impl(is, v, T());
 }
 
 /**
  * vector
  */
 template <typename Stream, typename T, typename A>
-void Serialize_impl(Stream &os, const std::vector<T, A> &v,
-                    const unsigned char &) {
+void Serialize_impl(Stream &os, const std::vector<T, A> &v, const uint8_t &) {
     WriteCompactSize(os, v.size());
     if (!v.empty()) os.write((char *)&v[0], v.size() * sizeof(T));
 }
 
 template <typename Stream, typename T, typename A, typename V>
 void Serialize_impl(Stream &os, const std::vector<T, A> &v, const V &) {
     WriteCompactSize(os, v.size());
     for (typename std::vector<T, A>::const_iterator vi = v.begin();
          vi != v.end(); ++vi)
         ::Serialize(os, (*vi));
 }
 
 template <typename Stream, typename T, typename A>
 inline void Serialize(Stream &os, const std::vector<T, A> &v) {
     Serialize_impl(os, v, T());
 }
 
 template <typename Stream, typename T, typename A>
-void Unserialize_impl(Stream &is, std::vector<T, A> &v, const unsigned char &) {
+void Unserialize_impl(Stream &is, std::vector<T, A> &v, const uint8_t &) {
     // Limit size per read so bogus size value won't cause out of memory
     v.clear();
     unsigned int nSize = ReadCompactSize(is);
     unsigned int i = 0;
     while (i < nSize) {
         unsigned int blk =
             std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
         v.resize(i + blk);
         is.read((char *)&v[i], blk * sizeof(T));
         i += blk;
     }
 }
 
 template <typename Stream, typename T, typename A, typename V>
 void Unserialize_impl(Stream &is, std::vector<T, A> &v, const V &) {
     v.clear();
     unsigned int nSize = ReadCompactSize(is);
     unsigned int i = 0;
     unsigned int nMid = 0;
     while (nMid < nSize) {
         nMid += 5000000 / sizeof(T);
         if (nMid > nSize) nMid = nSize;
         v.resize(nMid);
         for (; i < nMid; i++)
             Unserialize(is, v[i]);
     }
 }
 
 template <typename Stream, typename T, typename A>
 inline void Unserialize(Stream &is, std::vector<T, A> &v) {
     Unserialize_impl(is, v, T());
 }
 
 /**
  * pair
  */
 template <typename Stream, typename K, typename T>
 void Serialize(Stream &os, const std::pair<K, T> &item) {
     Serialize(os, item.first);
     Serialize(os, item.second);
 }
 
 template <typename Stream, typename K, typename T>
 void Unserialize(Stream &is, std::pair<K, T> &item) {
     Unserialize(is, item.first);
     Unserialize(is, item.second);
 }
 
 /**
  * map
  */
 template <typename Stream, typename K, typename T, typename Pred, typename A>
 void Serialize(Stream &os, const std::map<K, T, Pred, A> &m) {
     WriteCompactSize(os, m.size());
     for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin();
          mi != m.end(); ++mi)
         Serialize(os, (*mi));
 }
 
 template <typename Stream, typename K, typename T, typename Pred, typename A>
 void Unserialize(Stream &is, std::map<K, T, Pred, A> &m) {
     m.clear();
     unsigned int nSize = ReadCompactSize(is);
     typename std::map<K, T, Pred, A>::iterator mi = m.begin();
     for (unsigned int i = 0; i < nSize; i++) {
         std::pair<K, T> item;
         Unserialize(is, item);
         mi = m.insert(mi, item);
     }
 }
 
 /**
  * set
  */
 template <typename Stream, typename K, typename Pred, typename A>
 void Serialize(Stream &os, const std::set<K, Pred, A> &m) {
     WriteCompactSize(os, m.size());
     for (typename std::set<K, Pred, A>::const_iterator it = m.begin();
          it != m.end(); ++it)
         Serialize(os, (*it));
 }
 
 template <typename Stream, typename K, typename Pred, typename A>
 void Unserialize(Stream &is, std::set<K, Pred, A> &m) {
     m.clear();
     unsigned int nSize = ReadCompactSize(is);
     typename std::set<K, Pred, A>::iterator it = m.begin();
     for (unsigned int i = 0; i < nSize; i++) {
         K key;
         Unserialize(is, key);
         it = m.insert(it, key);
     }
 }
 
 /**
  * unique_ptr
  */
 template <typename Stream, typename T>
 void Serialize(Stream &os, const std::unique_ptr<const T> &p) {
     Serialize(os, *p);
 }
 
 template <typename Stream, typename T>
 void Unserialize(Stream &is, std::unique_ptr<const T> &p) {
     p.reset(new T(deserialize, is));
 }
 
 /**
  * shared_ptr
  */
 template <typename Stream, typename T>
 void Serialize(Stream &os, const std::shared_ptr<const T> &p) {
     Serialize(os, *p);
 }
 
 template <typename Stream, typename T>
 void Unserialize(Stream &is, std::shared_ptr<const T> &p) {
     p = std::make_shared<const T>(deserialize, is);
 }
 
 /**
  * Support for ADD_SERIALIZE_METHODS and READWRITE macro
  */
 struct CSerActionSerialize {
     constexpr bool ForRead() const { return false; }
 };
 struct CSerActionUnserialize {
     constexpr bool ForRead() const { return true; }
 };
 
 template <typename Stream, typename T>
 inline void SerReadWrite(Stream &s, const T &obj,
                          CSerActionSerialize ser_action) {
     ::Serialize(s, obj);
 }
 
 template <typename Stream, typename T>
 inline void SerReadWrite(Stream &s, T &obj, CSerActionUnserialize ser_action) {
     ::Unserialize(s, obj);
 }
 
 /**
  * ::GetSerializeSize implementations
  *
  * Computing the serialized size of objects is done through a special stream
  * object of type CSizeComputer, which only records the number of bytes written
  * to it.
  *
  * If your Serialize or SerializationOp method has non-trivial overhead for
  * serialization, it may be worthwhile to implement a specialized version for
  * CSizeComputer, which uses the s.seek() method to record bytes that would
  * be written instead.
  */
 class CSizeComputer {
 protected:
     size_t nSize;
 
     const int nType;
     const int nVersion;
 
 public:
     CSizeComputer(int nTypeIn, int nVersionIn)
         : nSize(0), nType(nTypeIn), nVersion(nVersionIn) {}
 
     void write(const char *psz, size_t _nSize) { this->nSize += _nSize; }
 
     /** Pretend _nSize bytes are written, without specifying them. */
     void seek(size_t _nSize) { this->nSize += _nSize; }
 
     template <typename T> CSizeComputer &operator<<(const T &obj) {
         ::Serialize(*this, obj);
         return (*this);
     }
 
     size_t size() const { return nSize; }
 
     int GetVersion() const { return nVersion; }
     int GetType() const { return nType; }
 };
 
 template <typename Stream> void SerializeMany(Stream &s) {}
 
 template <typename Stream, typename Arg>
 void SerializeMany(Stream &s, Arg &&arg) {
     ::Serialize(s, std::forward<Arg>(arg));
 }
 
 template <typename Stream, typename Arg, typename... Args>
 void SerializeMany(Stream &s, Arg &&arg, Args &&... args) {
     ::Serialize(s, std::forward<Arg>(arg));
     ::SerializeMany(s, std::forward<Args>(args)...);
 }
 
 template <typename Stream> inline void UnserializeMany(Stream &s) {}
 
 template <typename Stream, typename Arg>
 inline void UnserializeMany(Stream &s, Arg &arg) {
     ::Unserialize(s, arg);
 }
 
 template <typename Stream, typename Arg, typename... Args>
 inline void UnserializeMany(Stream &s, Arg &arg, Args &... args) {
     ::Unserialize(s, arg);
     ::UnserializeMany(s, args...);
 }
 
 template <typename Stream, typename... Args>
 inline void SerReadWriteMany(Stream &s, CSerActionSerialize ser_action,
                              Args &&... args) {
     ::SerializeMany(s, std::forward<Args>(args)...);
 }
 
 template <typename Stream, typename... Args>
 inline void SerReadWriteMany(Stream &s, CSerActionUnserialize ser_action,
                              Args &... args) {
     ::UnserializeMany(s, args...);
 }
 
 template <typename I> inline void WriteVarInt(CSizeComputer &s, I n) {
     s.seek(GetSizeOfVarInt<I>(n));
 }
 
 inline void WriteCompactSize(CSizeComputer &s, uint64_t nSize) {
     s.seek(GetSizeOfCompactSize(nSize));
 }
 
 template <typename T>
 size_t GetSerializeSize(const T &t, int nType, int nVersion = 0) {
     return (CSizeComputer(nType, nVersion) << t).size();
 }
 
 template <typename S, typename T>
 size_t GetSerializeSize(const S &s, const T &t) {
     return (CSizeComputer(s.GetType(), s.GetVersion()) << t).size();
 }
 
 #endif // BITCOIN_SERIALIZE_H
diff --git a/src/streams.h b/src/streams.h
index 70b66c927..005d73275 100644
--- a/src/streams.h
+++ b/src/streams.h
@@ -1,664 +1,661 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_STREAMS_H
 #define BITCOIN_STREAMS_H
 
 #include "serialize.h"
 #include "support/allocators/zeroafterfree.h"
 
 #include <algorithm>
 #include <cassert>
 #include <cstdint>
 #include <cstdio>
 #include <cstring>
 #include <ios>
 #include <limits>
 #include <map>
 #include <set>
 #include <string>
 #include <utility>
 #include <vector>
 
 template <typename Stream> class OverrideStream {
     Stream *stream;
 
     const int nType;
     const int nVersion;
 
 public:
     OverrideStream(Stream *stream_, int nType_, int nVersion_)
         : stream(stream_), nType(nType_), nVersion(nVersion_) {}
 
     template <typename T> OverrideStream<Stream> &operator<<(const T &obj) {
         // Serialize to this stream
         ::Serialize(*this, obj);
         return (*this);
     }
 
     template <typename T> OverrideStream<Stream> &operator>>(T &obj) {
         // Unserialize from this stream
         ::Unserialize(*this, obj);
         return (*this);
     }
 
     void write(const char *pch, size_t nSize) { stream->write(pch, nSize); }
 
     void read(char *pch, size_t nSize) { stream->read(pch, nSize); }
 
     int GetVersion() const { return nVersion; }
     int GetType() const { return nType; }
 };
 
 template <typename S> OverrideStream<S> WithOrVersion(S *s, int nVersionFlag) {
     return OverrideStream<S>(s, s->GetType(), s->GetVersion() | nVersionFlag);
 }
 
 /**
  * Minimal stream for overwriting and/or appending to an existing byte vector.
  *
  * The referenced vector will grow as necessary.
  */
 class CVectorWriter {
 public:
     /**
      * @param[in]  nTypeIn Serialization Type
      * @param[in]  nVersionIn Serialization Version (including any flags)
      * @param[in]  vchDataIn  Referenced byte vector to overwrite/append
      * @param[in]  nPosIn Starting position. Vector index where writes should
      * start. The vector will initially grow as necessary to  max(index,
      * vec.size()). So to append, use vec.size().
      */
-    CVectorWriter(int nTypeIn, int nVersionIn,
-                  std::vector<unsigned char> &vchDataIn, size_t nPosIn)
+    CVectorWriter(int nTypeIn, int nVersionIn, std::vector<uint8_t> &vchDataIn,
+                  size_t nPosIn)
         : nType(nTypeIn), nVersion(nVersionIn), vchData(vchDataIn),
           nPos(nPosIn) {
         if (nPos > vchData.size()) vchData.resize(nPos);
     }
     /**
      * (other params same as above)
      * @param[in]  args  A list of items to serialize starting at nPos.
      */
     template <typename... Args>
-    CVectorWriter(int nTypeIn, int nVersionIn,
-                  std::vector<unsigned char> &vchDataIn, size_t nPosIn,
-                  Args &&... args)
+    CVectorWriter(int nTypeIn, int nVersionIn, std::vector<uint8_t> &vchDataIn,
+                  size_t nPosIn, Args &&... args)
         : CVectorWriter(nTypeIn, nVersionIn, vchDataIn, nPosIn) {
         ::SerializeMany(*this, std::forward<Args>(args)...);
     }
     void write(const char *pch, size_t nSize) {
         assert(nPos <= vchData.size());
         size_t nOverwrite = std::min(nSize, vchData.size() - nPos);
         if (nOverwrite) {
             memcpy(vchData.data() + nPos,
-                   reinterpret_cast<const unsigned char *>(pch), nOverwrite);
+                   reinterpret_cast<const uint8_t *>(pch), nOverwrite);
         }
         if (nOverwrite < nSize) {
-            vchData.insert(
-                vchData.end(),
-                reinterpret_cast<const unsigned char *>(pch) + nOverwrite,
-                reinterpret_cast<const unsigned char *>(pch) + nSize);
+            vchData.insert(vchData.end(),
+                           reinterpret_cast<const uint8_t *>(pch) + nOverwrite,
+                           reinterpret_cast<const uint8_t *>(pch) + nSize);
         }
         nPos += nSize;
     }
     template <typename T> CVectorWriter &operator<<(const T &obj) {
         // Serialize to this stream
         ::Serialize(*this, obj);
         return (*this);
     }
     int GetVersion() const { return nVersion; }
     int GetType() const { return nType; }
     void seek(size_t nSize) {
         nPos += nSize;
         if (nPos > vchData.size()) vchData.resize(nPos);
     }
 
 private:
     const int nType;
     const int nVersion;
-    std::vector<unsigned char> &vchData;
+    std::vector<uint8_t> &vchData;
     size_t nPos;
 };
 
 /** Double ended buffer combining vector and stream-like interfaces.
  *
  * >> and << read and write unformatted data using the above serialization
  * templates. Fills with data in linear time; some stringstream implementations
  * take N^2 time.
  */
 class CDataStream {
 protected:
     typedef CSerializeData vector_type;
     vector_type vch;
     unsigned int nReadPos;
 
     int nType;
     int nVersion;
 
 public:
     typedef vector_type::allocator_type allocator_type;
     typedef vector_type::size_type size_type;
     typedef vector_type::difference_type difference_type;
     typedef vector_type::reference reference;
     typedef vector_type::const_reference const_reference;
     typedef vector_type::value_type value_type;
     typedef vector_type::iterator iterator;
     typedef vector_type::const_iterator const_iterator;
     typedef vector_type::reverse_iterator reverse_iterator;
 
     explicit CDataStream(int nTypeIn, int nVersionIn) {
         Init(nTypeIn, nVersionIn);
     }
 
     CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn,
                 int nVersionIn)
         : vch(pbegin, pend) {
         Init(nTypeIn, nVersionIn);
     }
 
     CDataStream(const char *pbegin, const char *pend, int nTypeIn,
                 int nVersionIn)
         : vch(pbegin, pend) {
         Init(nTypeIn, nVersionIn);
     }
 
     CDataStream(const vector_type &vchIn, int nTypeIn, int nVersionIn)
         : vch(vchIn.begin(), vchIn.end()) {
         Init(nTypeIn, nVersionIn);
     }
 
     CDataStream(const std::vector<char> &vchIn, int nTypeIn, int nVersionIn)
         : vch(vchIn.begin(), vchIn.end()) {
         Init(nTypeIn, nVersionIn);
     }
 
-    CDataStream(const std::vector<unsigned char> &vchIn, int nTypeIn,
-                int nVersionIn)
+    CDataStream(const std::vector<uint8_t> &vchIn, int nTypeIn, int nVersionIn)
         : vch(vchIn.begin(), vchIn.end()) {
         Init(nTypeIn, nVersionIn);
     }
 
     template <typename... Args>
     CDataStream(int nTypeIn, int nVersionIn, Args &&... args) {
         Init(nTypeIn, nVersionIn);
         ::SerializeMany(*this, std::forward<Args>(args)...);
     }
 
     void Init(int nTypeIn, int nVersionIn) {
         nReadPos = 0;
         nType = nTypeIn;
         nVersion = nVersionIn;
     }
 
     CDataStream &operator+=(const CDataStream &b) {
         vch.insert(vch.end(), b.begin(), b.end());
         return *this;
     }
 
     friend CDataStream operator+(const CDataStream &a, const CDataStream &b) {
         CDataStream ret = a;
         ret += b;
         return (ret);
     }
 
     std::string str() const { return (std::string(begin(), end())); }
 
     //
     // Vector subset
     //
     const_iterator begin() const { return vch.begin() + nReadPos; }
     iterator begin() { return vch.begin() + nReadPos; }
     const_iterator end() const { return vch.end(); }
     iterator end() { return vch.end(); }
     size_type size() const { return vch.size() - nReadPos; }
     bool empty() const { return vch.size() == nReadPos; }
     void resize(size_type n, value_type c = 0) { vch.resize(n + nReadPos, c); }
     void reserve(size_type n) { vch.reserve(n + nReadPos); }
     const_reference operator[](size_type pos) const {
         return vch[pos + nReadPos];
     }
     reference operator[](size_type pos) { return vch[pos + nReadPos]; }
     void clear() {
         vch.clear();
         nReadPos = 0;
     }
     iterator insert(iterator it, const char &x = char()) {
         return vch.insert(it, x);
     }
     void insert(iterator it, size_type n, const char &x) {
         vch.insert(it, n, x);
     }
     value_type *data() { return vch.data() + nReadPos; }
     const value_type *data() const { return vch.data() + nReadPos; }
 
     void insert(iterator it, std::vector<char>::const_iterator first,
                 std::vector<char>::const_iterator last) {
         if (last == first) {
             return;
         }
 
         assert(last - first > 0);
         if (it == vch.begin() + nReadPos &&
             (unsigned int)(last - first) <= nReadPos) {
             // special case for inserting at the front when there's room
             nReadPos -= (last - first);
             memcpy(&vch[nReadPos], &first[0], last - first);
         } else {
             vch.insert(it, first, last);
         }
     }
 
     void insert(iterator it, const char *first, const char *last) {
         if (last == first) {
             return;
         }
 
         assert(last - first > 0);
         if (it == vch.begin() + nReadPos &&
             (unsigned int)(last - first) <= nReadPos) {
             // special case for inserting at the front when there's room
             nReadPos -= (last - first);
             memcpy(&vch[nReadPos], &first[0], last - first);
         } else {
             vch.insert(it, first, last);
         }
     }
 
     iterator erase(iterator it) {
         if (it == vch.begin() + nReadPos) {
             // special case for erasing from the front
             if (++nReadPos >= vch.size()) {
                 // whenever we reach the end, we take the opportunity to clear
                 // the buffer
                 nReadPos = 0;
                 return vch.erase(vch.begin(), vch.end());
             }
             return vch.begin() + nReadPos;
         } else {
             return vch.erase(it);
         }
     }
 
     iterator erase(iterator first, iterator last) {
         if (first == vch.begin() + nReadPos) {
             // special case for erasing from the front
             if (last == vch.end()) {
                 nReadPos = 0;
                 return vch.erase(vch.begin(), vch.end());
             } else {
                 nReadPos = (last - vch.begin());
                 return last;
             }
         } else
             return vch.erase(first, last);
     }
 
     inline void Compact() {
         vch.erase(vch.begin(), vch.begin() + nReadPos);
         nReadPos = 0;
     }
 
     bool Rewind(size_type n) {
         // Rewind by n characters if the buffer hasn't been compacted yet
         if (n > nReadPos) return false;
         nReadPos -= n;
         return true;
     }
 
     //
     // Stream subset
     //
     bool eof() const { return size() == 0; }
     CDataStream *rdbuf() { return this; }
     int in_avail() { return size(); }
 
     void SetType(int n) { nType = n; }
     int GetType() const { return nType; }
     void SetVersion(int n) { nVersion = n; }
     int GetVersion() const { return nVersion; }
 
     void read(char *pch, size_t nSize) {
         if (nSize == 0) {
             return;
         }
 
         // Read from the beginning of the buffer
         unsigned int nReadPosNext = nReadPos + nSize;
         if (nReadPosNext >= vch.size()) {
             if (nReadPosNext > vch.size()) {
                 throw std::ios_base::failure(
                     "CDataStream::read(): end of data");
             }
             memcpy(pch, &vch[nReadPos], nSize);
             nReadPos = 0;
             vch.clear();
             return;
         }
         memcpy(pch, &vch[nReadPos], nSize);
         nReadPos = nReadPosNext;
     }
 
     void ignore(int nSize) {
         // Ignore from the beginning of the buffer
         if (nSize < 0) {
             throw std::ios_base::failure(
                 "CDataStream::ignore(): nSize negative");
         }
         unsigned int nReadPosNext = nReadPos + nSize;
         if (nReadPosNext >= vch.size()) {
             if (nReadPosNext > vch.size())
                 throw std::ios_base::failure(
                     "CDataStream::ignore(): end of data");
             nReadPos = 0;
             vch.clear();
             return;
         }
         nReadPos = nReadPosNext;
     }
 
     void write(const char *pch, size_t nSize) {
         // Write to the end of the buffer
         vch.insert(vch.end(), pch, pch + nSize);
     }
 
     template <typename Stream> void Serialize(Stream &s) const {
         // Special case: stream << stream concatenates like stream += stream
         if (!vch.empty()) s.write((char *)&vch[0], vch.size() * sizeof(vch[0]));
     }
 
     template <typename T> CDataStream &operator<<(const T &obj) {
         // Serialize to this stream
         ::Serialize(*this, obj);
         return (*this);
     }
 
     template <typename T> CDataStream &operator>>(T &obj) {
         // Unserialize from this stream
         ::Unserialize(*this, obj);
         return (*this);
     }
 
     void GetAndClear(CSerializeData &d) {
         d.insert(d.end(), begin(), end());
         clear();
     }
 
     /**
      * XOR the contents of this stream with a certain key.
      *
      * @param[in] key    The key used to XOR the data in this stream.
      */
-    void Xor(const std::vector<unsigned char> &key) {
+    void Xor(const std::vector<uint8_t> &key) {
         if (key.size() == 0) {
             return;
         }
 
         for (size_type i = 0, j = 0; i != size(); i++) {
             vch[i] ^= key[j++];
 
             // This potentially acts on very many bytes of data, so it's
             // important that we calculate `j`, i.e. the `key` index in this way
             // instead of doing a %, which would effectively be a division for
             // each byte Xor'd -- much slower than need be.
             if (j == key.size()) j = 0;
         }
     }
 };
 
 /**
  * Non-refcounted RAII wrapper for FILE*
  *
  * Will automatically close the file when it goes out of scope if not null. If
  * you're returning the file pointer, return file.release(). If you need to
  * close the file early, use file.fclose() instead of fclose(file).
  */
 class CAutoFile {
 private:
     // Disallow copies
     CAutoFile(const CAutoFile &);
     CAutoFile &operator=(const CAutoFile &);
 
     const int nType;
     const int nVersion;
 
     FILE *file;
 
 public:
     CAutoFile(FILE *filenew, int nTypeIn, int nVersionIn)
         : nType(nTypeIn), nVersion(nVersionIn) {
         file = filenew;
     }
 
     ~CAutoFile() { fclose(); }
 
     void fclose() {
         if (file) {
             ::fclose(file);
             file = nullptr;
         }
     }
 
     /**
      * Get wrapped FILE* with transfer of ownership.
      * @note This will invalidate the CAutoFile object, and makes it the
      * responsibility of the caller of this function to clean up the returned
      * FILE*.
      */
     FILE *release() {
         FILE *ret = file;
         file = nullptr;
         return ret;
     }
 
     /**
      * Get wrapped FILE* without transfer of ownership.
      * @note Ownership of the FILE* will remain with this class. Use this only
      * if the scope of the CAutoFile outlives use of the passed pointer.
      */
     FILE *Get() const { return file; }
 
     /** Return true if the wrapped FILE* is nullptr, false otherwise. */
     bool IsNull() const { return (file == nullptr); }
 
     //
     // Stream subset
     //
     int GetType() const { return nType; }
     int GetVersion() const { return nVersion; }
 
     void read(char *pch, size_t nSize) {
         if (!file)
             throw std::ios_base::failure(
                 "CAutoFile::read: file handle is nullptr");
         if (fread(pch, 1, nSize, file) != nSize)
             throw std::ios_base::failure(feof(file)
                                              ? "CAutoFile::read: end of file"
                                              : "CAutoFile::read: fread failed");
     }
 
     void ignore(size_t nSize) {
         if (!file)
             throw std::ios_base::failure(
                 "CAutoFile::ignore: file handle is nullptr");
-        unsigned char data[4096];
+        uint8_t data[4096];
         while (nSize > 0) {
             size_t nNow = std::min<size_t>(nSize, sizeof(data));
             if (fread(data, 1, nNow, file) != nNow)
                 throw std::ios_base::failure(
                     feof(file) ? "CAutoFile::ignore: end of file"
                                : "CAutoFile::read: fread failed");
             nSize -= nNow;
         }
     }
 
     void write(const char *pch, size_t nSize) {
         if (!file)
             throw std::ios_base::failure(
                 "CAutoFile::write: file handle is nullptr");
         if (fwrite(pch, 1, nSize, file) != nSize)
             throw std::ios_base::failure("CAutoFile::write: write failed");
     }
 
     template <typename T> CAutoFile &operator<<(const T &obj) {
         // Serialize to this stream
         if (!file)
             throw std::ios_base::failure(
                 "CAutoFile::operator<<: file handle is nullptr");
         ::Serialize(*this, obj);
         return (*this);
     }
 
     template <typename T> CAutoFile &operator>>(T &obj) {
         // Unserialize from this stream
         if (!file)
             throw std::ios_base::failure(
                 "CAutoFile::operator>>: file handle is nullptr");
         ::Unserialize(*this, obj);
         return (*this);
     }
 };
 
 /**
  * Non-refcounted RAII wrapper around a FILE* that implements a ring buffer to
  * deserialize from. It guarantees the ability to rewind a given number of
  * bytes.
  *
  * Will automatically close the file when it goes out of scope if not null. If
  * you need to close the file early, use file.fclose() instead of fclose(file).
  */
 class CBufferedFile {
 private:
     // Disallow copies
     CBufferedFile(const CBufferedFile &);
     CBufferedFile &operator=(const CBufferedFile &);
 
     const int nType;
     const int nVersion;
 
     // source file
     FILE *src;
     // how many bytes have been read from source
     uint64_t nSrcPos;
     // how many bytes have been read from this
     uint64_t nReadPos;
     // up to which position we're allowed to read
     uint64_t nReadLimit;
     // how many bytes we guarantee to rewind
     uint64_t nRewind;
     // the buffer
     std::vector<char> vchBuf;
 
 protected:
     // read data from the source to fill the buffer
     bool Fill() {
         unsigned int pos = nSrcPos % vchBuf.size();
         unsigned int readNow = vchBuf.size() - pos;
         unsigned int nAvail = vchBuf.size() - (nSrcPos - nReadPos) - nRewind;
         if (nAvail < readNow) readNow = nAvail;
         if (readNow == 0) return false;
         size_t read = fread((void *)&vchBuf[pos], 1, readNow, src);
         if (read == 0) {
             throw std::ios_base::failure(
                 feof(src) ? "CBufferedFile::Fill: end of file"
                           : "CBufferedFile::Fill: fread failed");
         } else {
             nSrcPos += read;
             return true;
         }
     }
 
 public:
     CBufferedFile(FILE *fileIn, uint64_t nBufSize, uint64_t nRewindIn,
                   int nTypeIn, int nVersionIn)
         : nType(nTypeIn), nVersion(nVersionIn), nSrcPos(0), nReadPos(0),
           nReadLimit((uint64_t)(-1)), nRewind(nRewindIn), vchBuf(nBufSize, 0) {
         src = fileIn;
     }
 
     ~CBufferedFile() { fclose(); }
 
     int GetVersion() const { return nVersion; }
     int GetType() const { return nType; }
 
     void fclose() {
         if (src) {
             ::fclose(src);
             src = nullptr;
         }
     }
 
     // check whether we're at the end of the source file
     bool eof() const { return nReadPos == nSrcPos && feof(src); }
 
     // read a number of bytes
     void read(char *pch, size_t nSize) {
         if (nSize + nReadPos > nReadLimit)
             throw std::ios_base::failure("Read attempted past buffer limit");
         if (nSize + nRewind > vchBuf.size())
             throw std::ios_base::failure("Read larger than buffer size");
         while (nSize > 0) {
             if (nReadPos == nSrcPos) Fill();
             unsigned int pos = nReadPos % vchBuf.size();
             size_t nNow = nSize;
             if (nNow + pos > vchBuf.size()) nNow = vchBuf.size() - pos;
             if (nNow + nReadPos > nSrcPos) nNow = nSrcPos - nReadPos;
             memcpy(pch, &vchBuf[pos], nNow);
             nReadPos += nNow;
             pch += nNow;
             nSize -= nNow;
         }
     }
 
     // return the current reading position
     uint64_t GetPos() { return nReadPos; }
 
     // rewind to a given reading position
     bool SetPos(uint64_t nPos) {
         nReadPos = nPos;
         if (nReadPos + nRewind < nSrcPos) {
             nReadPos = nSrcPos - nRewind;
             return false;
         } else if (nReadPos > nSrcPos) {
             nReadPos = nSrcPos;
             return false;
         } else {
             return true;
         }
     }
 
     bool Seek(uint64_t nPos) {
         long nLongPos = nPos;
         if (nPos != (uint64_t)nLongPos) return false;
         if (fseek(src, nLongPos, SEEK_SET)) return false;
         nLongPos = ftell(src);
         nSrcPos = nLongPos;
         nReadPos = nLongPos;
         return true;
     }
 
     // Prevent reading beyond a certain position. No argument removes the limit.
     bool SetLimit(uint64_t nPos = (uint64_t)(-1)) {
         if (nPos < nReadPos) return false;
         nReadLimit = nPos;
         return true;
     }
 
     template <typename T> CBufferedFile &operator>>(T &obj) {
         // Unserialize from this stream
         ::Unserialize(*this, obj);
         return (*this);
     }
 
     // search for a given byte in the stream, and remain positioned on it
     void FindByte(char ch) {
         while (true) {
             if (nReadPos == nSrcPos) Fill();
             if (vchBuf[nReadPos % vchBuf.size()] == ch) break;
             nReadPos++;
         }
     }
 };
 
 #endif // BITCOIN_STREAMS_H
diff --git a/src/test/arith_uint256_tests.cpp b/src/test/arith_uint256_tests.cpp
index 2094fa182..7f3f81f37 100644
--- a/src/test/arith_uint256_tests.cpp
+++ b/src/test/arith_uint256_tests.cpp
@@ -1,668 +1,668 @@
 // Copyright (c) 2011-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.
 
 #include "arith_uint256.h"
 #include "test/test_bitcoin.h"
 #include "uint256.h"
 #include "version.h"
 #include <boost/test/unit_test.hpp>
 #include <cmath>
 #include <cstdint>
 #include <iomanip>
 #include <limits>
 #include <sstream>
 #include <string>
 
 BOOST_FIXTURE_TEST_SUITE(arith_uint256_tests, BasicTestingSetup)
 
 /// Convert vector to arith_uint256, via uint256 blob
-inline arith_uint256 arith_uint256V(const std::vector<unsigned char> &vch) {
+inline arith_uint256 arith_uint256V(const std::vector<uint8_t> &vch) {
     return UintToArith256(uint256(vch));
 }
 
-const unsigned char R1Array[] =
+const uint8_t R1Array[] =
     "\x9c\x52\x4a\xdb\xcf\x56\x11\x12\x2b\x29\x12\x5e\x5d\x35\xd2\xd2"
     "\x22\x81\xaa\xb5\x33\xf0\x08\x32\xd5\x56\xb1\xf9\xea\xe5\x1d\x7d";
 const char R1ArrayHex[] =
     "7D1DE5EAF9B156D53208F033B5AA8122D2d2355d5e12292b121156cfdb4a529c";
 const double R1Ldouble =
     0.4887374590559308955; // R1L equals roughly R1Ldouble * 2^256
 const arith_uint256 R1L =
-    arith_uint256V(std::vector<unsigned char>(R1Array, R1Array + 32));
+    arith_uint256V(std::vector<uint8_t>(R1Array, R1Array + 32));
 const uint64_t R1LLow64 = 0x121156cfdb4a529cULL;
 
-const unsigned char R2Array[] =
+const uint8_t R2Array[] =
     "\x70\x32\x1d\x7c\x47\xa5\x6b\x40\x26\x7e\x0a\xc3\xa6\x9c\xb6\xbf"
     "\x13\x30\x47\xa3\x19\x2d\xda\x71\x49\x13\x72\xf0\xb4\xca\x81\xd7";
 const arith_uint256 R2L =
-    arith_uint256V(std::vector<unsigned char>(R2Array, R2Array + 32));
+    arith_uint256V(std::vector<uint8_t>(R2Array, R2Array + 32));
 
 const char R1LplusR2L[] =
     "549FB09FEA236A1EA3E31D4D58F1B1369288D204211CA751527CFC175767850C";
 
-const unsigned char ZeroArray[] =
+const uint8_t ZeroArray[] =
     "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
     "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
 const arith_uint256 ZeroL =
-    arith_uint256V(std::vector<unsigned char>(ZeroArray, ZeroArray + 32));
+    arith_uint256V(std::vector<uint8_t>(ZeroArray, ZeroArray + 32));
 
-const unsigned char OneArray[] =
+const uint8_t OneArray[] =
     "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
     "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
 const arith_uint256 OneL =
-    arith_uint256V(std::vector<unsigned char>(OneArray, OneArray + 32));
+    arith_uint256V(std::vector<uint8_t>(OneArray, OneArray + 32));
 
-const unsigned char MaxArray[] =
+const uint8_t MaxArray[] =
     "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
     "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
 const arith_uint256 MaxL =
-    arith_uint256V(std::vector<unsigned char>(MaxArray, MaxArray + 32));
+    arith_uint256V(std::vector<uint8_t>(MaxArray, MaxArray + 32));
 
 const arith_uint256 HalfL = (OneL << 255);
-std::string ArrayToString(const unsigned char A[], unsigned int width) {
+std::string ArrayToString(const uint8_t A[], unsigned int width) {
     std::stringstream Stream;
     Stream << std::hex;
     for (unsigned int i = 0; i < width; ++i) {
         Stream << std::setw(2) << std::setfill('0')
                << (unsigned int)A[width - i - 1];
     }
     return Stream.str();
 }
 
 BOOST_AUTO_TEST_CASE(basics) // constructors, equality, inequality
 {
     BOOST_CHECK(1 == 0 + 1);
     // constructor arith_uint256(vector<char>):
     BOOST_CHECK(R1L.ToString() == ArrayToString(R1Array, 32));
     BOOST_CHECK(R2L.ToString() == ArrayToString(R2Array, 32));
     BOOST_CHECK(ZeroL.ToString() == ArrayToString(ZeroArray, 32));
     BOOST_CHECK(OneL.ToString() == ArrayToString(OneArray, 32));
     BOOST_CHECK(MaxL.ToString() == ArrayToString(MaxArray, 32));
     BOOST_CHECK(OneL.ToString() != ArrayToString(ZeroArray, 32));
 
     // == and !=
     BOOST_CHECK(R1L != R2L);
     BOOST_CHECK(ZeroL != OneL);
     BOOST_CHECK(OneL != ZeroL);
     BOOST_CHECK(MaxL != ZeroL);
     BOOST_CHECK(~MaxL == ZeroL);
     BOOST_CHECK(((R1L ^ R2L) ^ R1L) == R2L);
 
     uint64_t Tmp64 = 0xc4dab720d9c7acaaULL;
     for (unsigned int i = 0; i < 256; ++i) {
         BOOST_CHECK(ZeroL != (OneL << i));
         BOOST_CHECK((OneL << i) != ZeroL);
         BOOST_CHECK(R1L != (R1L ^ (OneL << i)));
         BOOST_CHECK(((arith_uint256(Tmp64) ^ (OneL << i)) != Tmp64));
     }
     BOOST_CHECK(ZeroL == (OneL << 256));
 
     // String Constructor and Copy Constructor
     BOOST_CHECK(arith_uint256("0x" + R1L.ToString()) == R1L);
     BOOST_CHECK(arith_uint256("0x" + R2L.ToString()) == R2L);
     BOOST_CHECK(arith_uint256("0x" + ZeroL.ToString()) == ZeroL);
     BOOST_CHECK(arith_uint256("0x" + OneL.ToString()) == OneL);
     BOOST_CHECK(arith_uint256("0x" + MaxL.ToString()) == MaxL);
     BOOST_CHECK(arith_uint256(R1L.ToString()) == R1L);
     BOOST_CHECK(arith_uint256("   0x" + R1L.ToString() + "   ") == R1L);
     BOOST_CHECK(arith_uint256("") == ZeroL);
     BOOST_CHECK(R1L == arith_uint256(R1ArrayHex));
     BOOST_CHECK(arith_uint256(R1L) == R1L);
     BOOST_CHECK((arith_uint256(R1L ^ R2L) ^ R2L) == R1L);
     BOOST_CHECK(arith_uint256(ZeroL) == ZeroL);
     BOOST_CHECK(arith_uint256(OneL) == OneL);
 
     // uint64_t constructor
     BOOST_CHECK((R1L & arith_uint256("0xffffffffffffffff")) ==
                 arith_uint256(R1LLow64));
     BOOST_CHECK(ZeroL == arith_uint256(0));
     BOOST_CHECK(OneL == arith_uint256(1));
     BOOST_CHECK(arith_uint256("0xffffffffffffffff") ==
                 arith_uint256(0xffffffffffffffffULL));
 
     // Assignment (from base_uint)
     arith_uint256 tmpL = ~ZeroL;
     BOOST_CHECK(tmpL == ~ZeroL);
     tmpL = ~OneL;
     BOOST_CHECK(tmpL == ~OneL);
     tmpL = ~R1L;
     BOOST_CHECK(tmpL == ~R1L);
     tmpL = ~R2L;
     BOOST_CHECK(tmpL == ~R2L);
     tmpL = ~MaxL;
     BOOST_CHECK(tmpL == ~MaxL);
 }
 
-void shiftArrayRight(unsigned char *to, const unsigned char *from,
-                     unsigned int arrayLength, unsigned int bitsToShift) {
+void shiftArrayRight(uint8_t *to, const uint8_t *from, unsigned int arrayLength,
+                     unsigned int bitsToShift) {
     for (unsigned int T = 0; T < arrayLength; ++T) {
         unsigned int F = (T + bitsToShift / 8);
         if (F < arrayLength)
             to[T] = from[F] >> (bitsToShift % 8);
         else
             to[T] = 0;
         if (F + 1 < arrayLength)
             to[T] |= from[(F + 1)] << (8 - bitsToShift % 8);
     }
 }
 
-void shiftArrayLeft(unsigned char *to, const unsigned char *from,
-                    unsigned int arrayLength, unsigned int bitsToShift) {
+void shiftArrayLeft(uint8_t *to, const uint8_t *from, unsigned int arrayLength,
+                    unsigned int bitsToShift) {
     for (unsigned int T = 0; T < arrayLength; ++T) {
         if (T >= bitsToShift / 8) {
             unsigned int F = T - bitsToShift / 8;
             to[T] = from[F] << (bitsToShift % 8);
             if (T >= bitsToShift / 8 + 1)
                 to[T] |= from[F - 1] >> (8 - bitsToShift % 8);
         } else {
             to[T] = 0;
         }
     }
 }
 
 BOOST_AUTO_TEST_CASE(shifts) { // "<<"  ">>"  "<<="  ">>="
-    unsigned char TmpArray[32];
+    uint8_t TmpArray[32];
     arith_uint256 TmpL;
     for (unsigned int i = 0; i < 256; ++i) {
         shiftArrayLeft(TmpArray, OneArray, 32, i);
-        BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(
+        BOOST_CHECK(arith_uint256V(std::vector<uint8_t>(
                         TmpArray, TmpArray + 32)) == (OneL << i));
         TmpL = OneL;
         TmpL <<= i;
         BOOST_CHECK(TmpL == (OneL << i));
         BOOST_CHECK((HalfL >> (255 - i)) == (OneL << i));
         TmpL = HalfL;
         TmpL >>= (255 - i);
         BOOST_CHECK(TmpL == (OneL << i));
 
         shiftArrayLeft(TmpArray, R1Array, 32, i);
-        BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(
+        BOOST_CHECK(arith_uint256V(std::vector<uint8_t>(
                         TmpArray, TmpArray + 32)) == (R1L << i));
         TmpL = R1L;
         TmpL <<= i;
         BOOST_CHECK(TmpL == (R1L << i));
 
         shiftArrayRight(TmpArray, R1Array, 32, i);
-        BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(
+        BOOST_CHECK(arith_uint256V(std::vector<uint8_t>(
                         TmpArray, TmpArray + 32)) == (R1L >> i));
         TmpL = R1L;
         TmpL >>= i;
         BOOST_CHECK(TmpL == (R1L >> i));
 
         shiftArrayLeft(TmpArray, MaxArray, 32, i);
-        BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(
+        BOOST_CHECK(arith_uint256V(std::vector<uint8_t>(
                         TmpArray, TmpArray + 32)) == (MaxL << i));
         TmpL = MaxL;
         TmpL <<= i;
         BOOST_CHECK(TmpL == (MaxL << i));
 
         shiftArrayRight(TmpArray, MaxArray, 32, i);
-        BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(
+        BOOST_CHECK(arith_uint256V(std::vector<uint8_t>(
                         TmpArray, TmpArray + 32)) == (MaxL >> i));
         TmpL = MaxL;
         TmpL >>= i;
         BOOST_CHECK(TmpL == (MaxL >> i));
     }
     arith_uint256 c1L = arith_uint256(0x0123456789abcdefULL);
     arith_uint256 c2L = c1L << 128;
     for (unsigned int i = 0; i < 128; ++i) {
         BOOST_CHECK((c1L << i) == (c2L >> (128 - i)));
     }
     for (unsigned int i = 128; i < 256; ++i) {
         BOOST_CHECK((c1L << i) == (c2L << (i - 128)));
     }
 }
 
 BOOST_AUTO_TEST_CASE(unaryOperators) // !    ~    -
 {
     BOOST_CHECK(!ZeroL);
     BOOST_CHECK(!(!OneL));
     for (unsigned int i = 0; i < 256; ++i)
         BOOST_CHECK(!(!(OneL << i)));
     BOOST_CHECK(!(!R1L));
     BOOST_CHECK(!(!MaxL));
 
     BOOST_CHECK(~ZeroL == MaxL);
 
-    unsigned char TmpArray[32];
+    uint8_t TmpArray[32];
     for (unsigned int i = 0; i < 32; ++i) {
         TmpArray[i] = ~R1Array[i];
     }
-    BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(
-                    TmpArray, TmpArray + 32)) == (~R1L));
+    BOOST_CHECK(arith_uint256V(std::vector<uint8_t>(TmpArray, TmpArray + 32)) ==
+                (~R1L));
 
     BOOST_CHECK(-ZeroL == ZeroL);
     BOOST_CHECK(-R1L == (~R1L) + 1);
     for (unsigned int i = 0; i < 256; ++i)
         BOOST_CHECK(-(OneL << i) == (MaxL << i));
 }
 
 // Check if doing _A_ _OP_ _B_ results in the same as applying _OP_ onto each
 // element of Aarray and Barray, and then converting the result into a
 // arith_uint256.
 #define CHECKBITWISEOPERATOR(_A_, _B_, _OP_)                                   \
     for (unsigned int i = 0; i < 32; ++i) {                                    \
         TmpArray[i] = _A_##Array[i] _OP_ _B_##Array[i];                        \
     }                                                                          \
-    BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(                     \
+    BOOST_CHECK(arith_uint256V(std::vector<uint8_t>(                           \
                     TmpArray, TmpArray + 32)) == (_A_##L _OP_ _B_##L));
 
 #define CHECKASSIGNMENTOPERATOR(_A_, _B_, _OP_)                                \
     TmpL = _A_##L;                                                             \
     TmpL _OP_## = _B_##L;                                                      \
     BOOST_CHECK(TmpL == (_A_##L _OP_ _B_##L));
 
 BOOST_AUTO_TEST_CASE(bitwiseOperators) {
-    unsigned char TmpArray[32];
+    uint8_t TmpArray[32];
 
     CHECKBITWISEOPERATOR(R1, R2, |)
     CHECKBITWISEOPERATOR(R1, R2, ^)
     CHECKBITWISEOPERATOR(R1, R2, &)
     CHECKBITWISEOPERATOR(R1, Zero, |)
     CHECKBITWISEOPERATOR(R1, Zero, ^)
     CHECKBITWISEOPERATOR(R1, Zero, &)
     CHECKBITWISEOPERATOR(R1, Max, |)
     CHECKBITWISEOPERATOR(R1, Max, ^)
     CHECKBITWISEOPERATOR(R1, Max, &)
     CHECKBITWISEOPERATOR(Zero, R1, |)
     CHECKBITWISEOPERATOR(Zero, R1, ^)
     CHECKBITWISEOPERATOR(Zero, R1, &)
     CHECKBITWISEOPERATOR(Max, R1, |)
     CHECKBITWISEOPERATOR(Max, R1, ^)
     CHECKBITWISEOPERATOR(Max, R1, &)
 
     arith_uint256 TmpL;
     CHECKASSIGNMENTOPERATOR(R1, R2, |)
     CHECKASSIGNMENTOPERATOR(R1, R2, ^)
     CHECKASSIGNMENTOPERATOR(R1, R2, &)
     CHECKASSIGNMENTOPERATOR(R1, Zero, |)
     CHECKASSIGNMENTOPERATOR(R1, Zero, ^)
     CHECKASSIGNMENTOPERATOR(R1, Zero, &)
     CHECKASSIGNMENTOPERATOR(R1, Max, |)
     CHECKASSIGNMENTOPERATOR(R1, Max, ^)
     CHECKASSIGNMENTOPERATOR(R1, Max, &)
     CHECKASSIGNMENTOPERATOR(Zero, R1, |)
     CHECKASSIGNMENTOPERATOR(Zero, R1, ^)
     CHECKASSIGNMENTOPERATOR(Zero, R1, &)
     CHECKASSIGNMENTOPERATOR(Max, R1, |)
     CHECKASSIGNMENTOPERATOR(Max, R1, ^)
     CHECKASSIGNMENTOPERATOR(Max, R1, &)
 
     uint64_t Tmp64 = 0xe1db685c9a0b47a2ULL;
     TmpL = R1L;
     TmpL |= Tmp64;
     BOOST_CHECK(TmpL == (R1L | arith_uint256(Tmp64)));
     TmpL = R1L;
     TmpL |= 0;
     BOOST_CHECK(TmpL == R1L);
     TmpL ^= 0;
     BOOST_CHECK(TmpL == R1L);
     TmpL ^= Tmp64;
     BOOST_CHECK(TmpL == (R1L ^ arith_uint256(Tmp64)));
 }
 
 BOOST_AUTO_TEST_CASE(comparison) // <= >= < >
 {
     arith_uint256 TmpL;
     for (unsigned int i = 0; i < 256; ++i) {
         TmpL = OneL << i;
         BOOST_CHECK(TmpL >= ZeroL && TmpL > ZeroL && ZeroL < TmpL &&
                     ZeroL <= TmpL);
         BOOST_CHECK(TmpL >= 0 && TmpL > 0 && 0 < TmpL && 0 <= TmpL);
         TmpL |= R1L;
         BOOST_CHECK(TmpL >= R1L);
         BOOST_CHECK((TmpL == R1L) != (TmpL > R1L));
         BOOST_CHECK((TmpL == R1L) || !(TmpL <= R1L));
         BOOST_CHECK(R1L <= TmpL);
         BOOST_CHECK((R1L == TmpL) != (R1L < TmpL));
         BOOST_CHECK((TmpL == R1L) || !(R1L >= TmpL));
         BOOST_CHECK(!(TmpL < R1L));
         BOOST_CHECK(!(R1L > TmpL));
     }
 }
 
 BOOST_AUTO_TEST_CASE(plusMinus) {
     arith_uint256 TmpL = 0;
     BOOST_CHECK(R1L + R2L == arith_uint256(R1LplusR2L));
     TmpL += R1L;
     BOOST_CHECK(TmpL == R1L);
     TmpL += R2L;
     BOOST_CHECK(TmpL == R1L + R2L);
     BOOST_CHECK(OneL + MaxL == ZeroL);
     BOOST_CHECK(MaxL + OneL == ZeroL);
     for (unsigned int i = 1; i < 256; ++i) {
         BOOST_CHECK((MaxL >> i) + OneL == (HalfL >> (i - 1)));
         BOOST_CHECK(OneL + (MaxL >> i) == (HalfL >> (i - 1)));
         TmpL = (MaxL >> i);
         TmpL += OneL;
         BOOST_CHECK(TmpL == (HalfL >> (i - 1)));
         TmpL = (MaxL >> i);
         TmpL += 1;
         BOOST_CHECK(TmpL == (HalfL >> (i - 1)));
         TmpL = (MaxL >> i);
         BOOST_CHECK(TmpL++ == (MaxL >> i));
         BOOST_CHECK(TmpL == (HalfL >> (i - 1)));
     }
     BOOST_CHECK(arith_uint256(0xbedc77e27940a7ULL) + 0xee8d836fce66fbULL ==
                 arith_uint256(0xbedc77e27940a7ULL + 0xee8d836fce66fbULL));
     TmpL = arith_uint256(0xbedc77e27940a7ULL);
     TmpL += 0xee8d836fce66fbULL;
     BOOST_CHECK(TmpL ==
                 arith_uint256(0xbedc77e27940a7ULL + 0xee8d836fce66fbULL));
     TmpL -= 0xee8d836fce66fbULL;
     BOOST_CHECK(TmpL == 0xbedc77e27940a7ULL);
     TmpL = R1L;
     BOOST_CHECK(++TmpL == R1L + 1);
 
     BOOST_CHECK(R1L - (-R2L) == R1L + R2L);
     BOOST_CHECK(R1L - (-OneL) == R1L + OneL);
     BOOST_CHECK(R1L - OneL == R1L + (-OneL));
     for (unsigned int i = 1; i < 256; ++i) {
         BOOST_CHECK((MaxL >> i) - (-OneL) == (HalfL >> (i - 1)));
         BOOST_CHECK((HalfL >> (i - 1)) - OneL == (MaxL >> i));
         TmpL = (HalfL >> (i - 1));
         BOOST_CHECK(TmpL-- == (HalfL >> (i - 1)));
         BOOST_CHECK(TmpL == (MaxL >> i));
         TmpL = (HalfL >> (i - 1));
         BOOST_CHECK(--TmpL == (MaxL >> i));
     }
     TmpL = R1L;
     BOOST_CHECK(--TmpL == R1L - 1);
 }
 
 BOOST_AUTO_TEST_CASE(multiply) {
     BOOST_CHECK(
         (R1L * R1L).ToString() ==
         "62a38c0486f01e45879d7910a7761bf30d5237e9873f9bff3642a732c4d84f10");
     BOOST_CHECK(
         (R1L * R2L).ToString() ==
         "de37805e9986996cfba76ff6ba51c008df851987d9dd323f0e5de07760529c40");
     BOOST_CHECK((R1L * ZeroL) == ZeroL);
     BOOST_CHECK((R1L * OneL) == R1L);
     BOOST_CHECK((R1L * MaxL) == -R1L);
     BOOST_CHECK((R2L * R1L) == (R1L * R2L));
     BOOST_CHECK(
         (R2L * R2L).ToString() ==
         "ac8c010096767d3cae5005dec28bb2b45a1d85ab7996ccd3e102a650f74ff100");
     BOOST_CHECK((R2L * ZeroL) == ZeroL);
     BOOST_CHECK((R2L * OneL) == R2L);
     BOOST_CHECK((R2L * MaxL) == -R2L);
 
     BOOST_CHECK(MaxL * MaxL == OneL);
 
     BOOST_CHECK((R1L * 0) == 0);
     BOOST_CHECK((R1L * 1) == R1L);
     BOOST_CHECK(
         (R1L * 3).ToString() ==
         "7759b1c0ed14047f961ad09b20ff83687876a0181a367b813634046f91def7d4");
     BOOST_CHECK(
         (R2L * 0x87654321UL).ToString() ==
         "23f7816e30c4ae2017257b7a0fa64d60402f5234d46e746b61c960d09a26d070");
 }
 
 BOOST_AUTO_TEST_CASE(divide) {
     arith_uint256 D1L("AD7133AC1977FA2B7");
     arith_uint256 D2L("ECD751716");
     BOOST_CHECK(
         (R1L / D1L).ToString() ==
         "00000000000000000b8ac01106981635d9ed112290f8895545a7654dde28fb3a");
     BOOST_CHECK(
         (R1L / D2L).ToString() ==
         "000000000873ce8efec5b67150bad3aa8c5fcb70e947586153bf2cec7c37c57a");
     BOOST_CHECK(R1L / OneL == R1L);
     BOOST_CHECK(R1L / MaxL == ZeroL);
     BOOST_CHECK(MaxL / R1L == 2);
     BOOST_CHECK_THROW(R1L / ZeroL, uint_error);
     BOOST_CHECK(
         (R2L / D1L).ToString() ==
         "000000000000000013e1665895a1cc981de6d93670105a6b3ec3b73141b3a3c5");
     BOOST_CHECK(
         (R2L / D2L).ToString() ==
         "000000000e8f0abe753bb0afe2e9437ee85d280be60882cf0bd1aaf7fa3cc2c4");
     BOOST_CHECK(R2L / OneL == R2L);
     BOOST_CHECK(R2L / MaxL == ZeroL);
     BOOST_CHECK(MaxL / R2L == 1);
     BOOST_CHECK_THROW(R2L / ZeroL, uint_error);
 }
 
 bool almostEqual(double d1, double d2) {
     return fabs(d1 - d2) <=
            4 * fabs(d1) * std::numeric_limits<double>::epsilon();
 }
 
 BOOST_AUTO_TEST_CASE(methods) // GetHex SetHex size() GetLow64 GetSerializeSize,
                               // Serialize, Unserialize
 {
     BOOST_CHECK(R1L.GetHex() == R1L.ToString());
     BOOST_CHECK(R2L.GetHex() == R2L.ToString());
     BOOST_CHECK(OneL.GetHex() == OneL.ToString());
     BOOST_CHECK(MaxL.GetHex() == MaxL.ToString());
     arith_uint256 TmpL(R1L);
     BOOST_CHECK(TmpL == R1L);
     TmpL.SetHex(R2L.ToString());
     BOOST_CHECK(TmpL == R2L);
     TmpL.SetHex(ZeroL.ToString());
     BOOST_CHECK(TmpL == 0);
     TmpL.SetHex(HalfL.ToString());
     BOOST_CHECK(TmpL == HalfL);
 
     TmpL.SetHex(R1L.ToString());
     BOOST_CHECK(R1L.size() == 32);
     BOOST_CHECK(R2L.size() == 32);
     BOOST_CHECK(ZeroL.size() == 32);
     BOOST_CHECK(MaxL.size() == 32);
     BOOST_CHECK(R1L.GetLow64() == R1LLow64);
     BOOST_CHECK(HalfL.GetLow64() == 0x0000000000000000ULL);
     BOOST_CHECK(OneL.GetLow64() == 0x0000000000000001ULL);
 
     for (unsigned int i = 0; i < 255; ++i) {
         BOOST_CHECK((OneL << i).getdouble() == ldexp(1.0, i));
     }
     BOOST_CHECK(ZeroL.getdouble() == 0.0);
     for (int i = 256; i > 53; --i)
         BOOST_CHECK(
             almostEqual((R1L >> (256 - i)).getdouble(), ldexp(R1Ldouble, i)));
     uint64_t R1L64part = (R1L >> 192).GetLow64();
     for (int i = 53; i > 0;
          --i) // doubles can store all integers in {0,...,2^54-1} exactly
     {
         BOOST_CHECK((R1L >> (256 - i)).getdouble() ==
                     (double)(R1L64part >> (64 - i)));
     }
 }
 
 BOOST_AUTO_TEST_CASE(bignum_SetCompact) {
     arith_uint256 num;
     bool fNegative;
     bool fOverflow;
     num.SetCompact(0, &fNegative, &fOverflow);
     BOOST_CHECK_EQUAL(
         num.GetHex(),
         "0000000000000000000000000000000000000000000000000000000000000000");
     BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
     BOOST_CHECK_EQUAL(fNegative, false);
     BOOST_CHECK_EQUAL(fOverflow, false);
 
     num.SetCompact(0x00123456, &fNegative, &fOverflow);
     BOOST_CHECK_EQUAL(
         num.GetHex(),
         "0000000000000000000000000000000000000000000000000000000000000000");
     BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
     BOOST_CHECK_EQUAL(fNegative, false);
     BOOST_CHECK_EQUAL(fOverflow, false);
 
     num.SetCompact(0x01003456, &fNegative, &fOverflow);
     BOOST_CHECK_EQUAL(
         num.GetHex(),
         "0000000000000000000000000000000000000000000000000000000000000000");
     BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
     BOOST_CHECK_EQUAL(fNegative, false);
     BOOST_CHECK_EQUAL(fOverflow, false);
 
     num.SetCompact(0x02000056, &fNegative, &fOverflow);
     BOOST_CHECK_EQUAL(
         num.GetHex(),
         "0000000000000000000000000000000000000000000000000000000000000000");
     BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
     BOOST_CHECK_EQUAL(fNegative, false);
     BOOST_CHECK_EQUAL(fOverflow, false);
 
     num.SetCompact(0x03000000, &fNegative, &fOverflow);
     BOOST_CHECK_EQUAL(
         num.GetHex(),
         "0000000000000000000000000000000000000000000000000000000000000000");
     BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
     BOOST_CHECK_EQUAL(fNegative, false);
     BOOST_CHECK_EQUAL(fOverflow, false);
 
     num.SetCompact(0x04000000, &fNegative, &fOverflow);
     BOOST_CHECK_EQUAL(
         num.GetHex(),
         "0000000000000000000000000000000000000000000000000000000000000000");
     BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
     BOOST_CHECK_EQUAL(fNegative, false);
     BOOST_CHECK_EQUAL(fOverflow, false);
 
     num.SetCompact(0x00923456, &fNegative, &fOverflow);
     BOOST_CHECK_EQUAL(
         num.GetHex(),
         "0000000000000000000000000000000000000000000000000000000000000000");
     BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
     BOOST_CHECK_EQUAL(fNegative, false);
     BOOST_CHECK_EQUAL(fOverflow, false);
 
     num.SetCompact(0x01803456, &fNegative, &fOverflow);
     BOOST_CHECK_EQUAL(
         num.GetHex(),
         "0000000000000000000000000000000000000000000000000000000000000000");
     BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
     BOOST_CHECK_EQUAL(fNegative, false);
     BOOST_CHECK_EQUAL(fOverflow, false);
 
     num.SetCompact(0x02800056, &fNegative, &fOverflow);
     BOOST_CHECK_EQUAL(
         num.GetHex(),
         "0000000000000000000000000000000000000000000000000000000000000000");
     BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
     BOOST_CHECK_EQUAL(fNegative, false);
     BOOST_CHECK_EQUAL(fOverflow, false);
 
     num.SetCompact(0x03800000, &fNegative, &fOverflow);
     BOOST_CHECK_EQUAL(
         num.GetHex(),
         "0000000000000000000000000000000000000000000000000000000000000000");
     BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
     BOOST_CHECK_EQUAL(fNegative, false);
     BOOST_CHECK_EQUAL(fOverflow, false);
 
     num.SetCompact(0x04800000, &fNegative, &fOverflow);
     BOOST_CHECK_EQUAL(
         num.GetHex(),
         "0000000000000000000000000000000000000000000000000000000000000000");
     BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
     BOOST_CHECK_EQUAL(fNegative, false);
     BOOST_CHECK_EQUAL(fOverflow, false);
 
     num.SetCompact(0x01123456, &fNegative, &fOverflow);
     BOOST_CHECK_EQUAL(
         num.GetHex(),
         "0000000000000000000000000000000000000000000000000000000000000012");
     BOOST_CHECK_EQUAL(num.GetCompact(), 0x01120000U);
     BOOST_CHECK_EQUAL(fNegative, false);
     BOOST_CHECK_EQUAL(fOverflow, false);
 
     // Make sure that we don't generate compacts with the 0x00800000 bit set
     num = 0x80;
     BOOST_CHECK_EQUAL(num.GetCompact(), 0x02008000U);
 
     num.SetCompact(0x01fedcba, &fNegative, &fOverflow);
     BOOST_CHECK_EQUAL(
         num.GetHex(),
         "000000000000000000000000000000000000000000000000000000000000007e");
     BOOST_CHECK_EQUAL(num.GetCompact(true), 0x01fe0000U);
     BOOST_CHECK_EQUAL(fNegative, true);
     BOOST_CHECK_EQUAL(fOverflow, false);
 
     num.SetCompact(0x02123456, &fNegative, &fOverflow);
     BOOST_CHECK_EQUAL(
         num.GetHex(),
         "0000000000000000000000000000000000000000000000000000000000001234");
     BOOST_CHECK_EQUAL(num.GetCompact(), 0x02123400U);
     BOOST_CHECK_EQUAL(fNegative, false);
     BOOST_CHECK_EQUAL(fOverflow, false);
 
     num.SetCompact(0x03123456, &fNegative, &fOverflow);
     BOOST_CHECK_EQUAL(
         num.GetHex(),
         "0000000000000000000000000000000000000000000000000000000000123456");
     BOOST_CHECK_EQUAL(num.GetCompact(), 0x03123456U);
     BOOST_CHECK_EQUAL(fNegative, false);
     BOOST_CHECK_EQUAL(fOverflow, false);
 
     num.SetCompact(0x04123456, &fNegative, &fOverflow);
     BOOST_CHECK_EQUAL(
         num.GetHex(),
         "0000000000000000000000000000000000000000000000000000000012345600");
     BOOST_CHECK_EQUAL(num.GetCompact(), 0x04123456U);
     BOOST_CHECK_EQUAL(fNegative, false);
     BOOST_CHECK_EQUAL(fOverflow, false);
 
     num.SetCompact(0x04923456, &fNegative, &fOverflow);
     BOOST_CHECK_EQUAL(
         num.GetHex(),
         "0000000000000000000000000000000000000000000000000000000012345600");
     BOOST_CHECK_EQUAL(num.GetCompact(true), 0x04923456U);
     BOOST_CHECK_EQUAL(fNegative, true);
     BOOST_CHECK_EQUAL(fOverflow, false);
 
     num.SetCompact(0x05009234, &fNegative, &fOverflow);
     BOOST_CHECK_EQUAL(
         num.GetHex(),
         "0000000000000000000000000000000000000000000000000000000092340000");
     BOOST_CHECK_EQUAL(num.GetCompact(), 0x05009234U);
     BOOST_CHECK_EQUAL(fNegative, false);
     BOOST_CHECK_EQUAL(fOverflow, false);
 
     num.SetCompact(0x20123456, &fNegative, &fOverflow);
     BOOST_CHECK_EQUAL(
         num.GetHex(),
         "1234560000000000000000000000000000000000000000000000000000000000");
     BOOST_CHECK_EQUAL(num.GetCompact(), 0x20123456U);
     BOOST_CHECK_EQUAL(fNegative, false);
     BOOST_CHECK_EQUAL(fOverflow, false);
 
     num.SetCompact(0xff123456, &fNegative, &fOverflow);
     BOOST_CHECK_EQUAL(fNegative, false);
     BOOST_CHECK_EQUAL(fOverflow, true);
 }
 
 BOOST_AUTO_TEST_CASE(
     getmaxcoverage) // some more tests just to get 100% coverage
 {
     // ~R1L give a base_uint<256>
     BOOST_CHECK((~~R1L >> 10) == (R1L >> 10));
     BOOST_CHECK((~~R1L << 10) == (R1L << 10));
     BOOST_CHECK(!(~~R1L < R1L));
     BOOST_CHECK(~~R1L <= R1L);
     BOOST_CHECK(!(~~R1L > R1L));
     BOOST_CHECK(~~R1L >= R1L);
     BOOST_CHECK(!(R1L < ~~R1L));
     BOOST_CHECK(R1L <= ~~R1L);
     BOOST_CHECK(!(R1L > ~~R1L));
     BOOST_CHECK(R1L >= ~~R1L);
 
     BOOST_CHECK(~~R1L + R2L == R1L + ~~R2L);
     BOOST_CHECK(~~R1L - R2L == R1L - ~~R2L);
     BOOST_CHECK(~R1L != R1L);
     BOOST_CHECK(R1L != ~R1L);
-    unsigned char TmpArray[32];
+    uint8_t TmpArray[32];
     CHECKBITWISEOPERATOR(~R1, R2, |)
     CHECKBITWISEOPERATOR(~R1, R2, ^)
     CHECKBITWISEOPERATOR(~R1, R2, &)
     CHECKBITWISEOPERATOR(R1, ~R2, |)
     CHECKBITWISEOPERATOR(R1, ~R2, ^)
     CHECKBITWISEOPERATOR(R1, ~R2, &)
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp
index 149ada6e7..15855668c 100644
--- a/src/test/base58_tests.cpp
+++ b/src/test/base58_tests.cpp
@@ -1,283 +1,283 @@
 // Copyright (c) 2011-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.
 
 #include "base58.h"
 
 #include "data/base58_encode_decode.json.h"
 #include "data/base58_keys_invalid.json.h"
 #include "data/base58_keys_valid.json.h"
 
 #include "key.h"
 #include "script/script.h"
 #include "test/test_bitcoin.h"
 #include "uint256.h"
 #include "util.h"
 #include "utilstrencodings.h"
 
 #include <boost/test/unit_test.hpp>
 
 #include <univalue.h>
 
 extern UniValue read_json(const std::string &jsondata);
 
 BOOST_FIXTURE_TEST_SUITE(base58_tests, BasicTestingSetup)
 
 // Goal: test low-level base58 encoding functionality
 BOOST_AUTO_TEST_CASE(base58_EncodeBase58) {
     UniValue tests =
         read_json(std::string(json_tests::base58_encode_decode,
                               json_tests::base58_encode_decode +
                                   sizeof(json_tests::base58_encode_decode)));
     for (unsigned int idx = 0; idx < tests.size(); idx++) {
         UniValue test = tests[idx];
         std::string strTest = test.write();
         // Allow for extra stuff (useful for comments)
         if (test.size() < 2) {
             BOOST_ERROR("Bad test: " << strTest);
             continue;
         }
-        std::vector<unsigned char> sourcedata = ParseHex(test[0].get_str());
+        std::vector<uint8_t> sourcedata = ParseHex(test[0].get_str());
         std::string base58string = test[1].get_str();
         BOOST_CHECK_MESSAGE(
             EncodeBase58(sourcedata.data(),
                          sourcedata.data() + sourcedata.size()) == base58string,
             strTest);
     }
 }
 
 // Goal: test low-level base58 decoding functionality
 BOOST_AUTO_TEST_CASE(base58_DecodeBase58) {
     UniValue tests =
         read_json(std::string(json_tests::base58_encode_decode,
                               json_tests::base58_encode_decode +
                                   sizeof(json_tests::base58_encode_decode)));
-    std::vector<unsigned char> result;
+    std::vector<uint8_t> result;
 
     for (unsigned int idx = 0; idx < tests.size(); idx++) {
         UniValue test = tests[idx];
         std::string strTest = test.write();
         // Allow for extra stuff (useful for comments)
         if (test.size() < 2) {
             BOOST_ERROR("Bad test: " << strTest);
             continue;
         }
-        std::vector<unsigned char> expected = ParseHex(test[0].get_str());
+        std::vector<uint8_t> expected = ParseHex(test[0].get_str());
         std::string base58string = test[1].get_str();
         BOOST_CHECK_MESSAGE(DecodeBase58(base58string, result), strTest);
         BOOST_CHECK_MESSAGE(
             result.size() == expected.size() &&
                 std::equal(result.begin(), result.end(), expected.begin()),
             strTest);
     }
 
     BOOST_CHECK(!DecodeBase58("invalid", result));
 
     // check that DecodeBase58 skips whitespace, but still fails with unexpected
     // non-whitespace at the end.
     BOOST_CHECK(!DecodeBase58(" \t\n\v\f\r skip \r\f\v\n\t a", result));
     BOOST_CHECK(DecodeBase58(" \t\n\v\f\r skip \r\f\v\n\t ", result));
-    std::vector<unsigned char> expected = ParseHex("971a55");
+    std::vector<uint8_t> expected = ParseHex("971a55");
     BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(),
                                   expected.begin(), expected.end());
 }
 
 // Visitor to check address type
 class TestAddrTypeVisitor : public boost::static_visitor<bool> {
 private:
     std::string exp_addrType;
 
 public:
     TestAddrTypeVisitor(const std::string &_exp_addrType)
         : exp_addrType(_exp_addrType) {}
     bool operator()(const CKeyID &id) const {
         return (exp_addrType == "pubkey");
     }
     bool operator()(const CScriptID &id) const {
         return (exp_addrType == "script");
     }
     bool operator()(const CNoDestination &no) const {
         return (exp_addrType == "none");
     }
 };
 
 // Visitor to check address payload
 class TestPayloadVisitor : public boost::static_visitor<bool> {
 private:
-    std::vector<unsigned char> exp_payload;
+    std::vector<uint8_t> exp_payload;
 
 public:
-    TestPayloadVisitor(std::vector<unsigned char> &_exp_payload)
+    TestPayloadVisitor(std::vector<uint8_t> &_exp_payload)
         : exp_payload(_exp_payload) {}
     bool operator()(const CKeyID &id) const {
         uint160 exp_key(exp_payload);
         return exp_key == id;
     }
     bool operator()(const CScriptID &id) const {
         uint160 exp_key(exp_payload);
         return exp_key == id;
     }
     bool operator()(const CNoDestination &no) const {
         return exp_payload.size() == 0;
     }
 };
 
 // Goal: check that parsed keys match test payload
 BOOST_AUTO_TEST_CASE(base58_keys_valid_parse) {
     UniValue tests = read_json(std::string(
         json_tests::base58_keys_valid,
         json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid)));
     CBitcoinSecret secret;
     CBitcoinAddress addr;
     SelectParams(CBaseChainParams::MAIN);
 
     for (unsigned int idx = 0; idx < tests.size(); idx++) {
         UniValue test = tests[idx];
         std::string strTest = test.write();
         // Allow for extra stuff (useful for comments)
         if (test.size() < 3) {
             BOOST_ERROR("Bad test: " << strTest);
             continue;
         }
         std::string exp_base58string = test[0].get_str();
-        std::vector<unsigned char> exp_payload = ParseHex(test[1].get_str());
+        std::vector<uint8_t> exp_payload = ParseHex(test[1].get_str());
         const UniValue &metadata = test[2].get_obj();
         bool isPrivkey = find_value(metadata, "isPrivkey").get_bool();
         bool isTestnet = find_value(metadata, "isTestnet").get_bool();
         if (isTestnet)
             SelectParams(CBaseChainParams::TESTNET);
         else
             SelectParams(CBaseChainParams::MAIN);
         if (isPrivkey) {
             bool isCompressed = find_value(metadata, "isCompressed").get_bool();
             // Must be valid private key
             // Note: CBitcoinSecret::SetString tests isValid, whereas
             // CBitcoinAddress does not!
             BOOST_CHECK_MESSAGE(secret.SetString(exp_base58string),
                                 "!SetString:" + strTest);
             BOOST_CHECK_MESSAGE(secret.IsValid(), "!IsValid:" + strTest);
             CKey privkey = secret.GetKey();
             BOOST_CHECK_MESSAGE(privkey.IsCompressed() == isCompressed,
                                 "compressed mismatch:" + strTest);
             BOOST_CHECK_MESSAGE(privkey.size() == exp_payload.size() &&
                                     std::equal(privkey.begin(), privkey.end(),
                                                exp_payload.begin()),
                                 "key mismatch:" + strTest);
 
             // Private key must be invalid public key
             addr.SetString(exp_base58string);
             BOOST_CHECK_MESSAGE(!addr.IsValid(),
                                 "IsValid privkey as pubkey:" + strTest);
         } else {
             std::string exp_addrType = find_value(metadata, "addrType")
                                            .get_str(); // "script" or "pubkey"
             // Must be valid public key
             BOOST_CHECK_MESSAGE(addr.SetString(exp_base58string),
                                 "SetString:" + strTest);
             BOOST_CHECK_MESSAGE(addr.IsValid(), "!IsValid:" + strTest);
             BOOST_CHECK_MESSAGE(addr.IsScript() == (exp_addrType == "script"),
                                 "isScript mismatch" + strTest);
             CTxDestination dest = addr.Get();
             BOOST_CHECK_MESSAGE(
                 boost::apply_visitor(TestAddrTypeVisitor(exp_addrType), dest),
                 "addrType mismatch" + strTest);
 
             // Public key must be invalid private key
             secret.SetString(exp_base58string);
             BOOST_CHECK_MESSAGE(!secret.IsValid(),
                                 "IsValid pubkey as privkey:" + strTest);
         }
     }
 }
 
 // Goal: check that generated keys match test vectors
 BOOST_AUTO_TEST_CASE(base58_keys_valid_gen) {
     UniValue tests = read_json(std::string(
         json_tests::base58_keys_valid,
         json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid)));
 
     for (unsigned int idx = 0; idx < tests.size(); idx++) {
         UniValue test = tests[idx];
         std::string strTest = test.write();
         // Allow for extra stuff (useful for comments)
         if (test.size() < 3) {
             BOOST_ERROR("Bad test: " << strTest);
             continue;
         }
         std::string exp_base58string = test[0].get_str();
-        std::vector<unsigned char> exp_payload = ParseHex(test[1].get_str());
+        std::vector<uint8_t> exp_payload = ParseHex(test[1].get_str());
         const UniValue &metadata = test[2].get_obj();
         bool isPrivkey = find_value(metadata, "isPrivkey").get_bool();
         bool isTestnet = find_value(metadata, "isTestnet").get_bool();
         if (isTestnet)
             SelectParams(CBaseChainParams::TESTNET);
         else
             SelectParams(CBaseChainParams::MAIN);
         if (isPrivkey) {
             bool isCompressed = find_value(metadata, "isCompressed").get_bool();
             CKey key;
             key.Set(exp_payload.begin(), exp_payload.end(), isCompressed);
             assert(key.IsValid());
             CBitcoinSecret secret;
             secret.SetKey(key);
             BOOST_CHECK_MESSAGE(secret.ToString() == exp_base58string,
                                 "result mismatch: " + strTest);
         } else {
             std::string exp_addrType =
                 find_value(metadata, "addrType").get_str();
             CTxDestination dest;
             if (exp_addrType == "pubkey") {
                 dest = CKeyID(uint160(exp_payload));
             } else if (exp_addrType == "script") {
                 dest = CScriptID(uint160(exp_payload));
             } else if (exp_addrType == "none") {
                 dest = CNoDestination();
             } else {
                 BOOST_ERROR("Bad addrtype: " << strTest);
                 continue;
             }
             CBitcoinAddress addrOut;
             BOOST_CHECK_MESSAGE(addrOut.Set(dest), "encode dest: " + strTest);
             BOOST_CHECK_MESSAGE(addrOut.ToString() == exp_base58string,
                                 "mismatch: " + strTest);
         }
     }
 
     // Visiting a CNoDestination must fail
     CBitcoinAddress dummyAddr;
     CTxDestination nodest = CNoDestination();
     BOOST_CHECK(!dummyAddr.Set(nodest));
 
     SelectParams(CBaseChainParams::MAIN);
 }
 
 // Goal: check that base58 parsing code is robust against a variety of corrupted
 // data
 BOOST_AUTO_TEST_CASE(base58_keys_invalid) {
     // Negative testcases
     UniValue tests =
         read_json(std::string(json_tests::base58_keys_invalid,
                               json_tests::base58_keys_invalid +
                                   sizeof(json_tests::base58_keys_invalid)));
     CBitcoinSecret secret;
     CBitcoinAddress addr;
 
     for (unsigned int idx = 0; idx < tests.size(); idx++) {
         UniValue test = tests[idx];
         std::string strTest = test.write();
         // Allow for extra stuff (useful for comments)
         if (test.size() < 1) {
             BOOST_ERROR("Bad test: " << strTest);
             continue;
         }
         std::string exp_base58string = test[0].get_str();
 
         // must be invalid as public and as private key
         addr.SetString(exp_base58string);
         BOOST_CHECK_MESSAGE(!addr.IsValid(), "IsValid pubkey:" + strTest);
         secret.SetString(exp_base58string);
         BOOST_CHECK_MESSAGE(!secret.IsValid(), "IsValid privkey:" + strTest);
     }
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp
index 1b307700d..f6319ac12 100644
--- a/src/test/bip32_tests.cpp
+++ b/src/test/bip32_tests.cpp
@@ -1,170 +1,170 @@
 // Copyright (c) 2013-2015 The Bitcoin Core developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #include <boost/test/unit_test.hpp>
 
 #include "base58.h"
 #include "key.h"
 #include "test/test_bitcoin.h"
 #include "uint256.h"
 #include "util.h"
 #include "utilstrencodings.h"
 
 #include <string>
 #include <vector>
 
 struct TestDerivation {
     std::string pub;
     std::string prv;
     unsigned int nChild;
 };
 
 struct TestVector {
     std::string strHexMaster;
     std::vector<TestDerivation> vDerive;
 
     TestVector(std::string strHexMasterIn) : strHexMaster(strHexMasterIn) {}
 
     TestVector &operator()(std::string pub, std::string prv,
                            unsigned int nChild) {
         vDerive.push_back(TestDerivation());
         TestDerivation &der = vDerive.back();
         der.pub = pub;
         der.prv = prv;
         der.nChild = nChild;
         return *this;
     }
 };
 
 TestVector test1 = TestVector("000102030405060708090a0b0c0d0e0f")(
     "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1R"
     "upje8YtGqsefD265TMg7usUDFdp6W1EGMcet8",
     "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWU"
     "tg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi",
     0x80000000)("xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LH"
                 "hwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw",
                 "xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1"
                 "rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7",
                 1)("xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFH"
                    "KkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ",
                    "xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSx"
                    "qu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs",
                    0x80000002)(
     "xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGT"
     "sxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5",
     "xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4"
     "ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM",
     2)("xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZL"
        "RQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV",
        "xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7"
        "RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334",
        1000000000)("xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNT"
                    "EcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy",
                    "xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8"
                    "kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76",
                    0);
 
 TestVector test2 = TestVector("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdba"
                               "b7b4b1aeaba8a5a29f9c999693908d8a8784817e7b787572"
                               "6f6c696663605d5a5754514e4b484542")(
     "xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6"
     "Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB",
     "xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFm"
     "M8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U",
     0)("xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfv"
        "rnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH",
        "xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJ"
        "D9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt",
        0xFFFFFFFF)("xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ"
                    "85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a",
                    "xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYE"
                    "eEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9",
                    1)("xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg"
                       "5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon",
                       "xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTR"
                       "XSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef",
                       0xFFFFFFFE)(
     "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5J"
     "aHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL",
     "xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyu"
     "oseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc",
     2)("xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsA"
        "pME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt",
        "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38"
        "EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j",
        0);
 
 void RunTest(const TestVector &test) {
-    std::vector<unsigned char> seed = ParseHex(test.strHexMaster);
+    std::vector<uint8_t> seed = ParseHex(test.strHexMaster);
     CExtKey key;
     CExtPubKey pubkey;
     key.SetMaster(&seed[0], seed.size());
     pubkey = key.Neuter();
     for (const TestDerivation &derive : test.vDerive) {
-        unsigned char data[74];
+        uint8_t data[74];
         key.Encode(data);
         pubkey.Encode(data);
 
         // Test private key
         CBitcoinExtKey b58key;
         b58key.SetKey(key);
         BOOST_CHECK(b58key.ToString() == derive.prv);
 
         CBitcoinExtKey b58keyDecodeCheck(derive.prv);
         CExtKey checkKey = b58keyDecodeCheck.GetKey();
         // ensure a base58 decoded key also matches
         assert(checkKey == key);
 
         // Test public key
         CBitcoinExtPubKey b58pubkey;
         b58pubkey.SetKey(pubkey);
         BOOST_CHECK(b58pubkey.ToString() == derive.pub);
 
         CBitcoinExtPubKey b58PubkeyDecodeCheck(derive.pub);
         CExtPubKey checkPubKey = b58PubkeyDecodeCheck.GetKey();
         // ensure a base58 decoded pubkey also matches
         assert(checkPubKey == pubkey);
 
         // Derive new keys
         CExtKey keyNew;
         BOOST_CHECK(key.Derive(keyNew, derive.nChild));
         CExtPubKey pubkeyNew = keyNew.Neuter();
         if (!(derive.nChild & 0x80000000)) {
             // Compare with public derivation
             CExtPubKey pubkeyNew2;
             BOOST_CHECK(pubkey.Derive(pubkeyNew2, derive.nChild));
             BOOST_CHECK(pubkeyNew == pubkeyNew2);
         }
         key = keyNew;
         pubkey = pubkeyNew;
 
         CDataStream ssPub(SER_DISK, CLIENT_VERSION);
         ssPub << pubkeyNew;
         BOOST_CHECK(ssPub.size() == 75);
 
         CDataStream ssPriv(SER_DISK, CLIENT_VERSION);
         ssPriv << keyNew;
         BOOST_CHECK(ssPriv.size() == 75);
 
         CExtPubKey pubCheck;
         CExtKey privCheck;
         ssPub >> pubCheck;
         ssPriv >> privCheck;
 
         BOOST_CHECK(pubCheck == pubkeyNew);
         BOOST_CHECK(privCheck == keyNew);
     }
 }
 
 BOOST_FIXTURE_TEST_SUITE(bip32_tests, BasicTestingSetup)
 
 BOOST_AUTO_TEST_CASE(bip32_test1) {
     RunTest(test1);
 }
 
 BOOST_AUTO_TEST_CASE(bip32_test2) {
     RunTest(test2);
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp
index 21ed0ce29..547153b62 100644
--- a/src/test/bloom_tests.cpp
+++ b/src/test/bloom_tests.cpp
@@ -1,1129 +1,1129 @@
 // Copyright (c) 2012-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.
 
 #include "bloom.h"
 
 #include "base58.h"
 #include "clientversion.h"
 #include "key.h"
 #include "merkleblock.h"
 #include "random.h"
 #include "serialize.h"
 #include "streams.h"
 #include "test/test_bitcoin.h"
 #include "uint256.h"
 #include "util.h"
 #include "utilstrencodings.h"
 
 #include <vector>
 
 #include <boost/test/unit_test.hpp>
 #include <boost/tuple/tuple.hpp>
 
 BOOST_FIXTURE_TEST_SUITE(bloom_tests, BasicTestingSetup)
 
 BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize) {
     CBloomFilter filter(3, 0.01, 0, BLOOM_UPDATE_ALL);
 
     filter.insert(ParseHex("99108ad8ed9bb6274d3980bab5a85c048f0950c8"));
     BOOST_CHECK_MESSAGE(
         filter.contains(ParseHex("99108ad8ed9bb6274d3980bab5a85c048f0950c8")),
         "Bloom filter doesn't contain just-inserted object!");
     // One bit different in first byte
     BOOST_CHECK_MESSAGE(
         !filter.contains(ParseHex("19108ad8ed9bb6274d3980bab5a85c048f0950c8")),
         "Bloom filter contains something it shouldn't!");
 
     filter.insert(ParseHex("b5a2c786d9ef4658287ced5914b37a1b4aa32eee"));
     BOOST_CHECK_MESSAGE(
         filter.contains(ParseHex("b5a2c786d9ef4658287ced5914b37a1b4aa32eee")),
         "Bloom filter doesn't contain just-inserted object (2)!");
 
     filter.insert(ParseHex("b9300670b4c5366e95b2699e8b18bc75e5f729c5"));
     BOOST_CHECK_MESSAGE(
         filter.contains(ParseHex("b9300670b4c5366e95b2699e8b18bc75e5f729c5")),
         "Bloom filter doesn't contain just-inserted object (3)!");
 
     CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
     stream << filter;
 
-    std::vector<unsigned char> vch = ParseHex("03614e9b050000000000000001");
+    std::vector<uint8_t> vch = ParseHex("03614e9b050000000000000001");
     std::vector<char> expected(vch.size());
 
     for (unsigned int i = 0; i < vch.size(); i++)
         expected[i] = (char)vch[i];
 
     BOOST_CHECK_EQUAL_COLLECTIONS(stream.begin(), stream.end(),
                                   expected.begin(), expected.end());
 
     BOOST_CHECK_MESSAGE(
         filter.contains(ParseHex("99108ad8ed9bb6274d3980bab5a85c048f0950c8")),
         "Bloom filter doesn't contain just-inserted object!");
     filter.clear();
     BOOST_CHECK_MESSAGE(
         !filter.contains(ParseHex("99108ad8ed9bb6274d3980bab5a85c048f0950c8")),
         "Bloom filter should be empty!");
 }
 
 BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize_with_tweak) {
     // Same test as bloom_create_insert_serialize, but we add a nTweak of 100
     CBloomFilter filter(3, 0.01, 2147483649UL, BLOOM_UPDATE_ALL);
 
     filter.insert(ParseHex("99108ad8ed9bb6274d3980bab5a85c048f0950c8"));
     BOOST_CHECK_MESSAGE(
         filter.contains(ParseHex("99108ad8ed9bb6274d3980bab5a85c048f0950c8")),
         "Bloom filter doesn't contain just-inserted object!");
     // One bit different in first byte
     BOOST_CHECK_MESSAGE(
         !filter.contains(ParseHex("19108ad8ed9bb6274d3980bab5a85c048f0950c8")),
         "Bloom filter contains something it shouldn't!");
 
     filter.insert(ParseHex("b5a2c786d9ef4658287ced5914b37a1b4aa32eee"));
     BOOST_CHECK_MESSAGE(
         filter.contains(ParseHex("b5a2c786d9ef4658287ced5914b37a1b4aa32eee")),
         "Bloom filter doesn't contain just-inserted object (2)!");
 
     filter.insert(ParseHex("b9300670b4c5366e95b2699e8b18bc75e5f729c5"));
     BOOST_CHECK_MESSAGE(
         filter.contains(ParseHex("b9300670b4c5366e95b2699e8b18bc75e5f729c5")),
         "Bloom filter doesn't contain just-inserted object (3)!");
 
     CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
     stream << filter;
 
-    std::vector<unsigned char> vch = ParseHex("03ce4299050000000100008001");
+    std::vector<uint8_t> vch = ParseHex("03ce4299050000000100008001");
     std::vector<char> expected(vch.size());
 
     for (unsigned int i = 0; i < vch.size(); i++)
         expected[i] = (char)vch[i];
 
     BOOST_CHECK_EQUAL_COLLECTIONS(stream.begin(), stream.end(),
                                   expected.begin(), expected.end());
 }
 
 BOOST_AUTO_TEST_CASE(bloom_create_insert_key) {
     std::string strSecret =
         std::string("5Kg1gnAjaLfKiwhhPpGS3QfRg2m6awQvaj98JCZBZQ5SuS2F15C");
     CBitcoinSecret vchSecret;
     BOOST_CHECK(vchSecret.SetString(strSecret));
 
     CKey key = vchSecret.GetKey();
     CPubKey pubkey = key.GetPubKey();
-    std::vector<unsigned char> vchPubKey(pubkey.begin(), pubkey.end());
+    std::vector<uint8_t> vchPubKey(pubkey.begin(), pubkey.end());
 
     CBloomFilter filter(2, 0.001, 0, BLOOM_UPDATE_ALL);
     filter.insert(vchPubKey);
     uint160 hash = pubkey.GetID();
-    filter.insert(std::vector<unsigned char>(hash.begin(), hash.end()));
+    filter.insert(std::vector<uint8_t>(hash.begin(), hash.end()));
 
     CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
     stream << filter;
 
-    std::vector<unsigned char> vch = ParseHex("038fc16b080000000000000001");
+    std::vector<uint8_t> vch = ParseHex("038fc16b080000000000000001");
     std::vector<char> expected(vch.size());
 
     for (unsigned int i = 0; i < vch.size(); i++)
         expected[i] = (char)vch[i];
 
     BOOST_CHECK_EQUAL_COLLECTIONS(stream.begin(), stream.end(),
                                   expected.begin(), expected.end());
 }
 
 BOOST_AUTO_TEST_CASE(bloom_match) {
     // Random real transaction
     // (b4749f017444b051c44dfd2720e88f314ff94f3dd6d56d40ef65854fcd7fff6b)
     CDataStream stream(
         ParseHex("01000000010b26e9b7735eb6aabdf358bab62f9816a21ba9ebdb719d5299e"
                  "88607d722c190000000008b4830450220070aca44506c5cef3a16ed519d7c"
                  "3c39f8aab192c4e1c90d065f37b8a4af6141022100a8e160b856c2d43d27d"
                  "8fba71e5aef6405b8643ac4cb7cb3c462aced7f14711a0141046d11fee51b"
                  "0e60666d5049a9101a72741df480b96ee26488a4d3466b95c9a40ac5eeef8"
                  "7e10a5cd336c19a84565f80fa6c547957b7700ff4dfbdefe76036c339ffff"
                  "ffff021bff3d11000000001976a91404943fdd508053c75000106d3bc6e27"
                  "54dbcff1988ac2f15de00000000001976a914a266436d2965547608b9e15d"
                  "9032a7b9d64fa43188ac00000000"),
         SER_DISK, CLIENT_VERSION);
     CTransaction tx(deserialize, stream);
 
     // and one which spends it
     // (e2769b09e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436)
-    unsigned char ch[] = {
+    uint8_t ch[] = {
         0x01, 0x00, 0x00, 0x00, 0x01, 0x6b, 0xff, 0x7f, 0xcd, 0x4f, 0x85, 0x65,
         0xef, 0x40, 0x6d, 0xd5, 0xd6, 0x3d, 0x4f, 0xf9, 0x4f, 0x31, 0x8f, 0xe8,
         0x20, 0x27, 0xfd, 0x4d, 0xc4, 0x51, 0xb0, 0x44, 0x74, 0x01, 0x9f, 0x74,
         0xb4, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x49, 0x30, 0x46, 0x02, 0x21, 0x00,
         0xda, 0x0d, 0xc6, 0xae, 0xce, 0xfe, 0x1e, 0x06, 0xef, 0xdf, 0x05, 0x77,
         0x37, 0x57, 0xde, 0xb1, 0x68, 0x82, 0x09, 0x30, 0xe3, 0xb0, 0xd0, 0x3f,
         0x46, 0xf5, 0xfc, 0xf1, 0x50, 0xbf, 0x99, 0x0c, 0x02, 0x21, 0x00, 0xd2,
         0x5b, 0x5c, 0x87, 0x04, 0x00, 0x76, 0xe4, 0xf2, 0x53, 0xf8, 0x26, 0x2e,
         0x76, 0x3e, 0x2d, 0xd5, 0x1e, 0x7f, 0xf0, 0xbe, 0x15, 0x77, 0x27, 0xc4,
         0xbc, 0x42, 0x80, 0x7f, 0x17, 0xbd, 0x39, 0x01, 0x41, 0x04, 0xe6, 0xc2,
         0x6e, 0xf6, 0x7d, 0xc6, 0x10, 0xd2, 0xcd, 0x19, 0x24, 0x84, 0x78, 0x9a,
         0x6c, 0xf9, 0xae, 0xa9, 0x93, 0x0b, 0x94, 0x4b, 0x7e, 0x2d, 0xb5, 0x34,
         0x2b, 0x9d, 0x9e, 0x5b, 0x9f, 0xf7, 0x9a, 0xff, 0x9a, 0x2e, 0xe1, 0x97,
         0x8d, 0xd7, 0xfd, 0x01, 0xdf, 0xc5, 0x22, 0xee, 0x02, 0x28, 0x3d, 0x3b,
         0x06, 0xa9, 0xd0, 0x3a, 0xcf, 0x80, 0x96, 0x96, 0x8d, 0x7d, 0xbb, 0x0f,
         0x91, 0x78, 0xff, 0xff, 0xff, 0xff, 0x02, 0x8b, 0xa7, 0x94, 0x0e, 0x00,
         0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14, 0xba, 0xde, 0xec, 0xfd, 0xef,
         0x05, 0x07, 0x24, 0x7f, 0xc8, 0xf7, 0x42, 0x41, 0xd7, 0x3b, 0xc0, 0x39,
         0x97, 0x2d, 0x7b, 0x88, 0xac, 0x40, 0x94, 0xa8, 0x02, 0x00, 0x00, 0x00,
         0x00, 0x19, 0x76, 0xa9, 0x14, 0xc1, 0x09, 0x32, 0x48, 0x3f, 0xec, 0x93,
         0xed, 0x51, 0xf5, 0xfe, 0x95, 0xe7, 0x25, 0x59, 0xf2, 0xcc, 0x70, 0x43,
         0xf9, 0x88, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00};
-    std::vector<unsigned char> vch(ch, ch + sizeof(ch) - 1);
+    std::vector<uint8_t> vch(ch, ch + sizeof(ch) - 1);
     CDataStream spendStream(vch, SER_DISK, CLIENT_VERSION);
     CTransaction spendingTx(deserialize, spendStream);
 
     CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
     filter.insert(uint256S(
         "0xb4749f017444b051c44dfd2720e88f314ff94f3dd6d56d40ef65854fcd7fff6b"));
     BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx),
                         "Simple Bloom filter didn't match tx hash");
 
     filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
     // byte-reversed tx hash
     filter.insert(ParseHex(
         "6bff7fcd4f8565ef406dd5d63d4ff94f318fe82027fd4dc451b04474019f74b4"));
     BOOST_CHECK_MESSAGE(
         filter.IsRelevantAndUpdate(tx),
         "Simple Bloom filter didn't match manually serialized tx hash");
 
     filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
     filter.insert(ParseHex("30450220070aca44506c5cef3a16ed519d7c3c39f8aab192c4e"
                            "1c90d065f37b8a4af6141022100a8e160b856c2d43d27d8fba7"
                            "1e5aef6405b8643ac4cb7cb3c462aced7f14711a01"));
     BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx),
                         "Simple Bloom filter didn't match input signature");
 
     filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
     filter.insert(ParseHex("046d11fee51b0e60666d5049a9101a72741df480b96ee26488a"
                            "4d3466b95c9a40ac5eeef87e10a5cd336c19a84565f80fa6c54"
                            "7957b7700ff4dfbdefe76036c339"));
     BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx),
                         "Simple Bloom filter didn't match input pub key");
 
     filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
     filter.insert(ParseHex("04943fdd508053c75000106d3bc6e2754dbcff19"));
     BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx),
                         "Simple Bloom filter didn't match output address");
     BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(spendingTx),
                         "Simple Bloom filter didn't add output");
 
     filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
     filter.insert(ParseHex("a266436d2965547608b9e15d9032a7b9d64fa431"));
     BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx),
                         "Simple Bloom filter didn't match output address");
 
     filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
     filter.insert(COutPoint(uint256S("0x90c122d70786e899529d71dbeba91ba216982fb"
                                      "6ba58f3bdaab65e73b7e9260b"),
                             0));
     BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx),
                         "Simple Bloom filter didn't match COutPoint");
 
     filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
     COutPoint prevOutPoint(uint256S("0x90c122d70786e899529d71dbeba91ba216982fb6"
                                     "ba58f3bdaab65e73b7e9260b"),
                            0);
     {
-        std::vector<unsigned char> data(32 + sizeof(unsigned int));
+        std::vector<uint8_t> data(32 + sizeof(unsigned int));
         memcpy(&data[0], prevOutPoint.hash.begin(), 32);
         memcpy(&data[32], &prevOutPoint.n, sizeof(unsigned int));
         filter.insert(data);
     }
     BOOST_CHECK_MESSAGE(
         filter.IsRelevantAndUpdate(tx),
         "Simple Bloom filter didn't match manually serialized COutPoint");
 
     filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
     filter.insert(uint256S(
         "00000009e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436"));
     BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx),
                         "Simple Bloom filter matched random tx hash");
 
     filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
     filter.insert(ParseHex("0000006d2965547608b9e15d9032a7b9d64fa431"));
     BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx),
                         "Simple Bloom filter matched random address");
 
     filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
     filter.insert(COutPoint(uint256S("0x90c122d70786e899529d71dbeba91ba216982fb"
                                      "6ba58f3bdaab65e73b7e9260b"),
                             1));
     BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx),
                         "Simple Bloom filter matched COutPoint for an output "
                         "we didn't care about");
 
     filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
     filter.insert(COutPoint(uint256S("0x000000d70786e899529d71dbeba91ba216982fb"
                                      "6ba58f3bdaab65e73b7e9260b"),
                             0));
     BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx),
                         "Simple Bloom filter matched COutPoint for an output "
                         "we didn't care about");
 }
 
 BOOST_AUTO_TEST_CASE(merkle_block_1) {
     // Random real block
     // (0000000000013b8ab2cd513b0261a14096412195a72a0c4827d229dcc7e0f7af)
     // With 9 txes
     CBlock block;
     CDataStream stream(
         ParseHex(
             "0100000090f0a9f110702f808219ebea1173056042a714bad51b916cb680000000"
             "0000005275289558f51c9966699404ae2294730c3c9f9bda53523ce50e9b95e558"
             "da2fdb261b4d4c86041b1ab1bf9309010000000100000000000000000000000000"
             "00000000000000000000000000000000000000ffffffff07044c86041b0146ffff"
             "ffff0100f2052a01000000434104e18f7afbe4721580e81e8414fc8c24d7cfacf2"
             "54bb5c7b949450c3e997c2dc1242487a8169507b631eb3771f2b425483fb13102c"
             "4eb5d858eef260fe70fbfae0ac00000000010000000196608ccbafa16abada9027"
             "80da4dc35dafd7af05fa0da08cf833575f8cf9e836000000004a493046022100da"
             "b24889213caf43ae6adc41cf1c9396c08240c199f5225acf45416330fd7dbd0221"
             "00fe37900e0644bf574493a07fc5edba06dbc07c311b947520c2d514bc5725dcb4"
             "01ffffffff0100f2052a010000001976a914f15d1921f52e4007b146dfa60f369e"
             "d2fc393ce288ac000000000100000001fb766c1288458c2bafcfec81e48b24d98e"
             "c706de6b8af7c4e3c29419bfacb56d000000008c493046022100f268ba165ce0ad"
             "2e6d93f089cfcd3785de5c963bb5ea6b8c1b23f1ce3e517b9f022100da7c0f21ad"
             "c6c401887f2bfd1922f11d76159cbc597fbd756a23dcbb00f4d7290141042b4e86"
             "25a96127826915a5b109852636ad0da753c9e1d5606a50480cd0c40f1f8b8d8982"
             "35e571fe9357d9ec842bc4bba1827daaf4de06d71844d0057707966affffffff02"
             "80969800000000001976a9146963907531db72d0ed1a0cfb471ccb63923446f388"
             "ac80d6e34c000000001976a914f0688ba1c0d1ce182c7af6741e02658c7d4dfcd3"
             "88ac000000000100000002c40297f730dd7b5a99567eb8d27b78758f607507c522"
             "92d02d4031895b52f2ff010000008b483045022100f7edfd4b0aac404e5bab4fd3"
             "889e0c6c41aa8d0e6fa122316f68eddd0a65013902205b09cc8b2d56e1cd1f7f2f"
             "afd60a129ed94504c4ac7bdc67b56fe67512658b3e014104732012cb962afa90d3"
             "1b25d8fb0e32c94e513ab7a17805c14ca4c3423e18b4fb5d0e676841733cb83aba"
             "f975845c9f6f2a8097b7d04f4908b18368d6fc2d68ecffffffffca5065ff9617cb"
             "cba45eb23726df6498a9b9cafed4f54cbab9d227b0035ddefb000000008a473044"
             "022068010362a13c7f9919fa832b2dee4e788f61f6f5d344a7c2a0da6ae7406056"
             "58022006d1af525b9a14a35c003b78b72bd59738cd676f845d1ff3fc25049e0100"
             "3614014104732012cb962afa90d31b25d8fb0e32c94e513ab7a17805c14ca4c342"
             "3e18b4fb5d0e676841733cb83abaf975845c9f6f2a8097b7d04f4908b18368d6fc"
             "2d68ecffffffff01001ec4110200000043410469ab4181eceb28985b9b4e895c13"
             "fa5e68d85761b7eee311db5addef76fa8621865134a221bd01f28ec9999ee3e021"
             "e60766e9d1f3458c115fb28650605f11c9ac000000000100000001cdaf2f758e91"
             "c514655e2dc50633d1e4c84989f8aa90a0dbc883f0d23ed5c2fa010000008b4830"
             "4502207ab51be6f12a1962ba0aaaf24a20e0b69b27a94fac5adf45aa7d2d18ffd9"
             "236102210086ae728b370e5329eead9accd880d0cb070aea0c96255fae6c4f1ddc"
             "ce1fd56e014104462e76fd4067b3a0aa42070082dcb0bf2f388b6495cf33d78990"
             "4f07d0f55c40fbd4b82963c69b3dc31895d0c772c812b1d5fbcade15312ef1c0e8"
             "ebbb12dcd4ffffffff02404b4c00000000001976a9142b6ba7c9d796b75eef7942"
             "fc9288edd37c32f5c388ac002d3101000000001976a9141befba0cdc1ad5652937"
             "1864d9f6cb042faa06b588ac000000000100000001b4a47603e71b61bc3326efd9"
             "0111bf02d2f549b067f4c4a8fa183b57a0f800cb010000008a4730440220177c37"
             "f9a505c3f1a1f0ce2da777c339bd8339ffa02c7cb41f0a5804f473c9230220585b"
             "25a2ee80eb59292e52b987dad92acb0c64eced92ed9ee105ad153cdb12d0014104"
             "43bd44f683467e549dae7d20d1d79cbdb6df985c6e9c029c8d0c6cb46cc1a4d3cf"
             "7923c5021b27f7a0b562ada113bc85d5fda5a1b41e87fe6e8802817cf69996ffff"
             "ffff0280651406000000001976a9145505614859643ab7b547cd7f1f5e7e2a1232"
             "2d3788ac00aa0271000000001976a914ea4720a7a52fc166c55ff2298e07baf70a"
             "e67e1b88ac00000000010000000586c62cd602d219bb60edb14a3e204de0705176"
             "f9022fe49a538054fb14abb49e010000008c493046022100f2bc2aba2534becbdf"
             "062eb993853a42bbbc282083d0daf9b4b585bd401aa8c9022100b1d7fd7ee0b956"
             "00db8535bbf331b19eed8d961f7a8e54159c53675d5f69df8c014104462e76fd40"
             "67b3a0aa42070082dcb0bf2f388b6495cf33d789904f07d0f55c40fbd4b82963c6"
             "9b3dc31895d0c772c812b1d5fbcade15312ef1c0e8ebbb12dcd4ffffffff03ad0e"
             "58ccdac3df9dc28a218bcf6f1997b0a93306faaa4b3a28ae83447b217901000000"
             "8b483045022100be12b2937179da88599e27bb31c3525097a07cdb52422d165b3c"
             "a2f2020ffcf702200971b51f853a53d644ebae9ec8f3512e442b1bcb6c315a5b49"
             "1d119d10624c83014104462e76fd4067b3a0aa42070082dcb0bf2f388b6495cf33"
             "d789904f07d0f55c40fbd4b82963c69b3dc31895d0c772c812b1d5fbcade15312e"
             "f1c0e8ebbb12dcd4ffffffff2acfcab629bbc8685792603762c921580030ba144a"
             "f553d271716a95089e107b010000008b483045022100fa579a840ac258871365dd"
             "48cd7552f96c8eea69bd00d84f05b283a0dab311e102207e3c0ee9234814cfbb1b"
             "659b83671618f45abc1326b9edcc77d552a4f2a805c0014104462e76fd4067b3a0"
             "aa42070082dcb0bf2f388b6495cf33d789904f07d0f55c40fbd4b82963c69b3dc3"
             "1895d0c772c812b1d5fbcade15312ef1c0e8ebbb12dcd4ffffffffdcdc6023bbc9"
             "944a658ddc588e61eacb737ddf0a3cd24f113b5a8634c517fcd2000000008b4830"
             "450221008d6df731df5d32267954bd7d2dda2302b74c6c2a6aa5c0ca64ecbabc1a"
             "f03c75022010e55c571d65da7701ae2da1956c442df81bbf076cdbac25133f99d9"
             "8a9ed34c014104462e76fd4067b3a0aa42070082dcb0bf2f388b6495cf33d78990"
             "4f07d0f55c40fbd4b82963c69b3dc31895d0c772c812b1d5fbcade15312ef1c0e8"
             "ebbb12dcd4ffffffffe15557cd5ce258f479dfd6dc6514edf6d7ed5b21fcfa4a03"
             "8fd69f06b83ac76e010000008b483045022023b3e0ab071eb11de2eb1cc3a67261"
             "b866f86bf6867d4558165f7c8c8aca2d86022100dc6e1f53a91de3efe8f6351285"
             "0811f26284b62f850c70ca73ed5de8771fb451014104462e76fd4067b3a0aa4207"
             "0082dcb0bf2f388b6495cf33d789904f07d0f55c40fbd4b82963c69b3dc31895d0"
             "c772c812b1d5fbcade15312ef1c0e8ebbb12dcd4ffffffff01404b4c0000000000"
             "1976a9142b6ba7c9d796b75eef7942fc9288edd37c32f5c388ac00000000010000"
             "000166d7577163c932b4f9690ca6a80b6e4eb001f0a2fa9023df5595602aae96ed"
             "8d000000008a4730440220262b42546302dfb654a229cefc86432b89628ff259dc"
             "87edd1154535b16a67e102207b4634c020a97c3e7bbd0d4d19da6aa2269ad9dded"
             "4026e896b213d73ca4b63f014104979b82d02226b3a4597523845754d44f13639e"
             "3bf2df5e82c6aab2bdc79687368b01b1ab8b19875ae3c90d661a3d0a33161dab29"
             "934edeb36aa01976be3baf8affffffff02404b4c00000000001976a9144854e695"
             "a02af0aeacb823ccbc272134561e0a1688ac40420f00000000001976a914abee93"
             "376d6b37b5c2940655a6fcaf1c8e74237988ac0000000001000000014e3f8ef2e9"
             "1349a9059cb4f01e54ab2597c1387161d3da89919f7ea6acdbb371010000008c49"
             "304602210081f3183471a5ca22307c0800226f3ef9c353069e0773ac76bb580654"
             "d56aa523022100d4c56465bdc069060846f4fbf2f6b20520b2a80b08b168b31e66"
             "ddb9c694e240014104976c79848e18251612f8940875b2b08d06e6dc73b9840e88"
             "60c066b7e87432c477e9a59a453e71e6d76d5fe34058b800a098fc1740ce3012e8"
             "fc8a00c96af966ffffffff02c0e1e400000000001976a9144134e75a6fcb604203"
             "4aab5e18570cf1f844f54788ac404b4c00000000001976a9142b6ba7c9d796b75e"
             "ef7942fc9288edd37c32f5c388ac00000000"),
         SER_NETWORK, PROTOCOL_VERSION);
     stream >> block;
 
     CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
     // Match the last transaction
     filter.insert(uint256S(
         "0x74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20"));
 
     CMerkleBlock merkleBlock(block, filter);
     BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
 
     BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
     std::pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0];
 
     BOOST_CHECK(merkleBlock.vMatchedTxn[0].second ==
                 uint256S("0x74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b"
                          "586ec87451f20"));
     BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 8);
 
     std::vector<uint256> vMatched;
     std::vector<unsigned int> vIndex;
     BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) ==
                 block.hashMerkleRoot);
     BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
     for (unsigned int i = 0; i < vMatched.size(); i++)
         BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
 
     // Also match the 8th transaction
     filter.insert(uint256S(
         "0xdd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f168809cdfae1053"));
     merkleBlock = CMerkleBlock(block, filter);
     BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
 
     BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 2);
 
     BOOST_CHECK(merkleBlock.vMatchedTxn[1] == pair);
 
     BOOST_CHECK(merkleBlock.vMatchedTxn[0].second ==
                 uint256S("0xdd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f16"
                          "8809cdfae1053"));
     BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 7);
 
     BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) ==
                 block.hashMerkleRoot);
     BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
     for (unsigned int i = 0; i < vMatched.size(); i++)
         BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
 }
 
 BOOST_AUTO_TEST_CASE(merkle_block_2) {
     // Random real block
     // (000000005a4ded781e667e06ceefafb71410b511fe0d5adc3e5a27ecbec34ae6)
     // With 4 txes
     CBlock block;
     CDataStream stream(
         ParseHex(
             "0100000075616236cc2126035fadb38deb65b9102cc2c41c09cdf29fc051906800"
             "000000fe7d5e12ef0ff901f6050211249919b1c0653771832b3a80c66cea42847f"
             "0ae1d4d26e49ffff001d00f0a44104010000000100000000000000000000000000"
             "00000000000000000000000000000000000000ffffffff0804ffff001d029105ff"
             "ffffff0100f2052a010000004341046d8709a041d34357697dfcb30a9d05900a62"
             "94078012bf3bb09c6f9b525f1d16d5503d7905db1ada9501446ea00728668fc571"
             "9aa80be2fdfc8a858a4dbdd4fbac00000000010000000255605dc6f5c3dc148b6d"
             "a58442b0b2cd422be385eab2ebea4119ee9c268d28350000000049483045022100"
             "aa46504baa86df8a33b1192b1b9367b4d729dc41e389f2c04f3e5c7f0559aae702"
             "205e82253a54bf5c4f65b7428551554b2045167d6d206dfe6a2e198127d3f7df15"
             "01ffffffff55605dc6f5c3dc148b6da58442b0b2cd422be385eab2ebea4119ee9c"
             "268d2835010000004847304402202329484c35fa9d6bb32a55a70c0982f606ce0e"
             "3634b69006138683bcd12cbb6602200c28feb1e2555c3210f1dddb299738b4ff8b"
             "be9667b68cb8764b5ac17b7adf0001ffffffff0200e1f505000000004341046a07"
             "65b5865641ce08dd39690aade26dfbf5511430ca428a3089261361cef170e3929a"
             "68aee3d8d4848b0c5111b0a37b82b86ad559fd2a745b44d8e8d9dfdc0cac00180d"
             "8f000000004341044a656f065871a353f216ca26cef8dde2f03e8c16202d2e8ad7"
             "69f02032cb86a5eb5e56842e92e19141d60a01928f8dd2c875a390f67c1f6c94cf"
             "c617c0ea45afac0000000001000000025f9a06d3acdceb56be1bfeaa3e8a25e62d"
             "182fa24fefe899d1c17f1dad4c2028000000004847304402205d6058484157235b"
             "06028c30736c15613a28bdb768ee628094ca8b0030d4d6eb0220328789c9a2ec27"
             "ddaec0ad5ef58efded42e6ea17c2e1ce838f3d6913f5e95db601ffffffff5f9a06"
             "d3acdceb56be1bfeaa3e8a25e62d182fa24fefe899d1c17f1dad4c202801000000"
             "4a493046022100c45af050d3cea806cedd0ab22520c53ebe63b987b8954146cdca"
             "42487b84bdd6022100b9b027716a6b59e640da50a864d6dd8a0ef24c76ce62391f"
             "a3eabaf4d2886d2d01ffffffff0200e1f505000000004341046a0765b5865641ce"
             "08dd39690aade26dfbf5511430ca428a3089261361cef170e3929a68aee3d8d484"
             "8b0c5111b0a37b82b86ad559fd2a745b44d8e8d9dfdc0cac00180d8f0000000043"
             "41046a0765b5865641ce08dd39690aade26dfbf5511430ca428a3089261361cef1"
             "70e3929a68aee3d8d4848b0c5111b0a37b82b86ad559fd2a745b44d8e8d9dfdc0c"
             "ac000000000100000002e2274e5fea1bf29d963914bd301aa63b64daaf8a3e88f1"
             "19b5046ca5738a0f6b0000000048473044022016e7a727a061ea2254a6c358376a"
             "aa617ac537eb836c77d646ebda4c748aac8b0220192ce28bf9f2c06a6467e6531e"
             "27648d2b3e2e2bae85159c9242939840295ba501ffffffffe2274e5fea1bf29d96"
             "3914bd301aa63b64daaf8a3e88f119b5046ca5738a0f6b010000004a4930460221"
             "00b7a1a755588d4190118936e15cd217d133b0e4a53c3c15924010d5648d8925c9"
             "022100aaef031874db2114f2d869ac2de4ae53908fbfea5b2b1862e181626bb900"
             "5c9f01ffffffff0200e1f505000000004341044a656f065871a353f216ca26cef8"
             "dde2f03e8c16202d2e8ad769f02032cb86a5eb5e56842e92e19141d60a01928f8d"
             "d2c875a390f67c1f6c94cfc617c0ea45afac00180d8f000000004341046a0765b5"
             "865641ce08dd39690aade26dfbf5511430ca428a3089261361cef170e3929a68ae"
             "e3d8d4848b0c5111b0a37b82b86ad559fd2a745b44d8e8d9dfdc0cac00000000"),
         SER_NETWORK, PROTOCOL_VERSION);
     stream >> block;
 
     CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
     // Match the first transaction
     filter.insert(uint256S(
         "0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"));
 
     CMerkleBlock merkleBlock(block, filter);
     BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
 
     BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
     std::pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0];
 
     BOOST_CHECK(merkleBlock.vMatchedTxn[0].second ==
                 uint256S("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df"
                          "5b47aecb93b70"));
     BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0);
 
     std::vector<uint256> vMatched;
     std::vector<unsigned int> vIndex;
     BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) ==
                 block.hashMerkleRoot);
     BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
     for (unsigned int i = 0; i < vMatched.size(); i++)
         BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
 
     // Match an output from the second transaction (the pubkey for address
     // 1DZTzaBHUDM7T3QvUKBz4qXMRpkg8jsfB5)
     // This should match the third transaction because it spends the output
     // matched
     // It also matches the fourth transaction, which spends to the pubkey again
     filter.insert(ParseHex("044a656f065871a353f216ca26cef8dde2f03e8c16202d2e8ad"
                            "769f02032cb86a5eb5e56842e92e19141d60a01928f8dd2c875"
                            "a390f67c1f6c94cfc617c0ea45af"));
 
     merkleBlock = CMerkleBlock(block, filter);
     BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
 
     BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 4);
 
     BOOST_CHECK(pair == merkleBlock.vMatchedTxn[0]);
 
     BOOST_CHECK(merkleBlock.vMatchedTxn[1].second ==
                 uint256S("0x28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56e"
                          "bdcacd3069a5f"));
     BOOST_CHECK(merkleBlock.vMatchedTxn[1].first == 1);
 
     BOOST_CHECK(merkleBlock.vMatchedTxn[2].second ==
                 uint256S("0x6b0f8a73a56c04b519f1883e8aafda643ba61a30bd1439969df"
                          "21bea5f4e27e2"));
     BOOST_CHECK(merkleBlock.vMatchedTxn[2].first == 2);
 
     BOOST_CHECK(merkleBlock.vMatchedTxn[3].second ==
                 uint256S("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d70076"
                          "63ace63cddb23"));
     BOOST_CHECK(merkleBlock.vMatchedTxn[3].first == 3);
 
     BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) ==
                 block.hashMerkleRoot);
     BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
     for (unsigned int i = 0; i < vMatched.size(); i++)
         BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
 }
 
 BOOST_AUTO_TEST_CASE(merkle_block_2_with_update_none) {
     // Random real block
     // (000000005a4ded781e667e06ceefafb71410b511fe0d5adc3e5a27ecbec34ae6)
     // With 4 txes
     CBlock block;
     CDataStream stream(
         ParseHex(
             "0100000075616236cc2126035fadb38deb65b9102cc2c41c09cdf29fc051906800"
             "000000fe7d5e12ef0ff901f6050211249919b1c0653771832b3a80c66cea42847f"
             "0ae1d4d26e49ffff001d00f0a44104010000000100000000000000000000000000"
             "00000000000000000000000000000000000000ffffffff0804ffff001d029105ff"
             "ffffff0100f2052a010000004341046d8709a041d34357697dfcb30a9d05900a62"
             "94078012bf3bb09c6f9b525f1d16d5503d7905db1ada9501446ea00728668fc571"
             "9aa80be2fdfc8a858a4dbdd4fbac00000000010000000255605dc6f5c3dc148b6d"
             "a58442b0b2cd422be385eab2ebea4119ee9c268d28350000000049483045022100"
             "aa46504baa86df8a33b1192b1b9367b4d729dc41e389f2c04f3e5c7f0559aae702"
             "205e82253a54bf5c4f65b7428551554b2045167d6d206dfe6a2e198127d3f7df15"
             "01ffffffff55605dc6f5c3dc148b6da58442b0b2cd422be385eab2ebea4119ee9c"
             "268d2835010000004847304402202329484c35fa9d6bb32a55a70c0982f606ce0e"
             "3634b69006138683bcd12cbb6602200c28feb1e2555c3210f1dddb299738b4ff8b"
             "be9667b68cb8764b5ac17b7adf0001ffffffff0200e1f505000000004341046a07"
             "65b5865641ce08dd39690aade26dfbf5511430ca428a3089261361cef170e3929a"
             "68aee3d8d4848b0c5111b0a37b82b86ad559fd2a745b44d8e8d9dfdc0cac00180d"
             "8f000000004341044a656f065871a353f216ca26cef8dde2f03e8c16202d2e8ad7"
             "69f02032cb86a5eb5e56842e92e19141d60a01928f8dd2c875a390f67c1f6c94cf"
             "c617c0ea45afac0000000001000000025f9a06d3acdceb56be1bfeaa3e8a25e62d"
             "182fa24fefe899d1c17f1dad4c2028000000004847304402205d6058484157235b"
             "06028c30736c15613a28bdb768ee628094ca8b0030d4d6eb0220328789c9a2ec27"
             "ddaec0ad5ef58efded42e6ea17c2e1ce838f3d6913f5e95db601ffffffff5f9a06"
             "d3acdceb56be1bfeaa3e8a25e62d182fa24fefe899d1c17f1dad4c202801000000"
             "4a493046022100c45af050d3cea806cedd0ab22520c53ebe63b987b8954146cdca"
             "42487b84bdd6022100b9b027716a6b59e640da50a864d6dd8a0ef24c76ce62391f"
             "a3eabaf4d2886d2d01ffffffff0200e1f505000000004341046a0765b5865641ce"
             "08dd39690aade26dfbf5511430ca428a3089261361cef170e3929a68aee3d8d484"
             "8b0c5111b0a37b82b86ad559fd2a745b44d8e8d9dfdc0cac00180d8f0000000043"
             "41046a0765b5865641ce08dd39690aade26dfbf5511430ca428a3089261361cef1"
             "70e3929a68aee3d8d4848b0c5111b0a37b82b86ad559fd2a745b44d8e8d9dfdc0c"
             "ac000000000100000002e2274e5fea1bf29d963914bd301aa63b64daaf8a3e88f1"
             "19b5046ca5738a0f6b0000000048473044022016e7a727a061ea2254a6c358376a"
             "aa617ac537eb836c77d646ebda4c748aac8b0220192ce28bf9f2c06a6467e6531e"
             "27648d2b3e2e2bae85159c9242939840295ba501ffffffffe2274e5fea1bf29d96"
             "3914bd301aa63b64daaf8a3e88f119b5046ca5738a0f6b010000004a4930460221"
             "00b7a1a755588d4190118936e15cd217d133b0e4a53c3c15924010d5648d8925c9"
             "022100aaef031874db2114f2d869ac2de4ae53908fbfea5b2b1862e181626bb900"
             "5c9f01ffffffff0200e1f505000000004341044a656f065871a353f216ca26cef8"
             "dde2f03e8c16202d2e8ad769f02032cb86a5eb5e56842e92e19141d60a01928f8d"
             "d2c875a390f67c1f6c94cfc617c0ea45afac00180d8f000000004341046a0765b5"
             "865641ce08dd39690aade26dfbf5511430ca428a3089261361cef170e3929a68ae"
             "e3d8d4848b0c5111b0a37b82b86ad559fd2a745b44d8e8d9dfdc0cac00000000"),
         SER_NETWORK, PROTOCOL_VERSION);
     stream >> block;
 
     CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_NONE);
     // Match the first transaction
     filter.insert(uint256S(
         "0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"));
 
     CMerkleBlock merkleBlock(block, filter);
     BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
 
     BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
     std::pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0];
 
     BOOST_CHECK(merkleBlock.vMatchedTxn[0].second ==
                 uint256S("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df"
                          "5b47aecb93b70"));
     BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0);
 
     std::vector<uint256> vMatched;
     std::vector<unsigned int> vIndex;
     BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) ==
                 block.hashMerkleRoot);
     BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
     for (unsigned int i = 0; i < vMatched.size(); i++)
         BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
 
     // Match an output from the second transaction (the pubkey for address
     // 1DZTzaBHUDM7T3QvUKBz4qXMRpkg8jsfB5)
     // This should not match the third transaction though it spends the output
     // matched
     // It will match the fourth transaction, which has another pay-to-pubkey
     // output to the same address
     filter.insert(ParseHex("044a656f065871a353f216ca26cef8dde2f03e8c16202d2e8ad"
                            "769f02032cb86a5eb5e56842e92e19141d60a01928f8dd2c875"
                            "a390f67c1f6c94cfc617c0ea45af"));
 
     merkleBlock = CMerkleBlock(block, filter);
     BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
 
     BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 3);
 
     BOOST_CHECK(pair == merkleBlock.vMatchedTxn[0]);
 
     BOOST_CHECK(merkleBlock.vMatchedTxn[1].second ==
                 uint256S("0x28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56e"
                          "bdcacd3069a5f"));
     BOOST_CHECK(merkleBlock.vMatchedTxn[1].first == 1);
 
     BOOST_CHECK(merkleBlock.vMatchedTxn[2].second ==
                 uint256S("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d70076"
                          "63ace63cddb23"));
     BOOST_CHECK(merkleBlock.vMatchedTxn[2].first == 3);
 
     BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) ==
                 block.hashMerkleRoot);
     BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
     for (unsigned int i = 0; i < vMatched.size(); i++)
         BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
 }
 
 BOOST_AUTO_TEST_CASE(merkle_block_3_and_serialize) {
     // Random real block
     // (000000000000dab0130bbcc991d3d7ae6b81aa6f50a798888dfe62337458dc45)
     // With one tx
     CBlock block;
     CDataStream stream(
         ParseHex("0100000079cda856b143d9db2c1caff01d1aecc8630d30625d10e8b4b8b00"
                  "00000000000b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3f"
                  "f60abe184f196367291b4d4c86041b8fa45d6301010000000100000000000"
                  "00000000000000000000000000000000000000000000000000000ffffffff"
                  "08044c86041b020a02ffffffff0100f2052a01000000434104ecd3229b057"
                  "1c3be876feaac0442a9f13c5a572742927af1dc623353ecf8c202225f6486"
                  "8137a18cdd85cbbb4c74fbccfd4f49639cf1bdc94a5672bb15ad5d4cac000"
                  "00000"),
         SER_NETWORK, PROTOCOL_VERSION);
     stream >> block;
 
     CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
     // Match the only transaction
     filter.insert(uint256S(
         "0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5"));
 
     CMerkleBlock merkleBlock(block, filter);
     BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
 
     BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
 
     BOOST_CHECK(merkleBlock.vMatchedTxn[0].second ==
                 uint256S("0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee"
                          "3a3d669c00cb5"));
     BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0);
 
     std::vector<uint256> vMatched;
     std::vector<unsigned int> vIndex;
     BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) ==
                 block.hashMerkleRoot);
     BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
     for (unsigned int i = 0; i < vMatched.size(); i++)
         BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
 
     CDataStream merkleStream(SER_NETWORK, PROTOCOL_VERSION);
     merkleStream << merkleBlock;
 
-    std::vector<unsigned char> vch =
+    std::vector<uint8_t> vch =
         ParseHex("0100000079cda856b143d9db2c1caff01d1aecc8630d30625d10e8b4b8b00"
                  "00000000000b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3f"
                  "f60abe184f196367291b4d4c86041b8fa45d630100000001b50cc069d6a3e"
                  "33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f19630101");
     std::vector<char> expected(vch.size());
 
     for (unsigned int i = 0; i < vch.size(); i++)
         expected[i] = (char)vch[i];
 
     BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(),
                                   merkleStream.begin(), merkleStream.end());
 }
 
 BOOST_AUTO_TEST_CASE(merkle_block_4) {
     // Random real block
     // (000000000000b731f2eef9e8c63173adfb07e41bd53eb0ef0a6b720d6cb6dea4)
     // With 7 txes
     CBlock block;
     CDataStream stream(
         ParseHex(
             "0100000082bb869cf3a793432a66e826e05a6fc37469f8efb7421dc88067010000"
             "0000007f16c5962e8bd963659c793ce370d95f093bc7e367117b3c30c1f8fdd0d9"
             "728776381b4d4c86041b554b852907010000000100000000000000000000000000"
             "00000000000000000000000000000000000000ffffffff07044c86041b0136ffff"
             "ffff0100f2052a01000000434104eaafc2314def4ca98ac970241bcab022b9c1e1"
             "f4ea423a20f134c876f2c01ec0f0dd5b2e86e7168cefe0d81113c3807420ce13ad"
             "1357231a2252247d97a46a91ac000000000100000001bcad20a6a29827d1424f08"
             "989255120bf7f3e9e3cdaaa6bb31b0737fe048724300000000494830450220356e"
             "834b046cadc0f8ebb5a8a017b02de59c86305403dad52cd77b55af062ea1022100"
             "9253cd6c119d4729b77c978e1e2aa19f5ea6e0e52b3f16e32fa608cd5bab753901"
             "ffffffff02008d380c010000001976a9142b4b8072ecbba129b6453c63e129e643"
             "207249ca88ac0065cd1d000000001976a9141b8dd13b994bcfc787b32aeadf58cc"
             "b3615cbd5488ac000000000100000003fdacf9b3eb077412e7a968d2e4f11b9a9d"
             "ee312d666187ed77ee7d26af16cb0b000000008c493046022100ea1608e70911ca"
             "0de5af51ba57ad23b9a51db8d28f82c53563c56a05c20f5a87022100a8bdc8b4a8"
             "acc8634c6b420410150775eb7f2474f5615f7fccd65af30f310fbf01410465fdf4"
             "9e29b06b9a1582287b6279014f834edc317695d125ef623c1cc3aaece245bd69fc"
             "ad7508666e9c74a49dc9056d5fc14338ef38118dc4afae5fe2c585caffffffff30"
             "9e1913634ecb50f3c4f83e96e70b2df071b497b8973a3e75429df397b5af830000"
             "00004948304502202bdb79c596a9ffc24e96f4386199aba386e9bc7b6071516e2b"
             "51dda942b3a1ed022100c53a857e76b724fc14d45311eac5019650d415c3abb542"
             "8f3aae16d8e69bec2301ffffffff2089e33491695080c9edc18a428f7d834db5b6"
             "d372df13ce2b1b0e0cbcb1e6c10000000049483045022100d4ce67c5896ee251c8"
             "10ac1ff9ceccd328b497c8f553ab6e08431e7d40bad6b5022033119c0c2b7d792d"
             "31f1187779c7bd95aefd93d90a715586d73801d9b47471c601ffffffff01007144"
             "60030000001976a914c7b55141d097ea5df7a0ed330cf794376e53ec8d88ac0000"
             "000001000000045bf0e214aa4069a3e792ecee1e1bf0c1d397cde8dd08138f4b72"
             "a00681743447000000008b48304502200c45de8c4f3e2c1821f2fc878cba97b1e6"
             "f8807d94930713aa1c86a67b9bf1e40221008581abfef2e30f957815fc89978423"
             "746b2086375ca8ecf359c85c2a5b7c88ad01410462bb73f76ca0994fcb8b4271e6"
             "fb7561f5c0f9ca0cf6485261c4a0dc894f4ab844c6cdfb97cd0b60ffb5018ffd62"
             "38f4d87270efb1d3ae37079b794a92d7ec95ffffffffd669f7d7958d40fc59d225"
             "3d88e0f248e29b599c80bbcec344a83dda5f9aa72c000000008a47304402207812"
             "4c8beeaa825f9e0b30bff96e564dd859432f2d0cb3b72d3d5d93d38d7e93022069"
             "1d233b6c0f995be5acb03d70a7f7a65b6bc9bdd426260f38a1346669507a360141"
             "0462bb73f76ca0994fcb8b4271e6fb7561f5c0f9ca0cf6485261c4a0dc894f4ab8"
             "44c6cdfb97cd0b60ffb5018ffd6238f4d87270efb1d3ae37079b794a92d7ec95ff"
             "fffffff878af0d93f5229a68166cf051fd372bb7a537232946e0a46f53636b4daf"
             "daa4000000008c493046022100c717d1714551663f69c3c5759bdbb3a0fcd3fab0"
             "23abc0e522fe6440de35d8290221008d9cbe25bffc44af2b18e81c58eb37293fd7"
             "fe1c2e7b46fc37ee8c96c50ab1e201410462bb73f76ca0994fcb8b4271e6fb7561"
             "f5c0f9ca0cf6485261c4a0dc894f4ab844c6cdfb97cd0b60ffb5018ffd6238f4d8"
             "7270efb1d3ae37079b794a92d7ec95ffffffff27f2b668859cd7f2f894aa0fd2d9"
             "e60963bcd07c88973f425f999b8cbfd7a1e2000000008c493046022100e0084714"
             "7cbf517bcc2f502f3ddc6d284358d102ed20d47a8aa788a62f0db780022100d17b"
             "2d6fa84dcaf1c95d88d7e7c30385aecf415588d749afd3ec81f6022cecd7014104"
             "62bb73f76ca0994fcb8b4271e6fb7561f5c0f9ca0cf6485261c4a0dc894f4ab844"
             "c6cdfb97cd0b60ffb5018ffd6238f4d87270efb1d3ae37079b794a92d7ec95ffff"
             "ffff0100c817a8040000001976a914b6efd80d99179f4f4ff6f4dd0a007d018c38"
             "5d2188ac000000000100000001834537b2f1ce8ef9373a258e10545ce5a50b758d"
             "f616cd4356e0032554ebd3c4000000008b483045022100e68f422dd7c34fdce11e"
             "eb4509ddae38201773dd62f284e8aa9d96f85099d0b002202243bd399ff96b649a"
             "0fad05fa759d6a882f0af8c90cf7632c2840c29070aec20141045e58067e815c2f"
             "464c6a2a15f987758374203895710c2d452442e28496ff38ba8f5fd901dc20e29e"
             "88477167fe4fc299bf818fd0d9e1632d467b2a3d9503b1aaffffffff0280d7e636"
             "030000001976a914f34c3e10eb387efe872acb614c89e78bfca7815d88ac404b4c"
             "00000000001976a914a84e272933aaf87e1715d7786c51dfaeb5b65a6f88ac0000"
             "0000010000000143ac81c8e6f6ef307dfe17f3d906d999e23e0189fda838c5510d"
             "850927e03ae7000000008c4930460221009c87c344760a64cb8ae6685a3eec2c1a"
             "c1bed5b88c87de51acd0e124f266c16602210082d07c037359c3a257b5c63ebd90"
             "f5a5edf97b2ac1c434b08ca998839f346dd40141040ba7e521fa7946d12edbb1d1"
             "e95a15c34bd4398195e86433c92b431cd315f455fe30032ede69cad9d1e1ed6c3c"
             "4ec0dbfced53438c625462afb792dcb098544bffffffff0240420f000000000019"
             "76a9144676d1b820d63ec272f1900d59d43bc6463d96f888ac40420f0000000000"
             "1976a914648d04341d00d7968b3405c034adc38d4d8fb9bd88ac00000000010000"
             "000248cc917501ea5c55f4a8d2009c0567c40cfe037c2e71af017d0a452ff705e3"
             "f1000000008b483045022100bf5fdc86dc5f08a5d5c8e43a8c9d5b1ed8c65562e2"
             "80007b52b133021acd9acc02205e325d613e555f772802bf413d36ba807892ed1a"
             "690a77811d3033b3de226e0a01410429fa713b124484cb2bd7b5557b2c0b9df7b2"
             "b1fee61825eadc5ae6c37a9920d38bfccdc7dc3cb0c47d7b173dbc9db8d37db0a3"
             "3ae487982c59c6f8606e9d1791ffffffff41ed70551dd7e841883ab8f0b16bf041"
             "76b7d1480e4f0af9f3d4c3595768d068000000008b4830450221008513ad65187b"
             "903aed1102d1d0c47688127658c51106753fed0151ce9c16b80902201432b9ebcb"
             "87bd04ceb2de66035fbbaf4bf8b00d1cfe41f1a1f7338f9ad79d210141049d4cf8"
             "0125bf50be1709f718c07ad15d0fc612b7da1f5570dddc35f2a352f0f27c978b06"
             "820edca9ef982c35fda2d255afba340068c5035552368bc7200c1488ffffffff01"
             "00093d00000000001976a9148edb68822f1ad580b043c7b3df2e400f8699eb4888"
             "ac00000000"),
         SER_NETWORK, PROTOCOL_VERSION);
     stream >> block;
 
     CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
     // Match the last transaction
     filter.insert(uint256S(
         "0x0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f19b15df0ac154"));
 
     CMerkleBlock merkleBlock(block, filter);
     BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
 
     BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
     std::pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0];
 
     BOOST_CHECK(merkleBlock.vMatchedTxn[0].second ==
                 uint256S("0x0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f"
                          "19b15df0ac154"));
     BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 6);
 
     std::vector<uint256> vMatched;
     std::vector<unsigned int> vIndex;
     BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) ==
                 block.hashMerkleRoot);
     BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
     for (unsigned int i = 0; i < vMatched.size(); i++)
         BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
 
     // Also match the 4th transaction
     filter.insert(uint256S(
         "0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"));
     merkleBlock = CMerkleBlock(block, filter);
     BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
 
     BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 2);
 
     BOOST_CHECK(merkleBlock.vMatchedTxn[0].second ==
                 uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de673"
                          "26471df5bc041"));
     BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 3);
 
     BOOST_CHECK(merkleBlock.vMatchedTxn[1] == pair);
 
     BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) ==
                 block.hashMerkleRoot);
     BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
     for (unsigned int i = 0; i < vMatched.size(); i++)
         BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
 }
 
 BOOST_AUTO_TEST_CASE(merkle_block_4_test_p2pubkey_only) {
     // Random real block
     // (000000000000b731f2eef9e8c63173adfb07e41bd53eb0ef0a6b720d6cb6dea4)
     // With 7 txes
     CBlock block;
     CDataStream stream(
         ParseHex(
             "0100000082bb869cf3a793432a66e826e05a6fc37469f8efb7421dc88067010000"
             "0000007f16c5962e8bd963659c793ce370d95f093bc7e367117b3c30c1f8fdd0d9"
             "728776381b4d4c86041b554b852907010000000100000000000000000000000000"
             "00000000000000000000000000000000000000ffffffff07044c86041b0136ffff"
             "ffff0100f2052a01000000434104eaafc2314def4ca98ac970241bcab022b9c1e1"
             "f4ea423a20f134c876f2c01ec0f0dd5b2e86e7168cefe0d81113c3807420ce13ad"
             "1357231a2252247d97a46a91ac000000000100000001bcad20a6a29827d1424f08"
             "989255120bf7f3e9e3cdaaa6bb31b0737fe048724300000000494830450220356e"
             "834b046cadc0f8ebb5a8a017b02de59c86305403dad52cd77b55af062ea1022100"
             "9253cd6c119d4729b77c978e1e2aa19f5ea6e0e52b3f16e32fa608cd5bab753901"
             "ffffffff02008d380c010000001976a9142b4b8072ecbba129b6453c63e129e643"
             "207249ca88ac0065cd1d000000001976a9141b8dd13b994bcfc787b32aeadf58cc"
             "b3615cbd5488ac000000000100000003fdacf9b3eb077412e7a968d2e4f11b9a9d"
             "ee312d666187ed77ee7d26af16cb0b000000008c493046022100ea1608e70911ca"
             "0de5af51ba57ad23b9a51db8d28f82c53563c56a05c20f5a87022100a8bdc8b4a8"
             "acc8634c6b420410150775eb7f2474f5615f7fccd65af30f310fbf01410465fdf4"
             "9e29b06b9a1582287b6279014f834edc317695d125ef623c1cc3aaece245bd69fc"
             "ad7508666e9c74a49dc9056d5fc14338ef38118dc4afae5fe2c585caffffffff30"
             "9e1913634ecb50f3c4f83e96e70b2df071b497b8973a3e75429df397b5af830000"
             "00004948304502202bdb79c596a9ffc24e96f4386199aba386e9bc7b6071516e2b"
             "51dda942b3a1ed022100c53a857e76b724fc14d45311eac5019650d415c3abb542"
             "8f3aae16d8e69bec2301ffffffff2089e33491695080c9edc18a428f7d834db5b6"
             "d372df13ce2b1b0e0cbcb1e6c10000000049483045022100d4ce67c5896ee251c8"
             "10ac1ff9ceccd328b497c8f553ab6e08431e7d40bad6b5022033119c0c2b7d792d"
             "31f1187779c7bd95aefd93d90a715586d73801d9b47471c601ffffffff01007144"
             "60030000001976a914c7b55141d097ea5df7a0ed330cf794376e53ec8d88ac0000"
             "000001000000045bf0e214aa4069a3e792ecee1e1bf0c1d397cde8dd08138f4b72"
             "a00681743447000000008b48304502200c45de8c4f3e2c1821f2fc878cba97b1e6"
             "f8807d94930713aa1c86a67b9bf1e40221008581abfef2e30f957815fc89978423"
             "746b2086375ca8ecf359c85c2a5b7c88ad01410462bb73f76ca0994fcb8b4271e6"
             "fb7561f5c0f9ca0cf6485261c4a0dc894f4ab844c6cdfb97cd0b60ffb5018ffd62"
             "38f4d87270efb1d3ae37079b794a92d7ec95ffffffffd669f7d7958d40fc59d225"
             "3d88e0f248e29b599c80bbcec344a83dda5f9aa72c000000008a47304402207812"
             "4c8beeaa825f9e0b30bff96e564dd859432f2d0cb3b72d3d5d93d38d7e93022069"
             "1d233b6c0f995be5acb03d70a7f7a65b6bc9bdd426260f38a1346669507a360141"
             "0462bb73f76ca0994fcb8b4271e6fb7561f5c0f9ca0cf6485261c4a0dc894f4ab8"
             "44c6cdfb97cd0b60ffb5018ffd6238f4d87270efb1d3ae37079b794a92d7ec95ff"
             "fffffff878af0d93f5229a68166cf051fd372bb7a537232946e0a46f53636b4daf"
             "daa4000000008c493046022100c717d1714551663f69c3c5759bdbb3a0fcd3fab0"
             "23abc0e522fe6440de35d8290221008d9cbe25bffc44af2b18e81c58eb37293fd7"
             "fe1c2e7b46fc37ee8c96c50ab1e201410462bb73f76ca0994fcb8b4271e6fb7561"
             "f5c0f9ca0cf6485261c4a0dc894f4ab844c6cdfb97cd0b60ffb5018ffd6238f4d8"
             "7270efb1d3ae37079b794a92d7ec95ffffffff27f2b668859cd7f2f894aa0fd2d9"
             "e60963bcd07c88973f425f999b8cbfd7a1e2000000008c493046022100e0084714"
             "7cbf517bcc2f502f3ddc6d284358d102ed20d47a8aa788a62f0db780022100d17b"
             "2d6fa84dcaf1c95d88d7e7c30385aecf415588d749afd3ec81f6022cecd7014104"
             "62bb73f76ca0994fcb8b4271e6fb7561f5c0f9ca0cf6485261c4a0dc894f4ab844"
             "c6cdfb97cd0b60ffb5018ffd6238f4d87270efb1d3ae37079b794a92d7ec95ffff"
             "ffff0100c817a8040000001976a914b6efd80d99179f4f4ff6f4dd0a007d018c38"
             "5d2188ac000000000100000001834537b2f1ce8ef9373a258e10545ce5a50b758d"
             "f616cd4356e0032554ebd3c4000000008b483045022100e68f422dd7c34fdce11e"
             "eb4509ddae38201773dd62f284e8aa9d96f85099d0b002202243bd399ff96b649a"
             "0fad05fa759d6a882f0af8c90cf7632c2840c29070aec20141045e58067e815c2f"
             "464c6a2a15f987758374203895710c2d452442e28496ff38ba8f5fd901dc20e29e"
             "88477167fe4fc299bf818fd0d9e1632d467b2a3d9503b1aaffffffff0280d7e636"
             "030000001976a914f34c3e10eb387efe872acb614c89e78bfca7815d88ac404b4c"
             "00000000001976a914a84e272933aaf87e1715d7786c51dfaeb5b65a6f88ac0000"
             "0000010000000143ac81c8e6f6ef307dfe17f3d906d999e23e0189fda838c5510d"
             "850927e03ae7000000008c4930460221009c87c344760a64cb8ae6685a3eec2c1a"
             "c1bed5b88c87de51acd0e124f266c16602210082d07c037359c3a257b5c63ebd90"
             "f5a5edf97b2ac1c434b08ca998839f346dd40141040ba7e521fa7946d12edbb1d1"
             "e95a15c34bd4398195e86433c92b431cd315f455fe30032ede69cad9d1e1ed6c3c"
             "4ec0dbfced53438c625462afb792dcb098544bffffffff0240420f000000000019"
             "76a9144676d1b820d63ec272f1900d59d43bc6463d96f888ac40420f0000000000"
             "1976a914648d04341d00d7968b3405c034adc38d4d8fb9bd88ac00000000010000"
             "000248cc917501ea5c55f4a8d2009c0567c40cfe037c2e71af017d0a452ff705e3"
             "f1000000008b483045022100bf5fdc86dc5f08a5d5c8e43a8c9d5b1ed8c65562e2"
             "80007b52b133021acd9acc02205e325d613e555f772802bf413d36ba807892ed1a"
             "690a77811d3033b3de226e0a01410429fa713b124484cb2bd7b5557b2c0b9df7b2"
             "b1fee61825eadc5ae6c37a9920d38bfccdc7dc3cb0c47d7b173dbc9db8d37db0a3"
             "3ae487982c59c6f8606e9d1791ffffffff41ed70551dd7e841883ab8f0b16bf041"
             "76b7d1480e4f0af9f3d4c3595768d068000000008b4830450221008513ad65187b"
             "903aed1102d1d0c47688127658c51106753fed0151ce9c16b80902201432b9ebcb"
             "87bd04ceb2de66035fbbaf4bf8b00d1cfe41f1a1f7338f9ad79d210141049d4cf8"
             "0125bf50be1709f718c07ad15d0fc612b7da1f5570dddc35f2a352f0f27c978b06"
             "820edca9ef982c35fda2d255afba340068c5035552368bc7200c1488ffffffff01"
             "00093d00000000001976a9148edb68822f1ad580b043c7b3df2e400f8699eb4888"
             "ac00000000"),
         SER_NETWORK, PROTOCOL_VERSION);
     stream >> block;
 
     CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_P2PUBKEY_ONLY);
     // Match the generation pubkey
     filter.insert(ParseHex("04eaafc2314def4ca98ac970241bcab022b9c1e1f4ea423a20f"
                            "134c876f2c01ec0f0dd5b2e86e7168cefe0d81113c3807420ce"
                            "13ad1357231a2252247d97a46a91"));
     // ...and the output address of the 4th transaction
     filter.insert(ParseHex("b6efd80d99179f4f4ff6f4dd0a007d018c385d21"));
 
     CMerkleBlock merkleBlock(block, filter);
     BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
 
     // We should match the generation outpoint
     BOOST_CHECK(
         filter.contains(COutPoint(uint256S("0x147caa76786596590baa4e98f5d9f48b8"
                                            "6c7765e489f7a6ff3360fe5c674360b"),
                                   0)));
     // ... but not the 4th transaction's output (its not pay-2-pubkey)
     BOOST_CHECK(
         !filter.contains(COutPoint(uint256S("0x02981fa052f0481dbc5868f4fc216603"
                                             "5a10f27a03cfd2de67326471df5bc041"),
                                    0)));
 }
 
 BOOST_AUTO_TEST_CASE(merkle_block_4_test_update_none) {
     // Random real block
     // (000000000000b731f2eef9e8c63173adfb07e41bd53eb0ef0a6b720d6cb6dea4)
     // With 7 txes
     CBlock block;
     CDataStream stream(
         ParseHex(
             "0100000082bb869cf3a793432a66e826e05a6fc37469f8efb7421dc88067010000"
             "0000007f16c5962e8bd963659c793ce370d95f093bc7e367117b3c30c1f8fdd0d9"
             "728776381b4d4c86041b554b852907010000000100000000000000000000000000"
             "00000000000000000000000000000000000000ffffffff07044c86041b0136ffff"
             "ffff0100f2052a01000000434104eaafc2314def4ca98ac970241bcab022b9c1e1"
             "f4ea423a20f134c876f2c01ec0f0dd5b2e86e7168cefe0d81113c3807420ce13ad"
             "1357231a2252247d97a46a91ac000000000100000001bcad20a6a29827d1424f08"
             "989255120bf7f3e9e3cdaaa6bb31b0737fe048724300000000494830450220356e"
             "834b046cadc0f8ebb5a8a017b02de59c86305403dad52cd77b55af062ea1022100"
             "9253cd6c119d4729b77c978e1e2aa19f5ea6e0e52b3f16e32fa608cd5bab753901"
             "ffffffff02008d380c010000001976a9142b4b8072ecbba129b6453c63e129e643"
             "207249ca88ac0065cd1d000000001976a9141b8dd13b994bcfc787b32aeadf58cc"
             "b3615cbd5488ac000000000100000003fdacf9b3eb077412e7a968d2e4f11b9a9d"
             "ee312d666187ed77ee7d26af16cb0b000000008c493046022100ea1608e70911ca"
             "0de5af51ba57ad23b9a51db8d28f82c53563c56a05c20f5a87022100a8bdc8b4a8"
             "acc8634c6b420410150775eb7f2474f5615f7fccd65af30f310fbf01410465fdf4"
             "9e29b06b9a1582287b6279014f834edc317695d125ef623c1cc3aaece245bd69fc"
             "ad7508666e9c74a49dc9056d5fc14338ef38118dc4afae5fe2c585caffffffff30"
             "9e1913634ecb50f3c4f83e96e70b2df071b497b8973a3e75429df397b5af830000"
             "00004948304502202bdb79c596a9ffc24e96f4386199aba386e9bc7b6071516e2b"
             "51dda942b3a1ed022100c53a857e76b724fc14d45311eac5019650d415c3abb542"
             "8f3aae16d8e69bec2301ffffffff2089e33491695080c9edc18a428f7d834db5b6"
             "d372df13ce2b1b0e0cbcb1e6c10000000049483045022100d4ce67c5896ee251c8"
             "10ac1ff9ceccd328b497c8f553ab6e08431e7d40bad6b5022033119c0c2b7d792d"
             "31f1187779c7bd95aefd93d90a715586d73801d9b47471c601ffffffff01007144"
             "60030000001976a914c7b55141d097ea5df7a0ed330cf794376e53ec8d88ac0000"
             "000001000000045bf0e214aa4069a3e792ecee1e1bf0c1d397cde8dd08138f4b72"
             "a00681743447000000008b48304502200c45de8c4f3e2c1821f2fc878cba97b1e6"
             "f8807d94930713aa1c86a67b9bf1e40221008581abfef2e30f957815fc89978423"
             "746b2086375ca8ecf359c85c2a5b7c88ad01410462bb73f76ca0994fcb8b4271e6"
             "fb7561f5c0f9ca0cf6485261c4a0dc894f4ab844c6cdfb97cd0b60ffb5018ffd62"
             "38f4d87270efb1d3ae37079b794a92d7ec95ffffffffd669f7d7958d40fc59d225"
             "3d88e0f248e29b599c80bbcec344a83dda5f9aa72c000000008a47304402207812"
             "4c8beeaa825f9e0b30bff96e564dd859432f2d0cb3b72d3d5d93d38d7e93022069"
             "1d233b6c0f995be5acb03d70a7f7a65b6bc9bdd426260f38a1346669507a360141"
             "0462bb73f76ca0994fcb8b4271e6fb7561f5c0f9ca0cf6485261c4a0dc894f4ab8"
             "44c6cdfb97cd0b60ffb5018ffd6238f4d87270efb1d3ae37079b794a92d7ec95ff"
             "fffffff878af0d93f5229a68166cf051fd372bb7a537232946e0a46f53636b4daf"
             "daa4000000008c493046022100c717d1714551663f69c3c5759bdbb3a0fcd3fab0"
             "23abc0e522fe6440de35d8290221008d9cbe25bffc44af2b18e81c58eb37293fd7"
             "fe1c2e7b46fc37ee8c96c50ab1e201410462bb73f76ca0994fcb8b4271e6fb7561"
             "f5c0f9ca0cf6485261c4a0dc894f4ab844c6cdfb97cd0b60ffb5018ffd6238f4d8"
             "7270efb1d3ae37079b794a92d7ec95ffffffff27f2b668859cd7f2f894aa0fd2d9"
             "e60963bcd07c88973f425f999b8cbfd7a1e2000000008c493046022100e0084714"
             "7cbf517bcc2f502f3ddc6d284358d102ed20d47a8aa788a62f0db780022100d17b"
             "2d6fa84dcaf1c95d88d7e7c30385aecf415588d749afd3ec81f6022cecd7014104"
             "62bb73f76ca0994fcb8b4271e6fb7561f5c0f9ca0cf6485261c4a0dc894f4ab844"
             "c6cdfb97cd0b60ffb5018ffd6238f4d87270efb1d3ae37079b794a92d7ec95ffff"
             "ffff0100c817a8040000001976a914b6efd80d99179f4f4ff6f4dd0a007d018c38"
             "5d2188ac000000000100000001834537b2f1ce8ef9373a258e10545ce5a50b758d"
             "f616cd4356e0032554ebd3c4000000008b483045022100e68f422dd7c34fdce11e"
             "eb4509ddae38201773dd62f284e8aa9d96f85099d0b002202243bd399ff96b649a"
             "0fad05fa759d6a882f0af8c90cf7632c2840c29070aec20141045e58067e815c2f"
             "464c6a2a15f987758374203895710c2d452442e28496ff38ba8f5fd901dc20e29e"
             "88477167fe4fc299bf818fd0d9e1632d467b2a3d9503b1aaffffffff0280d7e636"
             "030000001976a914f34c3e10eb387efe872acb614c89e78bfca7815d88ac404b4c"
             "00000000001976a914a84e272933aaf87e1715d7786c51dfaeb5b65a6f88ac0000"
             "0000010000000143ac81c8e6f6ef307dfe17f3d906d999e23e0189fda838c5510d"
             "850927e03ae7000000008c4930460221009c87c344760a64cb8ae6685a3eec2c1a"
             "c1bed5b88c87de51acd0e124f266c16602210082d07c037359c3a257b5c63ebd90"
             "f5a5edf97b2ac1c434b08ca998839f346dd40141040ba7e521fa7946d12edbb1d1"
             "e95a15c34bd4398195e86433c92b431cd315f455fe30032ede69cad9d1e1ed6c3c"
             "4ec0dbfced53438c625462afb792dcb098544bffffffff0240420f000000000019"
             "76a9144676d1b820d63ec272f1900d59d43bc6463d96f888ac40420f0000000000"
             "1976a914648d04341d00d7968b3405c034adc38d4d8fb9bd88ac00000000010000"
             "000248cc917501ea5c55f4a8d2009c0567c40cfe037c2e71af017d0a452ff705e3"
             "f1000000008b483045022100bf5fdc86dc5f08a5d5c8e43a8c9d5b1ed8c65562e2"
             "80007b52b133021acd9acc02205e325d613e555f772802bf413d36ba807892ed1a"
             "690a77811d3033b3de226e0a01410429fa713b124484cb2bd7b5557b2c0b9df7b2"
             "b1fee61825eadc5ae6c37a9920d38bfccdc7dc3cb0c47d7b173dbc9db8d37db0a3"
             "3ae487982c59c6f8606e9d1791ffffffff41ed70551dd7e841883ab8f0b16bf041"
             "76b7d1480e4f0af9f3d4c3595768d068000000008b4830450221008513ad65187b"
             "903aed1102d1d0c47688127658c51106753fed0151ce9c16b80902201432b9ebcb"
             "87bd04ceb2de66035fbbaf4bf8b00d1cfe41f1a1f7338f9ad79d210141049d4cf8"
             "0125bf50be1709f718c07ad15d0fc612b7da1f5570dddc35f2a352f0f27c978b06"
             "820edca9ef982c35fda2d255afba340068c5035552368bc7200c1488ffffffff01"
             "00093d00000000001976a9148edb68822f1ad580b043c7b3df2e400f8699eb4888"
             "ac00000000"),
         SER_NETWORK, PROTOCOL_VERSION);
     stream >> block;
 
     CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_NONE);
     // Match the generation pubkey
     filter.insert(ParseHex("04eaafc2314def4ca98ac970241bcab022b9c1e1f4ea423a20f"
                            "134c876f2c01ec0f0dd5b2e86e7168cefe0d81113c3807420ce"
                            "13ad1357231a2252247d97a46a91"));
     // ...and the output address of the 4th transaction
     filter.insert(ParseHex("b6efd80d99179f4f4ff6f4dd0a007d018c385d21"));
 
     CMerkleBlock merkleBlock(block, filter);
     BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
 
     // We shouldn't match any outpoints (UPDATE_NONE)
     BOOST_CHECK(
         !filter.contains(COutPoint(uint256S("0x147caa76786596590baa4e98f5d9f48b"
                                             "86c7765e489f7a6ff3360fe5c674360b"),
                                    0)));
     BOOST_CHECK(
         !filter.contains(COutPoint(uint256S("0x02981fa052f0481dbc5868f4fc216603"
                                             "5a10f27a03cfd2de67326471df5bc041"),
                                    0)));
 }
 
-static std::vector<unsigned char> RandomData() {
+static std::vector<uint8_t> RandomData() {
     uint256 r = GetRandHash();
-    return std::vector<unsigned char>(r.begin(), r.end());
+    return std::vector<uint8_t>(r.begin(), r.end());
 }
 
 BOOST_AUTO_TEST_CASE(rolling_bloom) {
     // last-100-entry, 1% false positive:
     CRollingBloomFilter rb1(100, 0.01);
 
     // Overfill:
     static const int DATASIZE = 399;
-    std::vector<unsigned char> data[DATASIZE];
+    std::vector<uint8_t> data[DATASIZE];
     for (int i = 0; i < DATASIZE; i++) {
         data[i] = RandomData();
         rb1.insert(data[i]);
     }
     // Last 100 guaranteed to be remembered:
     for (int i = 299; i < DATASIZE; i++) {
         BOOST_CHECK(rb1.contains(data[i]));
     }
 
     // false positive rate is 1%, so we should get about 100 hits if
     // testing 10,000 random keys. We get worst-case false positive
     // behavior when the filter is as full as possible, which is
     // when we've inserted one minus an integer multiple of nElement*2.
     unsigned int nHits = 0;
     for (int i = 0; i < 10000; i++) {
         if (rb1.contains(RandomData())) ++nHits;
     }
     // Run test_bitcoin with --log_level=message to see BOOST_TEST_MESSAGEs:
     BOOST_TEST_MESSAGE("RollingBloomFilter got "
                        << nHits << " false positives (~100 expected)");
 
     // Insanely unlikely to get a fp count outside this range:
     BOOST_CHECK(nHits > 25);
     BOOST_CHECK(nHits < 175);
 
     BOOST_CHECK(rb1.contains(data[DATASIZE - 1]));
     rb1.reset();
     BOOST_CHECK(!rb1.contains(data[DATASIZE - 1]));
 
     // Now roll through data, make sure last 100 entries
     // are always remembered:
     for (int i = 0; i < DATASIZE; i++) {
         if (i >= 100) BOOST_CHECK(rb1.contains(data[i - 100]));
         rb1.insert(data[i]);
         BOOST_CHECK(rb1.contains(data[i]));
     }
 
     // Insert 999 more random entries:
     for (int i = 0; i < 999; i++) {
-        std::vector<unsigned char> d = RandomData();
+        std::vector<uint8_t> d = RandomData();
         rb1.insert(d);
         BOOST_CHECK(rb1.contains(d));
     }
     // Sanity check to make sure the filter isn't just filling up:
     nHits = 0;
     for (int i = 0; i < DATASIZE; i++) {
         if (rb1.contains(data[i])) ++nHits;
     }
     // Expect about 5 false positives, more than 100 means
     // something is definitely broken.
     BOOST_TEST_MESSAGE("RollingBloomFilter got "
                        << nHits << " false positives (~5 expected)");
     BOOST_CHECK(nHits < 100);
 
     // last-1000-entry, 0.01% false positive:
     CRollingBloomFilter rb2(1000, 0.001);
     for (int i = 0; i < DATASIZE; i++) {
         rb2.insert(data[i]);
     }
     // ... room for all of them:
     for (int i = 0; i < DATASIZE; i++) {
         BOOST_CHECK(rb2.contains(data[i]));
     }
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp
index a1347f522..1f4e46a1a 100644
--- a/src/test/crypto_tests.cpp
+++ b/src/test/crypto_tests.cpp
@@ -1,556 +1,554 @@
 // Copyright (c) 2014-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.
 
 #include "crypto/aes.h"
 #include "crypto/hmac_sha256.h"
 #include "crypto/hmac_sha512.h"
 #include "crypto/ripemd160.h"
 #include "crypto/sha1.h"
 #include "crypto/sha256.h"
 #include "crypto/sha512.h"
 #include "test/test_bitcoin.h"
 #include "test/test_random.h"
 #include "utilstrencodings.h"
 
 #include <vector>
 
 #include <boost/assign/list_of.hpp>
 #include <boost/test/unit_test.hpp>
 #include <openssl/aes.h>
 #include <openssl/evp.h>
 
 BOOST_FIXTURE_TEST_SUITE(crypto_tests, BasicTestingSetup)
 
 template <typename Hasher, typename In, typename Out>
 void TestVector(const Hasher &h, const In &in, const Out &out) {
     Out hash;
     BOOST_CHECK(out.size() == h.OUTPUT_SIZE);
     hash.resize(out.size());
     {
         // Test that writing the whole input string at once works.
-        Hasher(h).Write((unsigned char *)&in[0], in.size()).Finalize(&hash[0]);
+        Hasher(h).Write((uint8_t *)&in[0], in.size()).Finalize(&hash[0]);
         BOOST_CHECK(hash == out);
     }
     for (int i = 0; i < 32; i++) {
         // Test that writing the string broken up in random pieces works.
         Hasher hasher(h);
         size_t pos = 0;
         while (pos < in.size()) {
             size_t len = insecure_rand() % ((in.size() - pos + 1) / 2 + 1);
-            hasher.Write((unsigned char *)&in[pos], len);
+            hasher.Write((uint8_t *)&in[pos], len);
             pos += len;
             if (pos > 0 && pos + 2 * out.size() > in.size() &&
                 pos < in.size()) {
                 // Test that writing the rest at once to a copy of a hasher
                 // works.
                 Hasher(hasher)
-                    .Write((unsigned char *)&in[pos], in.size() - pos)
+                    .Write((uint8_t *)&in[pos], in.size() - pos)
                     .Finalize(&hash[0]);
                 BOOST_CHECK(hash == out);
             }
         }
         hasher.Finalize(&hash[0]);
         BOOST_CHECK(hash == out);
     }
 }
 
 void TestSHA1(const std::string &in, const std::string &hexout) {
     TestVector(CSHA1(), in, ParseHex(hexout));
 }
 void TestSHA256(const std::string &in, const std::string &hexout) {
     TestVector(CSHA256(), in, ParseHex(hexout));
 }
 void TestSHA512(const std::string &in, const std::string &hexout) {
     TestVector(CSHA512(), in, ParseHex(hexout));
 }
 void TestRIPEMD160(const std::string &in, const std::string &hexout) {
     TestVector(CRIPEMD160(), in, ParseHex(hexout));
 }
 
 void TestHMACSHA256(const std::string &hexkey, const std::string &hexin,
                     const std::string &hexout) {
-    std::vector<unsigned char> key = ParseHex(hexkey);
+    std::vector<uint8_t> key = ParseHex(hexkey);
     TestVector(CHMAC_SHA256(&key[0], key.size()), ParseHex(hexin),
                ParseHex(hexout));
 }
 
 void TestHMACSHA512(const std::string &hexkey, const std::string &hexin,
                     const std::string &hexout) {
-    std::vector<unsigned char> key = ParseHex(hexkey);
+    std::vector<uint8_t> key = ParseHex(hexkey);
     TestVector(CHMAC_SHA512(&key[0], key.size()), ParseHex(hexin),
                ParseHex(hexout));
 }
 
 void TestAES128(const std::string &hexkey, const std::string &hexin,
                 const std::string &hexout) {
-    std::vector<unsigned char> key = ParseHex(hexkey);
-    std::vector<unsigned char> in = ParseHex(hexin);
-    std::vector<unsigned char> correctout = ParseHex(hexout);
-    std::vector<unsigned char> buf, buf2;
+    std::vector<uint8_t> key = ParseHex(hexkey);
+    std::vector<uint8_t> in = ParseHex(hexin);
+    std::vector<uint8_t> correctout = ParseHex(hexout);
+    std::vector<uint8_t> buf, buf2;
 
     assert(key.size() == 16);
     assert(in.size() == 16);
     assert(correctout.size() == 16);
     AES128Encrypt enc(&key[0]);
     buf.resize(correctout.size());
     buf2.resize(correctout.size());
     enc.Encrypt(&buf[0], &in[0]);
     BOOST_CHECK_EQUAL(HexStr(buf), HexStr(correctout));
     AES128Decrypt dec(&key[0]);
     dec.Decrypt(&buf2[0], &buf[0]);
     BOOST_CHECK_EQUAL(HexStr(buf2), HexStr(in));
 }
 
 void TestAES256(const std::string &hexkey, const std::string &hexin,
                 const std::string &hexout) {
-    std::vector<unsigned char> key = ParseHex(hexkey);
-    std::vector<unsigned char> in = ParseHex(hexin);
-    std::vector<unsigned char> correctout = ParseHex(hexout);
-    std::vector<unsigned char> buf;
+    std::vector<uint8_t> key = ParseHex(hexkey);
+    std::vector<uint8_t> in = ParseHex(hexin);
+    std::vector<uint8_t> correctout = ParseHex(hexout);
+    std::vector<uint8_t> buf;
 
     assert(key.size() == 32);
     assert(in.size() == 16);
     assert(correctout.size() == 16);
     AES256Encrypt enc(&key[0]);
     buf.resize(correctout.size());
     enc.Encrypt(&buf[0], &in[0]);
     BOOST_CHECK(buf == correctout);
     AES256Decrypt dec(&key[0]);
     dec.Decrypt(&buf[0], &buf[0]);
     BOOST_CHECK(buf == in);
 }
 
 void TestAES128CBC(const std::string &hexkey, const std::string &hexiv,
                    bool pad, const std::string &hexin,
                    const std::string &hexout) {
-    std::vector<unsigned char> key = ParseHex(hexkey);
-    std::vector<unsigned char> iv = ParseHex(hexiv);
-    std::vector<unsigned char> in = ParseHex(hexin);
-    std::vector<unsigned char> correctout = ParseHex(hexout);
-    std::vector<unsigned char> realout(in.size() + AES_BLOCKSIZE);
+    std::vector<uint8_t> key = ParseHex(hexkey);
+    std::vector<uint8_t> iv = ParseHex(hexiv);
+    std::vector<uint8_t> in = ParseHex(hexin);
+    std::vector<uint8_t> correctout = ParseHex(hexout);
+    std::vector<uint8_t> realout(in.size() + AES_BLOCKSIZE);
 
     // Encrypt the plaintext and verify that it equals the cipher
     AES128CBCEncrypt enc(&key[0], &iv[0], pad);
     int size = enc.Encrypt(&in[0], in.size(), &realout[0]);
     realout.resize(size);
     BOOST_CHECK(realout.size() == correctout.size());
     BOOST_CHECK_MESSAGE(realout == correctout,
                         HexStr(realout) + std::string(" != ") + hexout);
 
     // Decrypt the cipher and verify that it equals the plaintext
-    std::vector<unsigned char> decrypted(correctout.size());
+    std::vector<uint8_t> decrypted(correctout.size());
     AES128CBCDecrypt dec(&key[0], &iv[0], pad);
     size = dec.Decrypt(&correctout[0], correctout.size(), &decrypted[0]);
     decrypted.resize(size);
     BOOST_CHECK(decrypted.size() == in.size());
     BOOST_CHECK_MESSAGE(decrypted == in,
                         HexStr(decrypted) + std::string(" != ") + hexin);
 
     // Encrypt and re-decrypt substrings of the plaintext and verify that they
     // equal each-other
-    for (std::vector<unsigned char>::iterator i(in.begin()); i != in.end();
-         ++i) {
-        std::vector<unsigned char> sub(i, in.end());
-        std::vector<unsigned char> subout(sub.size() + AES_BLOCKSIZE);
+    for (std::vector<uint8_t>::iterator i(in.begin()); i != in.end(); ++i) {
+        std::vector<uint8_t> sub(i, in.end());
+        std::vector<uint8_t> subout(sub.size() + AES_BLOCKSIZE);
         int _size = enc.Encrypt(&sub[0], sub.size(), &subout[0]);
         if (_size != 0) {
             subout.resize(_size);
-            std::vector<unsigned char> subdecrypted(subout.size());
+            std::vector<uint8_t> subdecrypted(subout.size());
             _size = dec.Decrypt(&subout[0], subout.size(), &subdecrypted[0]);
             subdecrypted.resize(_size);
             BOOST_CHECK(decrypted.size() == in.size());
             BOOST_CHECK_MESSAGE(subdecrypted == sub, HexStr(subdecrypted) +
                                                          std::string(" != ") +
                                                          HexStr(sub));
         }
     }
 }
 
 void TestAES256CBC(const std::string &hexkey, const std::string &hexiv,
                    bool pad, const std::string &hexin,
                    const std::string &hexout) {
-    std::vector<unsigned char> key = ParseHex(hexkey);
-    std::vector<unsigned char> iv = ParseHex(hexiv);
-    std::vector<unsigned char> in = ParseHex(hexin);
-    std::vector<unsigned char> correctout = ParseHex(hexout);
-    std::vector<unsigned char> realout(in.size() + AES_BLOCKSIZE);
+    std::vector<uint8_t> key = ParseHex(hexkey);
+    std::vector<uint8_t> iv = ParseHex(hexiv);
+    std::vector<uint8_t> in = ParseHex(hexin);
+    std::vector<uint8_t> correctout = ParseHex(hexout);
+    std::vector<uint8_t> realout(in.size() + AES_BLOCKSIZE);
 
     // Encrypt the plaintext and verify that it equals the cipher
     AES256CBCEncrypt enc(&key[0], &iv[0], pad);
     int size = enc.Encrypt(&in[0], in.size(), &realout[0]);
     realout.resize(size);
     BOOST_CHECK(realout.size() == correctout.size());
     BOOST_CHECK_MESSAGE(realout == correctout,
                         HexStr(realout) + std::string(" != ") + hexout);
 
     // Decrypt the cipher and verify that it equals the plaintext
-    std::vector<unsigned char> decrypted(correctout.size());
+    std::vector<uint8_t> decrypted(correctout.size());
     AES256CBCDecrypt dec(&key[0], &iv[0], pad);
     size = dec.Decrypt(&correctout[0], correctout.size(), &decrypted[0]);
     decrypted.resize(size);
     BOOST_CHECK(decrypted.size() == in.size());
     BOOST_CHECK_MESSAGE(decrypted == in,
                         HexStr(decrypted) + std::string(" != ") + hexin);
 
     // Encrypt and re-decrypt substrings of the plaintext and verify that they
     // equal each-other
-    for (std::vector<unsigned char>::iterator i(in.begin()); i != in.end();
-         ++i) {
-        std::vector<unsigned char> sub(i, in.end());
-        std::vector<unsigned char> subout(sub.size() + AES_BLOCKSIZE);
+    for (std::vector<uint8_t>::iterator i(in.begin()); i != in.end(); ++i) {
+        std::vector<uint8_t> sub(i, in.end());
+        std::vector<uint8_t> subout(sub.size() + AES_BLOCKSIZE);
         int _size = enc.Encrypt(&sub[0], sub.size(), &subout[0]);
         if (_size != 0) {
             subout.resize(_size);
-            std::vector<unsigned char> subdecrypted(subout.size());
+            std::vector<uint8_t> subdecrypted(subout.size());
             _size = dec.Decrypt(&subout[0], subout.size(), &subdecrypted[0]);
             subdecrypted.resize(_size);
             BOOST_CHECK(decrypted.size() == in.size());
             BOOST_CHECK_MESSAGE(subdecrypted == sub, HexStr(subdecrypted) +
                                                          std::string(" != ") +
                                                          HexStr(sub));
         }
     }
 }
 
 std::string LongTestString(void) {
     std::string ret;
     for (int i = 0; i < 200000; i++) {
-        ret += (unsigned char)(i);
-        ret += (unsigned char)(i >> 4);
-        ret += (unsigned char)(i >> 8);
-        ret += (unsigned char)(i >> 12);
-        ret += (unsigned char)(i >> 16);
+        ret += uint8_t(i);
+        ret += uint8_t(i >> 4);
+        ret += uint8_t(i >> 8);
+        ret += uint8_t(i >> 12);
+        ret += uint8_t(i >> 16);
     }
     return ret;
 }
 
 const std::string test1 = LongTestString();
 
 BOOST_AUTO_TEST_CASE(ripemd160_testvectors) {
     TestRIPEMD160("", "9c1185a5c5e9fc54612808977ee8f548b2258d31");
     TestRIPEMD160("abc", "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc");
     TestRIPEMD160("message digest", "5d0689ef49d2fae572b881b123a85ffa21595f36");
     TestRIPEMD160("secure hash algorithm",
                   "20397528223b6a5f4cbc2808aba0464e645544f9");
     TestRIPEMD160("RIPEMD160 is considered to be safe",
                   "a7d78608c7af8a8e728778e81576870734122b66");
     TestRIPEMD160("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
                   "12a053384a9c0c88e405a06c27dcf49ada62eb2b");
     TestRIPEMD160(
         "For this sample, this 63-byte string will be used as input data",
         "de90dbfee14b63fb5abf27c2ad4a82aaa5f27a11");
     TestRIPEMD160(
         "This is exactly 64 bytes long, not counting the terminating byte",
         "eda31d51d3a623b81e19eb02e24ff65d27d67b37");
     TestRIPEMD160(std::string(1000000, 'a'),
                   "52783243c1697bdbe16d37f97f68f08325dc1528");
     TestRIPEMD160(test1, "464243587bd146ea835cdf57bdae582f25ec45f1");
 }
 
 BOOST_AUTO_TEST_CASE(sha1_testvectors) {
     TestSHA1("", "da39a3ee5e6b4b0d3255bfef95601890afd80709");
     TestSHA1("abc", "a9993e364706816aba3e25717850c26c9cd0d89d");
     TestSHA1("message digest", "c12252ceda8be8994d5fa0290a47231c1d16aae3");
     TestSHA1("secure hash algorithm",
              "d4d6d2f0ebe317513bbd8d967d89bac5819c2f60");
     TestSHA1("SHA1 is considered to be safe",
              "f2b6650569ad3a8720348dd6ea6c497dee3a842a");
     TestSHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
              "84983e441c3bd26ebaae4aa1f95129e5e54670f1");
     TestSHA1("For this sample, this 63-byte string will be used as input data",
              "4f0ea5cd0585a23d028abdc1a6684e5a8094dc49");
     TestSHA1("This is exactly 64 bytes long, not counting the terminating byte",
              "fb679f23e7d1ce053313e66e127ab1b444397057");
     TestSHA1(std::string(1000000, 'a'),
              "34aa973cd4c4daa4f61eeb2bdbad27316534016f");
     TestSHA1(test1, "b7755760681cbfd971451668f32af5774f4656b5");
 }
 
 BOOST_AUTO_TEST_CASE(sha256_testvectors) {
     TestSHA256(
         "", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
     TestSHA256(
         "abc",
         "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad");
     TestSHA256(
         "message digest",
         "f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650");
     TestSHA256(
         "secure hash algorithm",
         "f30ceb2bb2829e79e4ca9753d35a8ecc00262d164cc077080295381cbd643f0d");
     TestSHA256(
         "SHA256 is considered to be safe",
         "6819d915c73f4d1e77e4e1b52d1fa0f9cf9beaead3939f15874bd988e2a23630");
     TestSHA256(
         "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
         "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1");
     TestSHA256(
         "For this sample, this 63-byte string will be used as input data",
         "f08a78cbbaee082b052ae0708f32fa1e50c5c421aa772ba5dbb406a2ea6be342");
     TestSHA256(
         "This is exactly 64 bytes long, not counting the terminating byte",
         "ab64eff7e88e2e46165e29f2bce41826bd4c7b3552f6b382a9e7d3af47c245f8");
     TestSHA256(
         "As Bitcoin relies on 80 byte header hashes, we want to have an "
         "example for that.",
         "7406e8de7d6e4fffc573daef05aefb8806e7790f55eab5576f31349743cca743");
     TestSHA256(
         std::string(1000000, 'a'),
         "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0");
     TestSHA256(
         test1,
         "a316d55510b49662420f49d145d42fb83f31ef8dc016aa4e32df049991a91e26");
 }
 
 BOOST_AUTO_TEST_CASE(sha512_testvectors) {
     TestSHA512(
         "", "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce"
             "47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e");
     TestSHA512(
         "abc",
         "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"
         "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f");
     TestSHA512(
         "message digest",
         "107dbf389d9e9f71a3a95f6c055b9251bc5268c2be16d6c13492ea45b0199f33"
         "09e16455ab1e96118e8a905d5597b72038ddb372a89826046de66687bb420e7c");
     TestSHA512(
         "secure hash algorithm",
         "7746d91f3de30c68cec0dd693120a7e8b04d8073cb699bdce1a3f64127bca7a3"
         "d5db502e814bb63c063a7a5043b2df87c61133395f4ad1edca7fcf4b30c3236e");
     TestSHA512(
         "SHA512 is considered to be safe",
         "099e6468d889e1c79092a89ae925a9499b5408e01b66cb5b0a3bd0dfa51a9964"
         "6b4a3901caab1318189f74cd8cf2e941829012f2449df52067d3dd5b978456c2");
     TestSHA512(
         "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
         "204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c335"
         "96fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445");
     TestSHA512(
         "For this sample, this 63-byte string will be used as input data",
         "b3de4afbc516d2478fe9b518d063bda6c8dd65fc38402dd81d1eb7364e72fb6e"
         "6663cf6d2771c8f5a6da09601712fb3d2a36c6ffea3e28b0818b05b0a8660766");
     TestSHA512(
         "This is exactly 64 bytes long, not counting the terminating byte",
         "70aefeaa0e7ac4f8fe17532d7185a289bee3b428d950c14fa8b713ca09814a38"
         "7d245870e007a80ad97c369d193e41701aa07f3221d15f0e65a1ff970cedf030");
     TestSHA512(
         "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno"
         "ijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
         "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018"
         "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909");
     TestSHA512(
         std::string(1000000, 'a'),
         "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb"
         "de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b");
     TestSHA512(
         test1,
         "40cac46c147e6131c5193dd5f34e9d8bb4951395f27b08c558c65ff4ba2de594"
         "37de8c3ef5459d76a52cedc02dc499a3c9ed9dedbfb3281afd9653b8a112fafc");
 }
 
 BOOST_AUTO_TEST_CASE(hmac_sha256_testvectors) {
     // test cases 1, 2, 3, 4, 6 and 7 of RFC 4231
     TestHMACSHA256(
         "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "4869205468657265",
         "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7");
     TestHMACSHA256(
         "4a656665", "7768617420646f2079612077616e7420666f72206e6f7468696e673f",
         "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843");
     TestHMACSHA256(
         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
         "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
         "dddddddddddddddddddddddddddddddddddd",
         "773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe");
     TestHMACSHA256(
         "0102030405060708090a0b0c0d0e0f10111213141516171819",
         "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
         "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
         "82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b");
     TestHMACSHA256(
         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
         "aaaaaa",
         "54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a"
         "65204b6579202d2048617368204b6579204669727374",
         "60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54");
     TestHMACSHA256(
         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
         "aaaaaa",
         "5468697320697320612074657374207573696e672061206c6172676572207468"
         "616e20626c6f636b2d73697a65206b657920616e642061206c61726765722074"
         "68616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565"
         "647320746f20626520686173686564206265666f7265206265696e6720757365"
         "642062792074686520484d414320616c676f726974686d2e",
         "9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2");
 }
 
 BOOST_AUTO_TEST_CASE(hmac_sha512_testvectors) {
     // test cases 1, 2, 3, 4, 6 and 7 of RFC 4231
     TestHMACSHA512(
         "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "4869205468657265",
         "87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cde"
         "daa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854");
     TestHMACSHA512(
         "4a656665", "7768617420646f2079612077616e7420666f72206e6f7468696e673f",
         "164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea250554"
         "9758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737");
     TestHMACSHA512(
         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
         "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
         "dddddddddddddddddddddddddddddddddddd",
         "fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39"
         "bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb");
     TestHMACSHA512(
         "0102030405060708090a0b0c0d0e0f10111213141516171819",
         "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
         "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
         "b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050361ee3db"
         "a91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2de2adebeb10a298dd");
     TestHMACSHA512(
         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
         "aaaaaa",
         "54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a"
         "65204b6579202d2048617368204b6579204669727374",
         "80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b013783f8f352"
         "6b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec8b915a985d786598");
     TestHMACSHA512(
         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
         "aaaaaa",
         "5468697320697320612074657374207573696e672061206c6172676572207468"
         "616e20626c6f636b2d73697a65206b657920616e642061206c61726765722074"
         "68616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565"
         "647320746f20626520686173686564206265666f7265206265696e6720757365"
         "642062792074686520484d414320616c676f726974686d2e",
         "e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d20cdc944"
         "b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58");
 }
 
 BOOST_AUTO_TEST_CASE(aes_testvectors) {
     // AES test vectors from FIPS 197.
     TestAES128("000102030405060708090a0b0c0d0e0f",
                "00112233445566778899aabbccddeeff",
                "69c4e0d86a7b0430d8cdb78070b4c55a");
     TestAES256(
         "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
         "00112233445566778899aabbccddeeff", "8ea2b7ca516745bfeafc49904b496089");
 
     // AES-ECB test vectors from NIST sp800-38a.
     TestAES128("2b7e151628aed2a6abf7158809cf4f3c",
                "6bc1bee22e409f96e93d7e117393172a",
                "3ad77bb40d7a3660a89ecaf32466ef97");
     TestAES128("2b7e151628aed2a6abf7158809cf4f3c",
                "ae2d8a571e03ac9c9eb76fac45af8e51",
                "f5d3d58503b9699de785895a96fdbaaf");
     TestAES128("2b7e151628aed2a6abf7158809cf4f3c",
                "30c81c46a35ce411e5fbc1191a0a52ef",
                "43b1cd7f598ece23881b00e3ed030688");
     TestAES128("2b7e151628aed2a6abf7158809cf4f3c",
                "f69f2445df4f9b17ad2b417be66c3710",
                "7b0c785e27e8ad3f8223207104725dd4");
     TestAES256(
         "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
         "6bc1bee22e409f96e93d7e117393172a", "f3eed1bdb5d2a03c064b5a7e3db181f8");
     TestAES256(
         "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
         "ae2d8a571e03ac9c9eb76fac45af8e51", "591ccb10d410ed26dc5ba74a31362870");
     TestAES256(
         "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
         "30c81c46a35ce411e5fbc1191a0a52ef", "b6ed21b99ca6f4f9f153e7b1beafed1d");
     TestAES256(
         "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
         "f69f2445df4f9b17ad2b417be66c3710", "23304b7a39f9f3ff067d8d8f9e24ecc7");
 }
 
 BOOST_AUTO_TEST_CASE(aes_cbc_testvectors) {
 
     // NIST AES CBC 128-bit encryption test-vectors
     TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c",
                   "000102030405060708090A0B0C0D0E0F", false,
                   "6bc1bee22e409f96e93d7e117393172a",
                   "7649abac8119b246cee98e9b12e9197d");
     TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c",
                   "7649ABAC8119B246CEE98E9B12E9197D", false,
                   "ae2d8a571e03ac9c9eb76fac45af8e51",
                   "5086cb9b507219ee95db113a917678b2");
     TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c",
                   "5086cb9b507219ee95db113a917678b2", false,
                   "30c81c46a35ce411e5fbc1191a0a52ef",
                   "73bed6b8e3c1743b7116e69e22229516");
     TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c",
                   "73bed6b8e3c1743b7116e69e22229516", false,
                   "f69f2445df4f9b17ad2b417be66c3710",
                   "3ff1caa1681fac09120eca307586e1a7");
 
     // The same vectors with padding enabled
     TestAES128CBC(
         "2b7e151628aed2a6abf7158809cf4f3c", "000102030405060708090A0B0C0D0E0F",
         true, "6bc1bee22e409f96e93d7e117393172a",
         "7649abac8119b246cee98e9b12e9197d8964e0b149c10b7b682e6e39aaeb731c");
     TestAES128CBC(
         "2b7e151628aed2a6abf7158809cf4f3c", "7649ABAC8119B246CEE98E9B12E9197D",
         true, "ae2d8a571e03ac9c9eb76fac45af8e51",
         "5086cb9b507219ee95db113a917678b255e21d7100b988ffec32feeafaf23538");
     TestAES128CBC(
         "2b7e151628aed2a6abf7158809cf4f3c", "5086cb9b507219ee95db113a917678b2",
         true, "30c81c46a35ce411e5fbc1191a0a52ef",
         "73bed6b8e3c1743b7116e69e22229516f6eccda327bf8e5ec43718b0039adceb");
     TestAES128CBC(
         "2b7e151628aed2a6abf7158809cf4f3c", "73bed6b8e3c1743b7116e69e22229516",
         true, "f69f2445df4f9b17ad2b417be66c3710",
         "3ff1caa1681fac09120eca307586e1a78cb82807230e1321d3fae00d18cc2012");
 
     // NIST AES CBC 256-bit encryption test-vectors
     TestAES256CBC(
         "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
         "000102030405060708090A0B0C0D0E0F", false,
         "6bc1bee22e409f96e93d7e117393172a", "f58c4c04d6e5f1ba779eabfb5f7bfbd6");
     TestAES256CBC(
         "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
         "F58C4C04D6E5F1BA779EABFB5F7BFBD6", false,
         "ae2d8a571e03ac9c9eb76fac45af8e51", "9cfc4e967edb808d679f777bc6702c7d");
     TestAES256CBC(
         "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
         "9CFC4E967EDB808D679F777BC6702C7D", false,
         "30c81c46a35ce411e5fbc1191a0a52ef", "39f23369a9d9bacfa530e26304231461");
     TestAES256CBC(
         "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
         "39F23369A9D9BACFA530E26304231461", false,
         "f69f2445df4f9b17ad2b417be66c3710", "b2eb05e2c39be9fcda6c19078c6a9d1b");
 
     // The same vectors with padding enabled
     TestAES256CBC(
         "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
         "000102030405060708090A0B0C0D0E0F", true,
         "6bc1bee22e409f96e93d7e117393172a",
         "f58c4c04d6e5f1ba779eabfb5f7bfbd6485a5c81519cf378fa36d42b8547edc0");
     TestAES256CBC(
         "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
         "F58C4C04D6E5F1BA779EABFB5F7BFBD6", true,
         "ae2d8a571e03ac9c9eb76fac45af8e51",
         "9cfc4e967edb808d679f777bc6702c7d3a3aa5e0213db1a9901f9036cf5102d2");
     TestAES256CBC(
         "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
         "9CFC4E967EDB808D679F777BC6702C7D", true,
         "30c81c46a35ce411e5fbc1191a0a52ef",
         "39f23369a9d9bacfa530e263042314612f8da707643c90a6f732b3de1d3f5cee");
     TestAES256CBC(
         "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
         "39F23369A9D9BACFA530E26304231461", true,
         "f69f2445df4f9b17ad2b417be66c3710",
         "b2eb05e2c39be9fcda6c19078c6a9d1b3f461796d6b0d6b2e0c2a72b4d80e644");
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp
index d1d4c9913..9f0eef853 100644
--- a/src/test/dbwrapper_tests.cpp
+++ b/src/test/dbwrapper_tests.cpp
@@ -1,331 +1,331 @@
 // Copyright (c) 2012-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.
 
 #include "dbwrapper.h"
 #include "random.h"
 #include "test/test_bitcoin.h"
 #include "uint256.h"
 
 #include <boost/assert.hpp>
 #include <boost/assign/std/vector.hpp> // for 'operator+=()'
 #include <boost/test/unit_test.hpp>
 
 // Test if a string consists entirely of null characters
-bool is_null_key(const std::vector<unsigned char> &key) {
+bool is_null_key(const std::vector<uint8_t> &key) {
     bool isnull = true;
 
     for (unsigned int i = 0; i < key.size(); i++)
         isnull &= (key[i] == '\x00');
 
     return isnull;
 }
 
 BOOST_FIXTURE_TEST_SUITE(dbwrapper_tests, BasicTestingSetup)
 
 BOOST_AUTO_TEST_CASE(dbwrapper) {
     // Perform tests both obfuscated and non-obfuscated.
     for (int i = 0; i < 2; i++) {
         bool obfuscate = (bool)i;
         boost::filesystem::path ph = boost::filesystem::temp_directory_path() /
                                      boost::filesystem::unique_path();
         CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate);
         char key = 'k';
         uint256 in = GetRandHash();
         uint256 res;
 
         // Ensure that we're doing real obfuscation when obfuscate=true
         BOOST_CHECK(obfuscate !=
                     is_null_key(dbwrapper_private::GetObfuscateKey(dbw)));
 
         BOOST_CHECK(dbw.Write(key, in));
         BOOST_CHECK(dbw.Read(key, res));
         BOOST_CHECK_EQUAL(res.ToString(), in.ToString());
     }
 }
 
 // Test batch operations
 BOOST_AUTO_TEST_CASE(dbwrapper_batch) {
     // Perform tests both obfuscated and non-obfuscated.
     for (int i = 0; i < 2; i++) {
         bool obfuscate = (bool)i;
         boost::filesystem::path ph = boost::filesystem::temp_directory_path() /
                                      boost::filesystem::unique_path();
         CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate);
 
         char key = 'i';
         uint256 in = GetRandHash();
         char key2 = 'j';
         uint256 in2 = GetRandHash();
         char key3 = 'k';
         uint256 in3 = GetRandHash();
 
         uint256 res;
         CDBBatch batch(dbw);
 
         batch.Write(key, in);
         batch.Write(key2, in2);
         batch.Write(key3, in3);
 
         // Remove key3 before it's even been written
         batch.Erase(key3);
 
         dbw.WriteBatch(batch);
 
         BOOST_CHECK(dbw.Read(key, res));
         BOOST_CHECK_EQUAL(res.ToString(), in.ToString());
         BOOST_CHECK(dbw.Read(key2, res));
         BOOST_CHECK_EQUAL(res.ToString(), in2.ToString());
 
         // key3 should've never been written
         BOOST_CHECK(dbw.Read(key3, res) == false);
     }
 }
 
 BOOST_AUTO_TEST_CASE(dbwrapper_iterator) {
     // Perform tests both obfuscated and non-obfuscated.
     for (int i = 0; i < 2; i++) {
         bool obfuscate = (bool)i;
         boost::filesystem::path ph = boost::filesystem::temp_directory_path() /
                                      boost::filesystem::unique_path();
         CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate);
 
         // The two keys are intentionally chosen for ordering
         char key = 'j';
         uint256 in = GetRandHash();
         BOOST_CHECK(dbw.Write(key, in));
         char key2 = 'k';
         uint256 in2 = GetRandHash();
         BOOST_CHECK(dbw.Write(key2, in2));
 
         std::unique_ptr<CDBIterator> it(
             const_cast<CDBWrapper *>(&dbw)->NewIterator());
 
         // Be sure to seek past the obfuscation key (if it exists)
         it->Seek(key);
 
         char key_res;
         uint256 val_res;
 
         it->GetKey(key_res);
         it->GetValue(val_res);
         BOOST_CHECK_EQUAL(key_res, key);
         BOOST_CHECK_EQUAL(val_res.ToString(), in.ToString());
 
         it->Next();
 
         it->GetKey(key_res);
         it->GetValue(val_res);
         BOOST_CHECK_EQUAL(key_res, key2);
         BOOST_CHECK_EQUAL(val_res.ToString(), in2.ToString());
 
         it->Next();
         BOOST_CHECK_EQUAL(it->Valid(), false);
     }
 }
 
 // Test that we do not obfuscation if there is existing data.
 BOOST_AUTO_TEST_CASE(existing_data_no_obfuscate) {
     // We're going to share this boost::filesystem::path between two wrappers
     boost::filesystem::path ph = boost::filesystem::temp_directory_path() /
                                  boost::filesystem::unique_path();
     create_directories(ph);
 
     // Set up a non-obfuscated wrapper to write some initial data.
     CDBWrapper *dbw = new CDBWrapper(ph, (1 << 10), false, false, false);
     char key = 'k';
     uint256 in = GetRandHash();
     uint256 res;
 
     BOOST_CHECK(dbw->Write(key, in));
     BOOST_CHECK(dbw->Read(key, res));
     BOOST_CHECK_EQUAL(res.ToString(), in.ToString());
 
     // Call the destructor to free leveldb LOCK
     delete dbw;
 
     // Now, set up another wrapper that wants to obfuscate the same directory
     CDBWrapper odbw(ph, (1 << 10), false, false, true);
 
     // Check that the key/val we wrote with unobfuscated wrapper exists and
     // is readable.
     uint256 res2;
     BOOST_CHECK(odbw.Read(key, res2));
     BOOST_CHECK_EQUAL(res2.ToString(), in.ToString());
 
     // There should be existing data
     BOOST_CHECK(!odbw.IsEmpty());
     // The key should be an empty string
     BOOST_CHECK(is_null_key(dbwrapper_private::GetObfuscateKey(odbw)));
 
     uint256 in2 = GetRandHash();
     uint256 res3;
 
     // Check that we can write successfully
     BOOST_CHECK(odbw.Write(key, in2));
     BOOST_CHECK(odbw.Read(key, res3));
     BOOST_CHECK_EQUAL(res3.ToString(), in2.ToString());
 }
 
 // Ensure that we start obfuscating during a reindex.
 BOOST_AUTO_TEST_CASE(existing_data_reindex) {
     // We're going to share this boost::filesystem::path between two wrappers
     boost::filesystem::path ph = boost::filesystem::temp_directory_path() /
                                  boost::filesystem::unique_path();
     create_directories(ph);
 
     // Set up a non-obfuscated wrapper to write some initial data.
     CDBWrapper *dbw = new CDBWrapper(ph, (1 << 10), false, false, false);
     char key = 'k';
     uint256 in = GetRandHash();
     uint256 res;
 
     BOOST_CHECK(dbw->Write(key, in));
     BOOST_CHECK(dbw->Read(key, res));
     BOOST_CHECK_EQUAL(res.ToString(), in.ToString());
 
     // Call the destructor to free leveldb LOCK
     delete dbw;
 
     // Simulate a -reindex by wiping the existing data store
     CDBWrapper odbw(ph, (1 << 10), false, true, true);
 
     // Check that the key/val we wrote with unobfuscated wrapper doesn't exist
     uint256 res2;
     BOOST_CHECK(!odbw.Read(key, res2));
     BOOST_CHECK(!is_null_key(dbwrapper_private::GetObfuscateKey(odbw)));
 
     uint256 in2 = GetRandHash();
     uint256 res3;
 
     // Check that we can write successfully
     BOOST_CHECK(odbw.Write(key, in2));
     BOOST_CHECK(odbw.Read(key, res3));
     BOOST_CHECK_EQUAL(res3.ToString(), in2.ToString());
 }
 
 BOOST_AUTO_TEST_CASE(iterator_ordering) {
     boost::filesystem::path ph = boost::filesystem::temp_directory_path() /
                                  boost::filesystem::unique_path();
     CDBWrapper dbw(ph, (1 << 20), true, false, false);
     for (int x = 0x00; x < 256; ++x) {
         uint8_t key = x;
         uint32_t value = x * x;
         BOOST_CHECK(dbw.Write(key, value));
     }
 
     std::unique_ptr<CDBIterator> it(
         const_cast<CDBWrapper *>(&dbw)->NewIterator());
     for (int c = 0; c < 2; ++c) {
         int seek_start;
         if (c == 0)
             seek_start = 0x00;
         else
             seek_start = 0x80;
         it->Seek((uint8_t)seek_start);
         for (int x = seek_start; x < 256; ++x) {
             uint8_t key;
             uint32_t value;
             BOOST_CHECK(it->Valid());
             // Avoid spurious errors about invalid iterator's  key and value in
             // case of failure
             if (!it->Valid()) break;
             BOOST_CHECK(it->GetKey(key));
             BOOST_CHECK(it->GetValue(value));
             BOOST_CHECK_EQUAL(key, x);
             BOOST_CHECK_EQUAL(value, x * x);
             it->Next();
         }
         BOOST_CHECK(!it->Valid());
     }
 }
 
 struct StringContentsSerializer {
     // Used to make two serialized objects the same while letting them have a
     // different lengths. This is a terrible idea.
     std::string str;
     StringContentsSerializer() {}
     StringContentsSerializer(const std::string &inp) : str(inp) {}
 
     StringContentsSerializer &operator+=(const std::string &s) {
         str += s;
         return *this;
     }
     StringContentsSerializer &operator+=(const StringContentsSerializer &s) {
         return *this += s.str;
     }
 
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
     inline void SerializationOp(Stream &s, Operation ser_action) {
         if (ser_action.ForRead()) {
             str.clear();
             char c = 0;
             while (true) {
                 try {
                     READWRITE(c);
                     str.push_back(c);
                 } catch (const std::ios_base::failure &e) {
                     break;
                 }
             }
         } else {
             for (size_t i = 0; i < str.size(); i++)
                 READWRITE(str[i]);
         }
     }
 };
 
 BOOST_AUTO_TEST_CASE(iterator_string_ordering) {
     char buf[10];
 
     boost::filesystem::path ph = boost::filesystem::temp_directory_path() /
                                  boost::filesystem::unique_path();
     CDBWrapper dbw(ph, (1 << 20), true, false, false);
     for (int x = 0x00; x < 10; ++x) {
         for (int y = 0; y < 10; y++) {
             sprintf(buf, "%d", x);
             StringContentsSerializer key(buf);
             for (int z = 0; z < y; z++)
                 key += key;
             uint32_t value = x * x;
             BOOST_CHECK(dbw.Write(key, value));
         }
     }
 
     std::unique_ptr<CDBIterator> it(
         const_cast<CDBWrapper *>(&dbw)->NewIterator());
     for (int c = 0; c < 2; ++c) {
         int seek_start;
         if (c == 0)
             seek_start = 0;
         else
             seek_start = 5;
         sprintf(buf, "%d", seek_start);
         StringContentsSerializer seek_key(buf);
         it->Seek(seek_key);
         for (int x = seek_start; x < 10; ++x) {
             for (int y = 0; y < 10; y++) {
                 sprintf(buf, "%d", x);
                 std::string exp_key(buf);
                 for (int z = 0; z < y; z++)
                     exp_key += exp_key;
                 StringContentsSerializer key;
                 uint32_t value;
                 BOOST_CHECK(it->Valid());
                 // Avoid spurious errors about invalid iterator's key and value
                 // in case of failure
                 if (!it->Valid()) break;
                 BOOST_CHECK(it->GetKey(key));
                 BOOST_CHECK(it->GetValue(value));
                 BOOST_CHECK_EQUAL(key.str, exp_key);
                 BOOST_CHECK_EQUAL(value, x * x);
                 it->Next();
             }
         }
         BOOST_CHECK(!it->Valid());
     }
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/hash_tests.cpp b/src/test/hash_tests.cpp
index 4b4ddaba6..ba48885fe 100644
--- a/src/test/hash_tests.cpp
+++ b/src/test/hash_tests.cpp
@@ -1,142 +1,142 @@
 // 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.
 
 #include "hash.h"
 #include "test/test_bitcoin.h"
 #include "utilstrencodings.h"
 
 #include <vector>
 
 #include <boost/test/unit_test.hpp>
 
 BOOST_FIXTURE_TEST_SUITE(hash_tests, BasicTestingSetup)
 
 BOOST_AUTO_TEST_CASE(murmurhash3) {
 
 #define T(expected, seed, data)                                                \
     BOOST_CHECK_EQUAL(MurmurHash3(seed, ParseHex(data)), expected)
 
     // Test MurmurHash3 with various inputs. Of course this is retested in the
     // bloom filter tests - they would fail if MurmurHash3() had any problems -
     // but is useful for those trying to implement Bitcoin libraries as a
     // source of test data for their MurmurHash3() primitive during
     // development.
     //
     // The magic number 0xFBA4C795 comes from CBloomFilter::Hash()
 
     T(0x00000000, 0x00000000, "");
     T(0x6a396f08, 0xFBA4C795, "");
     T(0x81f16f39, 0xffffffff, "");
 
     T(0x514e28b7, 0x00000000, "00");
     T(0xea3f0b17, 0xFBA4C795, "00");
     T(0xfd6cf10d, 0x00000000, "ff");
 
     T(0x16c6b7ab, 0x00000000, "0011");
     T(0x8eb51c3d, 0x00000000, "001122");
     T(0xb4471bf8, 0x00000000, "00112233");
     T(0xe2301fa8, 0x00000000, "0011223344");
     T(0xfc2e4a15, 0x00000000, "001122334455");
     T(0xb074502c, 0x00000000, "00112233445566");
     T(0x8034d2a0, 0x00000000, "0011223344556677");
     T(0xb4698def, 0x00000000, "001122334455667788");
 
 #undef T
 }
 
 /*
    SipHash-2-4 output with
    k = 00 01 02 ...
    and
    in = (empty string)
    in = 00 (1 byte)
    in = 00 01 (2 bytes)
    in = 00 01 02 (3 bytes)
    ...
    in = 00 01 02 ... 3e (63 bytes)
 
    from: https://131002.net/siphash/siphash24.c
 */
 uint64_t siphash_4_2_testvec[] = {
     0x726fdb47dd0e0e31, 0x74f839c593dc67fd, 0x0d6c8009d9a94f5a,
     0x85676696d7fb7e2d, 0xcf2794e0277187b7, 0x18765564cd99a68d,
     0xcbc9466e58fee3ce, 0xab0200f58b01d137, 0x93f5f5799a932462,
     0x9e0082df0ba9e4b0, 0x7a5dbbc594ddb9f3, 0xf4b32f46226bada7,
     0x751e8fbc860ee5fb, 0x14ea5627c0843d90, 0xf723ca908e7af2ee,
     0xa129ca6149be45e5, 0x3f2acc7f57c29bdb, 0x699ae9f52cbe4794,
     0x4bc1b3f0968dd39c, 0xbb6dc91da77961bd, 0xbed65cf21aa2ee98,
     0xd0f2cbb02e3b67c7, 0x93536795e3a33e88, 0xa80c038ccd5ccec8,
     0xb8ad50c6f649af94, 0xbce192de8a85b8ea, 0x17d835b85bbb15f3,
     0x2f2e6163076bcfad, 0xde4daaaca71dc9a5, 0xa6a2506687956571,
     0xad87a3535c49ef28, 0x32d892fad841c342, 0x7127512f72f27cce,
     0xa7f32346f95978e3, 0x12e0b01abb051238, 0x15e034d40fa197ae,
     0x314dffbe0815a3b4, 0x027990f029623981, 0xcadcd4e59ef40c4d,
     0x9abfd8766a33735c, 0x0e3ea96b5304a7d0, 0xad0c42d6fc585992,
     0x187306c89bc215a9, 0xd4a60abcf3792b95, 0xf935451de4f21df2,
     0xa9538f0419755787, 0xdb9acddff56ca510, 0xd06c98cd5c0975eb,
     0xe612a3cb9ecba951, 0xc766e62cfcadaf96, 0xee64435a9752fe72,
     0xa192d576b245165a, 0x0a8787bf8ecb74b2, 0x81b3e73d20b49b6f,
     0x7fa8220ba3b2ecea, 0x245731c13ca42499, 0xb78dbfaf3a8d83bd,
     0xea1ad565322a1a0b, 0x60e61c23a3795013, 0x6606d7e446282b93,
     0x6ca4ecb15c5f91e1, 0x9f626da15c9625f3, 0xe51b38608ef25f57,
     0x958a324ceb064572};
 
 BOOST_AUTO_TEST_CASE(siphash) {
     CSipHasher hasher(0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL);
     BOOST_CHECK_EQUAL(hasher.Finalize(), 0x726fdb47dd0e0e31ull);
-    static const unsigned char t0[1] = {0};
+    static const uint8_t t0[1] = {0};
     hasher.Write(t0, 1);
     BOOST_CHECK_EQUAL(hasher.Finalize(), 0x74f839c593dc67fdull);
-    static const unsigned char t1[7] = {1, 2, 3, 4, 5, 6, 7};
+    static const uint8_t t1[7] = {1, 2, 3, 4, 5, 6, 7};
     hasher.Write(t1, 7);
     BOOST_CHECK_EQUAL(hasher.Finalize(), 0x93f5f5799a932462ull);
     hasher.Write(0x0F0E0D0C0B0A0908ULL);
     BOOST_CHECK_EQUAL(hasher.Finalize(), 0x3f2acc7f57c29bdbull);
-    static const unsigned char t2[2] = {16, 17};
+    static const uint8_t t2[2] = {16, 17};
     hasher.Write(t2, 2);
     BOOST_CHECK_EQUAL(hasher.Finalize(), 0x4bc1b3f0968dd39cull);
-    static const unsigned char t3[9] = {18, 19, 20, 21, 22, 23, 24, 25, 26};
+    static const uint8_t t3[9] = {18, 19, 20, 21, 22, 23, 24, 25, 26};
     hasher.Write(t3, 9);
     BOOST_CHECK_EQUAL(hasher.Finalize(), 0x2f2e6163076bcfadull);
-    static const unsigned char t4[5] = {27, 28, 29, 30, 31};
+    static const uint8_t t4[5] = {27, 28, 29, 30, 31};
     hasher.Write(t4, 5);
     BOOST_CHECK_EQUAL(hasher.Finalize(), 0x7127512f72f27cceull);
     hasher.Write(0x2726252423222120ULL);
     BOOST_CHECK_EQUAL(hasher.Finalize(), 0x0e3ea96b5304a7d0ull);
     hasher.Write(0x2F2E2D2C2B2A2928ULL);
     BOOST_CHECK_EQUAL(hasher.Finalize(), 0xe612a3cb9ecba951ull);
 
     BOOST_CHECK_EQUAL(
         SipHashUint256(0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL,
                        uint256S("1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09"
                                 "080706050403020100")),
         0x7127512f72f27cceull);
 
     // Check test vectors from spec, one byte at a time
     CSipHasher hasher2(0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL);
     for (uint8_t x = 0; x < ARRAYLEN(siphash_4_2_testvec); ++x) {
         BOOST_CHECK_EQUAL(hasher2.Finalize(), siphash_4_2_testvec[x]);
         hasher2.Write(&x, 1);
     }
     // Check test vectors from spec, eight bytes at a time
     CSipHasher hasher3(0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL);
     for (uint8_t x = 0; x < ARRAYLEN(siphash_4_2_testvec); x += 8) {
         BOOST_CHECK_EQUAL(hasher3.Finalize(), siphash_4_2_testvec[x]);
         hasher3.Write(uint64_t(x) | (uint64_t(x + 1) << 8) |
                       (uint64_t(x + 2) << 16) | (uint64_t(x + 3) << 24) |
                       (uint64_t(x + 4) << 32) | (uint64_t(x + 5) << 40) |
                       (uint64_t(x + 6) << 48) | (uint64_t(x + 7) << 56));
     }
 
     CHashWriter ss(SER_DISK, CLIENT_VERSION);
     CMutableTransaction tx;
     // Note these tests were originally written with tx.nVersion=1
     // and the test would be affected by default tx version bumps if not fixed.
     tx.nVersion = 1;
     ss << tx;
     BOOST_CHECK_EQUAL(SipHashUint256(1, 2, ss.GetHash()),
                       0x79751e980c2a0a35ULL);
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp
index 6ecc8437f..9047d28ab 100644
--- a/src/test/key_tests.cpp
+++ b/src/test/key_tests.cpp
@@ -1,205 +1,205 @@
 // Copyright (c) 2012-2015 The Bitcoin Core developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #include "key.h"
 
 #include "base58.h"
 #include "script/script.h"
 #include "test/test_bitcoin.h"
 #include "uint256.h"
 #include "util.h"
 #include "utilstrencodings.h"
 
 #include <string>
 #include <vector>
 
 #include <boost/test/unit_test.hpp>
 
 static const std::string
     strSecret1("5HxWvvfubhXpYYpS3tJkw6fq9jE9j18THftkZjHHfmFiWtmAbrj");
 static const std::string
     strSecret2("5KC4ejrDjv152FGwP386VD1i2NYc5KkfSMyv1nGy1VGDxGHqVY3");
 static const std::string
     strSecret1C("Kwr371tjA9u2rFSMZjTNun2PXXP3WPZu2afRHTcta6KxEUdm1vEw");
 static const std::string
     strSecret2C("L3Hq7a8FEQwJkW1M2GNKDW28546Vp5miewcCzSqUD9kCAXrJdS3g");
 static const CBitcoinAddress addr1("1QFqqMUD55ZV3PJEJZtaKCsQmjLT6JkjvJ");
 static const CBitcoinAddress addr2("1F5y5E5FMc5YzdJtB9hLaUe43GDxEKXENJ");
 static const CBitcoinAddress addr1C("1NoJrossxPBKfCHuJXT4HadJrXRE9Fxiqs");
 static const CBitcoinAddress addr2C("1CRj2HyM1CXWzHAXLQtiGLyggNT9WQqsDs");
 
 static const std::string strAddressBad("1HV9Lc3sNHZxwj4Zk6fB38tEmBryq2cBiF");
 
 #ifdef KEY_TESTS_DUMPINFO
 void dumpKeyInfo(uint256 privkey) {
     CKey key;
     key.resize(32);
     memcpy(&secret[0], &privkey, 32);
-    std::vector<unsigned char> sec;
+    std::vector<uint8_t> sec;
     sec.resize(32);
     memcpy(&sec[0], &secret[0], 32);
     printf("  * secret (hex): %s\n", HexStr(sec).c_str());
 
     for (int nCompressed = 0; nCompressed < 2; nCompressed++) {
         bool fCompressed = nCompressed == 1;
         printf("  * %s:\n", fCompressed ? "compressed" : "uncompressed");
         CBitcoinSecret bsecret;
         bsecret.SetSecret(secret, fCompressed);
         printf("    * secret (base58): %s\n", bsecret.ToString().c_str());
         CKey key;
         key.SetSecret(secret, fCompressed);
-        std::vector<unsigned char> vchPubKey = key.GetPubKey();
+        std::vector<uint8_t> vchPubKey = key.GetPubKey();
         printf("    * pubkey (hex): %s\n", HexStr(vchPubKey).c_str());
         printf("    * address (base58): %s\n",
                CBitcoinAddress(vchPubKey).ToString().c_str());
     }
 }
 #endif
 
 BOOST_FIXTURE_TEST_SUITE(key_tests, BasicTestingSetup)
 
 BOOST_AUTO_TEST_CASE(key_test1) {
     CBitcoinSecret bsecret1, bsecret2, bsecret1C, bsecret2C, baddress1;
     BOOST_CHECK(bsecret1.SetString(strSecret1));
     BOOST_CHECK(bsecret2.SetString(strSecret2));
     BOOST_CHECK(bsecret1C.SetString(strSecret1C));
     BOOST_CHECK(bsecret2C.SetString(strSecret2C));
     BOOST_CHECK(!baddress1.SetString(strAddressBad));
 
     CKey key1 = bsecret1.GetKey();
     BOOST_CHECK(key1.IsCompressed() == false);
     CKey key2 = bsecret2.GetKey();
     BOOST_CHECK(key2.IsCompressed() == false);
     CKey key1C = bsecret1C.GetKey();
     BOOST_CHECK(key1C.IsCompressed() == true);
     CKey key2C = bsecret2C.GetKey();
     BOOST_CHECK(key2C.IsCompressed() == true);
 
     CPubKey pubkey1 = key1.GetPubKey();
     CPubKey pubkey2 = key2.GetPubKey();
     CPubKey pubkey1C = key1C.GetPubKey();
     CPubKey pubkey2C = key2C.GetPubKey();
 
     BOOST_CHECK(key1.VerifyPubKey(pubkey1));
     BOOST_CHECK(!key1.VerifyPubKey(pubkey1C));
     BOOST_CHECK(!key1.VerifyPubKey(pubkey2));
     BOOST_CHECK(!key1.VerifyPubKey(pubkey2C));
 
     BOOST_CHECK(!key1C.VerifyPubKey(pubkey1));
     BOOST_CHECK(key1C.VerifyPubKey(pubkey1C));
     BOOST_CHECK(!key1C.VerifyPubKey(pubkey2));
     BOOST_CHECK(!key1C.VerifyPubKey(pubkey2C));
 
     BOOST_CHECK(!key2.VerifyPubKey(pubkey1));
     BOOST_CHECK(!key2.VerifyPubKey(pubkey1C));
     BOOST_CHECK(key2.VerifyPubKey(pubkey2));
     BOOST_CHECK(!key2.VerifyPubKey(pubkey2C));
 
     BOOST_CHECK(!key2C.VerifyPubKey(pubkey1));
     BOOST_CHECK(!key2C.VerifyPubKey(pubkey1C));
     BOOST_CHECK(!key2C.VerifyPubKey(pubkey2));
     BOOST_CHECK(key2C.VerifyPubKey(pubkey2C));
 
     BOOST_CHECK(addr1.Get() == CTxDestination(pubkey1.GetID()));
     BOOST_CHECK(addr2.Get() == CTxDestination(pubkey2.GetID()));
     BOOST_CHECK(addr1C.Get() == CTxDestination(pubkey1C.GetID()));
     BOOST_CHECK(addr2C.Get() == CTxDestination(pubkey2C.GetID()));
 
     for (int n = 0; n < 16; n++) {
         std::string strMsg = strprintf("Very secret message %i: 11", n);
         uint256 hashMsg = Hash(strMsg.begin(), strMsg.end());
 
         // normal signatures
 
-        std::vector<unsigned char> sign1, sign2, sign1C, sign2C;
+        std::vector<uint8_t> sign1, sign2, sign1C, sign2C;
 
         BOOST_CHECK(key1.Sign(hashMsg, sign1));
         BOOST_CHECK(key2.Sign(hashMsg, sign2));
         BOOST_CHECK(key1C.Sign(hashMsg, sign1C));
         BOOST_CHECK(key2C.Sign(hashMsg, sign2C));
 
         BOOST_CHECK(pubkey1.Verify(hashMsg, sign1));
         BOOST_CHECK(!pubkey1.Verify(hashMsg, sign2));
         BOOST_CHECK(pubkey1.Verify(hashMsg, sign1C));
         BOOST_CHECK(!pubkey1.Verify(hashMsg, sign2C));
 
         BOOST_CHECK(!pubkey2.Verify(hashMsg, sign1));
         BOOST_CHECK(pubkey2.Verify(hashMsg, sign2));
         BOOST_CHECK(!pubkey2.Verify(hashMsg, sign1C));
         BOOST_CHECK(pubkey2.Verify(hashMsg, sign2C));
 
         BOOST_CHECK(pubkey1C.Verify(hashMsg, sign1));
         BOOST_CHECK(!pubkey1C.Verify(hashMsg, sign2));
         BOOST_CHECK(pubkey1C.Verify(hashMsg, sign1C));
         BOOST_CHECK(!pubkey1C.Verify(hashMsg, sign2C));
 
         BOOST_CHECK(!pubkey2C.Verify(hashMsg, sign1));
         BOOST_CHECK(pubkey2C.Verify(hashMsg, sign2));
         BOOST_CHECK(!pubkey2C.Verify(hashMsg, sign1C));
         BOOST_CHECK(pubkey2C.Verify(hashMsg, sign2C));
 
         // compact signatures (with key recovery)
 
-        std::vector<unsigned char> csign1, csign2, csign1C, csign2C;
+        std::vector<uint8_t> csign1, csign2, csign1C, csign2C;
 
         BOOST_CHECK(key1.SignCompact(hashMsg, csign1));
         BOOST_CHECK(key2.SignCompact(hashMsg, csign2));
         BOOST_CHECK(key1C.SignCompact(hashMsg, csign1C));
         BOOST_CHECK(key2C.SignCompact(hashMsg, csign2C));
 
         CPubKey rkey1, rkey2, rkey1C, rkey2C;
 
         BOOST_CHECK(rkey1.RecoverCompact(hashMsg, csign1));
         BOOST_CHECK(rkey2.RecoverCompact(hashMsg, csign2));
         BOOST_CHECK(rkey1C.RecoverCompact(hashMsg, csign1C));
         BOOST_CHECK(rkey2C.RecoverCompact(hashMsg, csign2C));
 
         BOOST_CHECK(rkey1 == pubkey1);
         BOOST_CHECK(rkey2 == pubkey2);
         BOOST_CHECK(rkey1C == pubkey1C);
         BOOST_CHECK(rkey2C == pubkey2C);
     }
 
     // test deterministic signing
 
-    std::vector<unsigned char> detsig, detsigc;
+    std::vector<uint8_t> detsig, detsigc;
     std::string strMsg = "Very deterministic message";
     uint256 hashMsg = Hash(strMsg.begin(), strMsg.end());
     BOOST_CHECK(key1.Sign(hashMsg, detsig));
     BOOST_CHECK(key1C.Sign(hashMsg, detsigc));
     BOOST_CHECK(detsig == detsigc);
     BOOST_CHECK(detsig ==
                 ParseHex("304402205dbbddda71772d95ce91cd2d14b592cfbc1dd0aabd6a3"
                          "94b6c2d377bbe59d31d022014ddda21494a4e221f0824f0b8b924"
                          "c43fa43c0ad57dccdaa11f81a6bd4582f6"));
     BOOST_CHECK(key2.Sign(hashMsg, detsig));
     BOOST_CHECK(key2C.Sign(hashMsg, detsigc));
     BOOST_CHECK(detsig == detsigc);
     BOOST_CHECK(detsig ==
                 ParseHex("3044022052d8a32079c11e79db95af63bb9600c5b04f21a9ca33d"
                          "c129c2bfa8ac9dc1cd5022061d8ae5e0f6c1a16bde3719c64c2fd"
                          "70e404b6428ab9a69566962e8771b5944d"));
     BOOST_CHECK(key1.SignCompact(hashMsg, detsig));
     BOOST_CHECK(key1C.SignCompact(hashMsg, detsigc));
     BOOST_CHECK(detsig ==
                 ParseHex("1c5dbbddda71772d95ce91cd2d14b592cfbc1dd0aabd6a394b6c2"
                          "d377bbe59d31d14ddda21494a4e221f0824f0b8b924c43fa43c0a"
                          "d57dccdaa11f81a6bd4582f6"));
     BOOST_CHECK(detsigc ==
                 ParseHex("205dbbddda71772d95ce91cd2d14b592cfbc1dd0aabd6a394b6c2"
                          "d377bbe59d31d14ddda21494a4e221f0824f0b8b924c43fa43c0a"
                          "d57dccdaa11f81a6bd4582f6"));
     BOOST_CHECK(key2.SignCompact(hashMsg, detsig));
     BOOST_CHECK(key2C.SignCompact(hashMsg, detsigc));
     BOOST_CHECK(detsig ==
                 ParseHex("1c52d8a32079c11e79db95af63bb9600c5b04f21a9ca33dc129c2"
                          "bfa8ac9dc1cd561d8ae5e0f6c1a16bde3719c64c2fd70e404b642"
                          "8ab9a69566962e8771b5944d"));
     BOOST_CHECK(detsigc ==
                 ParseHex("2052d8a32079c11e79db95af63bb9600c5b04f21a9ca33dc129c2"
                          "bfa8ac9dc1cd561d8ae5e0f6c1a16bde3719c64c2fd70e404b642"
                          "8ab9a69566962e8771b5944d"));
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp
index 4cc5a10aa..b8b27f6e9 100644
--- a/src/test/miner_tests.cpp
+++ b/src/test/miner_tests.cpp
@@ -1,781 +1,781 @@
 // Copyright (c) 2011-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.
 
 #include "miner.h"
 #include "chainparams.h"
 #include "coins.h"
 #include "config.h"
 #include "consensus/consensus.h"
 #include "consensus/merkle.h"
 #include "consensus/validation.h"
 #include "policy/policy.h"
 #include "pubkey.h"
 #include "script/standard.h"
 #include "txmempool.h"
 #include "uint256.h"
 #include "util.h"
 #include "utilstrencodings.h"
 #include "validation.h"
 #include "validation.h"
 
 #include "test/test_bitcoin.h"
 
 #include <memory>
 
 #include <boost/test/unit_test.hpp>
 
 BOOST_FIXTURE_TEST_SUITE(miner_tests, TestingSetup)
 
 static CFeeRate blockMinFeeRate = CFeeRate(DEFAULT_BLOCK_MIN_TX_FEE);
 
 static struct {
-    unsigned char extranonce;
+    uint8_t extranonce;
     unsigned int nonce;
 } blockinfo[] = {
     {4, 0xa4a3e223}, {2, 0x15c32f9e}, {1, 0x0375b547}, {1, 0x7004a8a5},
     {2, 0xce440296}, {2, 0x52cfe198}, {1, 0x77a72cd0}, {2, 0xbb5d6f84},
     {2, 0x83f30c2c}, {1, 0x48a73d5b}, {1, 0xef7dcd01}, {2, 0x6809c6c4},
     {2, 0x0883ab3c}, {1, 0x087bbbe2}, {2, 0x2104a814}, {2, 0xdffb6daa},
     {1, 0xee8a0a08}, {2, 0xba4237c1}, {1, 0xa70349dc}, {1, 0x344722bb},
     {3, 0xd6294733}, {2, 0xec9f5c94}, {2, 0xca2fbc28}, {1, 0x6ba4f406},
     {2, 0x015d4532}, {1, 0x6e119b7c}, {2, 0x43e8f314}, {2, 0x27962f38},
     {2, 0xb571b51b}, {2, 0xb36bee23}, {2, 0xd17924a8}, {2, 0x6bc212d9},
     {1, 0x630d4948}, {2, 0x9a4c4ebb}, {2, 0x554be537}, {1, 0xd63ddfc7},
     {2, 0xa10acc11}, {1, 0x759a8363}, {2, 0xfb73090d}, {1, 0xe82c6a34},
     {1, 0xe33e92d7}, {3, 0x658ef5cb}, {2, 0xba32ff22}, {5, 0x0227a10c},
     {1, 0xa9a70155}, {5, 0xd096d809}, {1, 0x37176174}, {1, 0x830b8d0f},
     {1, 0xc6e3910e}, {2, 0x823f3ca8}, {1, 0x99850849}, {1, 0x7521fb81},
     {1, 0xaacaabab}, {1, 0xd645a2eb}, {5, 0x7aea1781}, {5, 0x9d6e4b78},
     {1, 0x4ce90fd8}, {1, 0xabdc832d}, {6, 0x4a34f32a}, {2, 0xf2524c1c},
     {2, 0x1bbeb08a}, {1, 0xad47f480}, {1, 0x9f026aeb}, {1, 0x15a95049},
     {2, 0xd1cb95b2}, {2, 0xf84bbda5}, {1, 0x0fa62cd1}, {1, 0xe05f9169},
     {1, 0x78d194a9}, {5, 0x3e38147b}, {5, 0x737ba0d4}, {1, 0x63378e10},
     {1, 0x6d5f91cf}, {2, 0x88612eb8}, {2, 0xe9639484}, {1, 0xb7fabc9d},
     {2, 0x19b01592}, {1, 0x5a90dd31}, {2, 0x5bd7e028}, {2, 0x94d00323},
     {1, 0xa9b9c01a}, {1, 0x3a40de61}, {1, 0x56e7eec7}, {5, 0x859f7ef6},
     {1, 0xfd8e5630}, {1, 0x2b0c9f7f}, {1, 0xba700e26}, {1, 0x7170a408},
     {1, 0x70de86a8}, {1, 0x74d64cd5}, {1, 0x49e738a1}, {2, 0x6910b602},
     {0, 0x643c565f}, {1, 0x54264b3f}, {2, 0x97ea6396}, {2, 0x55174459},
     {2, 0x03e8779a}, {1, 0x98f34d8f}, {1, 0xc07b2b07}, {1, 0xdfe29668},
     {1, 0x3141c7c1}, {1, 0xb3b595f4}, {1, 0x735abf08}, {5, 0x623bfbce},
     {2, 0xd351e722}, {1, 0xf4ca48c9}, {1, 0x5b19c670}, {1, 0xa164bf0e},
     {2, 0xbbbeb305}, {2, 0xfe1c810a},
 };
 
 CBlockIndex CreateBlockIndex(int nHeight) {
     CBlockIndex index;
     index.nHeight = nHeight;
     index.pprev = chainActive.Tip();
     return index;
 }
 
 bool TestSequenceLocks(const CTransaction &tx, int flags) {
     LOCK(mempool.cs);
     return CheckSequenceLocks(tx, flags);
 }
 
 // Test suite for ancestor feerate transaction selection.
 // Implemented as an additional function, rather than a separate test case, to
 // allow reusing the blockchain created in CreateNewBlock_validity.
 // Note that this test assumes blockprioritysize is 0.
 void TestPackageSelection(const CChainParams &chainparams, CScript scriptPubKey,
                           std::vector<CTransactionRef> &txFirst) {
     // Test the ancestor feerate transaction selection.
     TestMemPoolEntryHelper entry;
 
     GlobalConfig config;
 
     // Test that a medium fee transaction will be selected after a higher fee
     // rate package with a low fee rate parent.
     CMutableTransaction tx;
     tx.vin.resize(1);
     tx.vin[0].scriptSig = CScript() << OP_1;
     tx.vin[0].prevout.hash = txFirst[0]->GetId();
     tx.vin[0].prevout.n = 0;
     tx.vout.resize(1);
     tx.vout[0].nValue = 5000000000LL - 1000;
     // This tx has a low fee: 1000 satoshis.
     // Save this txid for later use.
     uint256 hashParentTx = tx.GetId();
     mempool.addUnchecked(
         hashParentTx,
         entry.Fee(1000).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
 
     // This tx has a medium fee: 10000 satoshis.
     tx.vin[0].prevout.hash = txFirst[1]->GetId();
     tx.vout[0].nValue = 5000000000LL - 10000;
     uint256 hashMediumFeeTx = tx.GetId();
     mempool.addUnchecked(
         hashMediumFeeTx,
         entry.Fee(10000).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
 
     // This tx has a high fee, but depends on the first transaction.
     tx.vin[0].prevout.hash = hashParentTx;
     // 50k satoshi fee.
     tx.vout[0].nValue = 5000000000LL - 1000 - 50000;
     uint256 hashHighFeeTx = tx.GetId();
     mempool.addUnchecked(
         hashHighFeeTx,
         entry.Fee(50000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx));
 
     std::unique_ptr<CBlockTemplate> pblocktemplate =
         BlockAssembler(config, chainparams).CreateNewBlock(scriptPubKey);
     BOOST_CHECK(pblocktemplate->block.vtx[1]->GetId() == hashParentTx);
     BOOST_CHECK(pblocktemplate->block.vtx[2]->GetId() == hashHighFeeTx);
     BOOST_CHECK(pblocktemplate->block.vtx[3]->GetId() == hashMediumFeeTx);
 
     // Test that a package below the block min tx fee doesn't get included
     tx.vin[0].prevout.hash = hashHighFeeTx;
     // 0 fee.
     tx.vout[0].nValue = 5000000000LL - 1000 - 50000;
     uint256 hashFreeTx = tx.GetId();
     mempool.addUnchecked(hashFreeTx, entry.Fee(0).FromTx(tx));
     size_t freeTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
 
     // Calculate a fee on child transaction that will put the package just
     // below the block min tx fee (assuming 1 child tx of the same size).
     CAmount feeToUse = blockMinFeeRate.GetFee(2 * freeTxSize) - 1;
 
     tx.vin[0].prevout.hash = hashFreeTx;
     tx.vout[0].nValue = 5000000000LL - 1000 - 50000 - feeToUse;
     uint256 hashLowFeeTx = tx.GetId();
     mempool.addUnchecked(hashLowFeeTx, entry.Fee(feeToUse).FromTx(tx));
     pblocktemplate =
         BlockAssembler(config, chainparams).CreateNewBlock(scriptPubKey);
     // Verify that the free tx and the low fee tx didn't get selected.
     for (size_t i = 0; i < pblocktemplate->block.vtx.size(); ++i) {
         BOOST_CHECK(pblocktemplate->block.vtx[i]->GetId() != hashFreeTx);
         BOOST_CHECK(pblocktemplate->block.vtx[i]->GetId() != hashLowFeeTx);
     }
 
     // Test that packages above the min relay fee do get included, even if one
     // of the transactions is below the min relay fee. Remove the low fee
     // transaction and replace with a higher fee transaction
     mempool.removeRecursive(tx);
     // Now we should be just over the min relay fee.
     tx.vout[0].nValue -= 2;
     hashLowFeeTx = tx.GetId();
     mempool.addUnchecked(hashLowFeeTx, entry.Fee(feeToUse + 2).FromTx(tx));
     pblocktemplate =
         BlockAssembler(config, chainparams).CreateNewBlock(scriptPubKey);
     BOOST_CHECK(pblocktemplate->block.vtx[4]->GetId() == hashFreeTx);
     BOOST_CHECK(pblocktemplate->block.vtx[5]->GetId() == hashLowFeeTx);
 
     // Test that transaction selection properly updates ancestor fee
     // calculations as ancestor transactions get included in a block. Add a
     // 0-fee transaction that has 2 outputs.
     tx.vin[0].prevout.hash = txFirst[2]->GetId();
     tx.vout.resize(2);
     tx.vout[0].nValue = 5000000000LL - 100000000;
     // 1BCC output.
     tx.vout[1].nValue = 100000000;
     uint256 hashFreeTx2 = tx.GetId();
     mempool.addUnchecked(hashFreeTx2,
                          entry.Fee(0).SpendsCoinbase(true).FromTx(tx));
 
     // This tx can't be mined by itself.
     tx.vin[0].prevout.hash = hashFreeTx2;
     tx.vout.resize(1);
     feeToUse = blockMinFeeRate.GetFee(freeTxSize);
     tx.vout[0].nValue = 5000000000LL - 100000000 - feeToUse;
     uint256 hashLowFeeTx2 = tx.GetId();
     mempool.addUnchecked(hashLowFeeTx2,
                          entry.Fee(feeToUse).SpendsCoinbase(false).FromTx(tx));
     pblocktemplate =
         BlockAssembler(config, chainparams).CreateNewBlock(scriptPubKey);
 
     // Verify that this tx isn't selected.
     for (size_t i = 0; i < pblocktemplate->block.vtx.size(); ++i) {
         BOOST_CHECK(pblocktemplate->block.vtx[i]->GetId() != hashFreeTx2);
         BOOST_CHECK(pblocktemplate->block.vtx[i]->GetId() != hashLowFeeTx2);
     }
 
     // This tx will be mineable, and should cause hashLowFeeTx2 to be selected
     // as well.
     tx.vin[0].prevout.n = 1;
     // 10k satoshi fee.
     tx.vout[0].nValue = 100000000 - 10000;
     mempool.addUnchecked(tx.GetId(), entry.Fee(10000).FromTx(tx));
     pblocktemplate =
         BlockAssembler(config, chainparams).CreateNewBlock(scriptPubKey);
     BOOST_CHECK(pblocktemplate->block.vtx[8]->GetId() == hashLowFeeTx2);
 }
 
 void TestCoinbaseMessageEB(uint64_t eb, std::string cbmsg) {
 
     GlobalConfig config;
     config.SetMaxBlockSize(eb);
     const CChainParams &chainparams = config.GetChainParams();
 
     CScript scriptPubKey =
         CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909"
                               "a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112"
                               "de5c384df7ba0b8d578a4c702b6bf11d5f")
                   << OP_CHECKSIG;
 
     std::unique_ptr<CBlockTemplate> pblocktemplate =
         BlockAssembler(config, chainparams).CreateNewBlock(scriptPubKey);
 
     CBlock *pblock = &pblocktemplate->block;
 
     // IncrementExtraNonce creates a valid coinbase and merkleRoot
     unsigned int extraNonce = 0;
     IncrementExtraNonce(config, pblock, chainActive.Tip(), extraNonce);
     unsigned int nHeight = chainActive.Tip()->nHeight + 1;
-    std::vector<unsigned char> vec(cbmsg.begin(), cbmsg.end());
+    std::vector<uint8_t> vec(cbmsg.begin(), cbmsg.end());
     BOOST_CHECK(pblock->vtx[0]->vin[0].scriptSig ==
                 ((CScript() << nHeight << CScriptNum(extraNonce) << vec) +
                  COINBASE_FLAGS));
 }
 
 // Coinbase scriptSig has to contains the correct EB value
 // converted to MB, rounded down to the first decimal
 BOOST_AUTO_TEST_CASE(CheckCoinbase_EB) {
     TestCoinbaseMessageEB(1000001, "/EB1.0/");
     TestCoinbaseMessageEB(2000000, "/EB2.0/");
     TestCoinbaseMessageEB(8000000, "/EB8.0/");
     TestCoinbaseMessageEB(8320000, "/EB8.3/");
 }
 
 // NOTE: These tests rely on CreateNewBlock doing its own self-validation!
 BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) {
     // Note that by default, these tests run with size accounting enabled.
     const CChainParams &chainparams = Params(CBaseChainParams::MAIN);
     CScript scriptPubKey =
         CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909"
                               "a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112"
                               "de5c384df7ba0b8d578a4c702b6bf11d5f")
                   << OP_CHECKSIG;
     std::unique_ptr<CBlockTemplate> pblocktemplate;
     CMutableTransaction tx, tx2;
     CScript script;
     uint256 hash;
     TestMemPoolEntryHelper entry;
     entry.nFee = 11;
     entry.dPriority = 111.0;
     entry.nHeight = 11;
 
     GlobalConfig config;
 
     LOCK(cs_main);
     fCheckpointsEnabled = false;
 
     // Simple block creation, nothing special yet:
     BOOST_CHECK(
         pblocktemplate =
             BlockAssembler(config, chainparams).CreateNewBlock(scriptPubKey));
 
     // We can't make transactions until we have inputs. Therefore, load 100
     // blocks :)
     int baseheight = 0;
     std::vector<CTransactionRef> txFirst;
     for (unsigned int i = 0; i < sizeof(blockinfo) / sizeof(*blockinfo); ++i) {
         // pointer for convenience.
         CBlock *pblock = &pblocktemplate->block;
         pblock->nVersion = 1;
         pblock->nTime = chainActive.Tip()->GetMedianTimePast() + 1;
         CMutableTransaction txCoinbase(*pblock->vtx[0]);
         txCoinbase.nVersion = 1;
         txCoinbase.vin[0].scriptSig = CScript();
         txCoinbase.vin[0].scriptSig.push_back(blockinfo[i].extranonce);
         txCoinbase.vin[0].scriptSig.push_back(chainActive.Height());
         // Ignore the (optional) segwit commitment added by CreateNewBlock (as
         // the hardcoded nonces don't account for this)
         txCoinbase.vout.resize(1);
         txCoinbase.vout[0].scriptPubKey = CScript();
         pblock->vtx[0] = MakeTransactionRef(std::move(txCoinbase));
         if (txFirst.size() == 0) baseheight = chainActive.Height();
         if (txFirst.size() < 4) txFirst.push_back(pblock->vtx[0]);
         pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
         pblock->nNonce = blockinfo[i].nonce;
         std::shared_ptr<const CBlock> shared_pblock =
             std::make_shared<const CBlock>(*pblock);
         BOOST_CHECK(ProcessNewBlock(GetConfig(), shared_pblock, true, nullptr));
         pblock->hashPrevBlock = pblock->GetHash();
     }
 
     // Just to make sure we can still make simple blocks.
     BOOST_CHECK(
         pblocktemplate =
             BlockAssembler(config, chainparams).CreateNewBlock(scriptPubKey));
 
     const CAmount BLOCKSUBSIDY = 50 * COIN;
     const CAmount LOWFEE = CENT;
     const CAmount HIGHFEE = COIN;
     const CAmount HIGHERFEE = 4 * COIN;
 
     // block sigops > limit: 1000 CHECKMULTISIG + 1
     tx.vin.resize(1);
     // NOTE: OP_NOP is used to force 20 SigOps for the CHECKMULTISIG
     tx.vin[0].scriptSig = CScript() << OP_0 << OP_0 << OP_0 << OP_NOP
                                     << OP_CHECKMULTISIG << OP_1;
     tx.vin[0].prevout.hash = txFirst[0]->GetId();
     tx.vin[0].prevout.n = 0;
     tx.vout.resize(1);
     tx.vout[0].nValue = BLOCKSUBSIDY;
     for (unsigned int i = 0; i < 1001; ++i) {
         tx.vout[0].nValue -= LOWFEE;
         hash = tx.GetId();
         // Only first tx spends coinbase.
         bool spendsCoinbase = (i == 0) ? true : false;
         // If we don't set the # of sig ops in the CTxMemPoolEntry, template
         // creation fails.
         mempool.addUnchecked(hash, entry.Fee(LOWFEE)
                                        .Time(GetTime())
                                        .SpendsCoinbase(spendsCoinbase)
                                        .FromTx(tx));
         tx.vin[0].prevout.hash = hash;
     }
     BOOST_CHECK_THROW(
         BlockAssembler(config, chainparams).CreateNewBlock(scriptPubKey),
         std::runtime_error);
     mempool.clear();
 
     tx.vin[0].prevout.hash = txFirst[0]->GetId();
     tx.vout[0].nValue = BLOCKSUBSIDY;
     for (unsigned int i = 0; i < 1001; ++i) {
         tx.vout[0].nValue -= LOWFEE;
         hash = tx.GetId();
         // Only first tx spends coinbase.
         bool spendsCoinbase = (i == 0) ? true : false;
         // If we do set the # of sig ops in the CTxMemPoolEntry, template
         // creation passes.
         mempool.addUnchecked(hash, entry.Fee(LOWFEE)
                                        .Time(GetTime())
                                        .SpendsCoinbase(spendsCoinbase)
                                        .SigOpsCost(80)
                                        .FromTx(tx));
         tx.vin[0].prevout.hash = hash;
     }
     BOOST_CHECK(
         pblocktemplate =
             BlockAssembler(config, chainparams).CreateNewBlock(scriptPubKey));
     mempool.clear();
 
     // block size > limit
     tx.vin[0].scriptSig = CScript();
     // 18 * (520char + DROP) + OP_1 = 9433 bytes
-    std::vector<unsigned char> vchData(520);
+    std::vector<uint8_t> vchData(520);
     for (unsigned int i = 0; i < 18; ++i)
         tx.vin[0].scriptSig << vchData << OP_DROP;
     tx.vin[0].scriptSig << OP_1;
     tx.vin[0].prevout.hash = txFirst[0]->GetId();
     tx.vout[0].nValue = BLOCKSUBSIDY;
     for (unsigned int i = 0; i < 128; ++i) {
         tx.vout[0].nValue -= LOWFEE;
         hash = tx.GetId();
         // Only first tx spends coinbase.
         bool spendsCoinbase = (i == 0) ? true : false;
         mempool.addUnchecked(hash, entry.Fee(LOWFEE)
                                        .Time(GetTime())
                                        .SpendsCoinbase(spendsCoinbase)
                                        .FromTx(tx));
         tx.vin[0].prevout.hash = hash;
     }
     BOOST_CHECK(
         pblocktemplate =
             BlockAssembler(config, chainparams).CreateNewBlock(scriptPubKey));
     mempool.clear();
 
     // Orphan in mempool, template creation fails.
     hash = tx.GetId();
     mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).FromTx(tx));
     BOOST_CHECK_THROW(
         BlockAssembler(config, chainparams).CreateNewBlock(scriptPubKey),
         std::runtime_error);
     mempool.clear();
 
     // Child with higher priority than parent.
     tx.vin[0].scriptSig = CScript() << OP_1;
     tx.vin[0].prevout.hash = txFirst[1]->GetId();
     tx.vout[0].nValue = BLOCKSUBSIDY - HIGHFEE;
     hash = tx.GetId();
     mempool.addUnchecked(
         hash,
         entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
     tx.vin[0].prevout.hash = hash;
     tx.vin.resize(2);
     tx.vin[1].scriptSig = CScript() << OP_1;
     tx.vin[1].prevout.hash = txFirst[0]->GetId();
     tx.vin[1].prevout.n = 0;
     // First txn output + fresh coinbase - new txn fee.
     tx.vout[0].nValue = tx.vout[0].nValue + BLOCKSUBSIDY - HIGHERFEE;
     hash = tx.GetId();
     mempool.addUnchecked(
         hash,
         entry.Fee(HIGHERFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
     BOOST_CHECK(
         pblocktemplate =
             BlockAssembler(config, chainparams).CreateNewBlock(scriptPubKey));
     mempool.clear();
 
     // Coinbase in mempool, template creation fails.
     tx.vin.resize(1);
     tx.vin[0].prevout.SetNull();
     tx.vin[0].scriptSig = CScript() << OP_0 << OP_1;
     tx.vout[0].nValue = 0;
     hash = tx.GetId();
     // Give it a fee so it'll get mined.
     mempool.addUnchecked(
         hash,
         entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx));
     BOOST_CHECK_THROW(
         BlockAssembler(config, chainparams).CreateNewBlock(scriptPubKey),
         std::runtime_error);
     mempool.clear();
 
     // Invalid (pre-p2sh) txn in mempool, template creation fails.
     tx.vin[0].prevout.hash = txFirst[0]->GetId();
     tx.vin[0].prevout.n = 0;
     tx.vin[0].scriptSig = CScript() << OP_1;
     tx.vout[0].nValue = BLOCKSUBSIDY - LOWFEE;
     script = CScript() << OP_0;
     tx.vout[0].scriptPubKey = GetScriptForDestination(CScriptID(script));
     hash = tx.GetId();
     mempool.addUnchecked(
         hash,
         entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
     tx.vin[0].prevout.hash = hash;
-    tx.vin[0].scriptSig =
-        CScript() << std::vector<unsigned char>(script.begin(), script.end());
+    tx.vin[0].scriptSig = CScript()
+                          << std::vector<uint8_t>(script.begin(), script.end());
     tx.vout[0].nValue -= LOWFEE;
     hash = tx.GetId();
     mempool.addUnchecked(
         hash,
         entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx));
     BOOST_CHECK_THROW(
         BlockAssembler(config, chainparams).CreateNewBlock(scriptPubKey),
         std::runtime_error);
     mempool.clear();
 
     // Double spend txn pair in mempool, template creation fails.
     tx.vin[0].prevout.hash = txFirst[0]->GetId();
     tx.vin[0].scriptSig = CScript() << OP_1;
     tx.vout[0].nValue = BLOCKSUBSIDY - HIGHFEE;
     tx.vout[0].scriptPubKey = CScript() << OP_1;
     hash = tx.GetId();
     mempool.addUnchecked(
         hash,
         entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
     tx.vout[0].scriptPubKey = CScript() << OP_2;
     hash = tx.GetId();
     mempool.addUnchecked(
         hash,
         entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
     BOOST_CHECK_THROW(
         BlockAssembler(config, chainparams).CreateNewBlock(scriptPubKey),
         std::runtime_error);
     mempool.clear();
 
     // Subsidy changing.
     int nHeight = chainActive.Height();
     // Create an actual 209999-long block chain (without valid blocks).
     while (chainActive.Tip()->nHeight < 209999) {
         CBlockIndex *prev = chainActive.Tip();
         CBlockIndex *next = new CBlockIndex();
         next->phashBlock = new uint256(GetRandHash());
         pcoinsTip->SetBestBlock(next->GetBlockHash());
         next->pprev = prev;
         next->nHeight = prev->nHeight + 1;
         next->BuildSkip();
         chainActive.SetTip(next);
     }
     BOOST_CHECK(
         pblocktemplate =
             BlockAssembler(config, chainparams).CreateNewBlock(scriptPubKey));
     // Extend to a 210000-long block chain.
     while (chainActive.Tip()->nHeight < 210000) {
         CBlockIndex *prev = chainActive.Tip();
         CBlockIndex *next = new CBlockIndex();
         next->phashBlock = new uint256(GetRandHash());
         pcoinsTip->SetBestBlock(next->GetBlockHash());
         next->pprev = prev;
         next->nHeight = prev->nHeight + 1;
         next->BuildSkip();
         chainActive.SetTip(next);
     }
     BOOST_CHECK(
         pblocktemplate =
             BlockAssembler(config, chainparams).CreateNewBlock(scriptPubKey));
     // Delete the dummy blocks again.
     while (chainActive.Tip()->nHeight > nHeight) {
         CBlockIndex *del = chainActive.Tip();
         chainActive.SetTip(del->pprev);
         pcoinsTip->SetBestBlock(del->pprev->GetBlockHash());
         delete del->phashBlock;
         delete del;
     }
 
     // non-final txs in mempool
     SetMockTime(chainActive.Tip()->GetMedianTimePast() + 1);
     int flags = LOCKTIME_VERIFY_SEQUENCE | LOCKTIME_MEDIAN_TIME_PAST;
     // height map
     std::vector<int> prevheights;
 
     // Relative height locked.
     tx.nVersion = 2;
     tx.vin.resize(1);
     prevheights.resize(1);
     // Only 1 transaction.
     tx.vin[0].prevout.hash = txFirst[0]->GetId();
     tx.vin[0].prevout.n = 0;
     tx.vin[0].scriptSig = CScript() << OP_1;
     // txFirst[0] is the 2nd block
     tx.vin[0].nSequence = chainActive.Tip()->nHeight + 1;
     prevheights[0] = baseheight + 1;
     tx.vout.resize(1);
     tx.vout[0].nValue = BLOCKSUBSIDY - HIGHFEE;
     tx.vout[0].scriptPubKey = CScript() << OP_1;
     tx.nLockTime = 0;
     hash = tx.GetId();
     mempool.addUnchecked(
         hash,
         entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
 
     {
         // Locktime passes.
         GlobalConfig config;
         CValidationState state;
         BOOST_CHECK(ContextualCheckTransactionForCurrentBlock(
             config, tx, state, chainparams.GetConsensus(), flags));
     }
 
     // Sequence locks fail.
     BOOST_CHECK(!TestSequenceLocks(tx, flags));
     // Sequence locks pass on 2nd block.
     BOOST_CHECK(
         SequenceLocks(tx, flags, &prevheights,
                       CreateBlockIndex(chainActive.Tip()->nHeight + 2)));
 
     // Relative time locked.
     tx.vin[0].prevout.hash = txFirst[1]->GetId();
     // txFirst[1] is the 3rd block.
     tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG |
                           (((chainActive.Tip()->GetMedianTimePast() + 1 -
                              chainActive[1]->GetMedianTimePast()) >>
                             CTxIn::SEQUENCE_LOCKTIME_GRANULARITY) +
                            1);
     prevheights[0] = baseheight + 2;
     hash = tx.GetId();
     mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
 
     {
         // Locktime passes.
         GlobalConfig config;
         CValidationState state;
         BOOST_CHECK(ContextualCheckTransactionForCurrentBlock(
             config, tx, state, chainparams.GetConsensus(), flags));
     }
 
     // Sequence locks fail.
     BOOST_CHECK(!TestSequenceLocks(tx, flags));
 
     for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++) {
         // Trick the MedianTimePast.
         chainActive.Tip()->GetAncestor(chainActive.Tip()->nHeight - i)->nTime +=
             512;
     }
     // Sequence locks pass 512 seconds later.
     BOOST_CHECK(
         SequenceLocks(tx, flags, &prevheights,
                       CreateBlockIndex(chainActive.Tip()->nHeight + 1)));
     for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++) {
         // Undo tricked MTP.
         chainActive.Tip()->GetAncestor(chainActive.Tip()->nHeight - i)->nTime -=
             512;
     }
 
     // Absolute height locked.
     tx.vin[0].prevout.hash = txFirst[2]->GetId();
     tx.vin[0].nSequence = CTxIn::SEQUENCE_FINAL - 1;
     prevheights[0] = baseheight + 3;
     tx.nLockTime = chainActive.Tip()->nHeight + 1;
     hash = tx.GetId();
     mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
 
     {
         // Locktime fails.
         GlobalConfig config;
         CValidationState state;
         BOOST_CHECK(!ContextualCheckTransactionForCurrentBlock(
             config, tx, state, chainparams.GetConsensus(), flags));
         BOOST_CHECK_EQUAL(state.GetRejectReason(), "bad-txns-nonfinal");
     }
 
     // Sequence locks pass.
     BOOST_CHECK(TestSequenceLocks(tx, flags));
 
     {
         // Locktime passes on 2nd block.
         GlobalConfig config;
         CValidationState state;
         BOOST_CHECK(ContextualCheckTransaction(
             config, tx, state, chainparams.GetConsensus(),
             chainActive.Tip()->nHeight + 2,
             chainActive.Tip()->GetMedianTimePast(),
             chainActive.Tip()->GetMedianTimePast()));
     }
 
     // Absolute time locked.
     tx.vin[0].prevout.hash = txFirst[3]->GetId();
     tx.nLockTime = chainActive.Tip()->GetMedianTimePast();
     prevheights.resize(1);
     prevheights[0] = baseheight + 4;
     hash = tx.GetId();
     mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
 
     {
         // Locktime fails.
         GlobalConfig config;
         CValidationState state;
         BOOST_CHECK(!ContextualCheckTransactionForCurrentBlock(
             config, tx, state, chainparams.GetConsensus(), flags));
         BOOST_CHECK_EQUAL(state.GetRejectReason(), "bad-txns-nonfinal");
     }
 
     // Sequence locks pass.
     BOOST_CHECK(TestSequenceLocks(tx, flags));
 
     {
         // Locktime passes 1 second later.
         GlobalConfig config;
         CValidationState state;
         BOOST_CHECK(ContextualCheckTransaction(
             config, tx, state, chainparams.GetConsensus(),
             chainActive.Tip()->nHeight + 1,
             chainActive.Tip()->GetMedianTimePast() + 1,
             chainActive.Tip()->GetMedianTimePast()));
     }
 
     // mempool-dependent transactions (not added)
     tx.vin[0].prevout.hash = hash;
     prevheights[0] = chainActive.Tip()->nHeight + 1;
     tx.nLockTime = 0;
     tx.vin[0].nSequence = 0;
 
     {
         // Locktime passes.
         GlobalConfig config;
         CValidationState state;
         BOOST_CHECK(ContextualCheckTransactionForCurrentBlock(
             config, tx, state, chainparams.GetConsensus(), flags));
     }
 
     // Sequence locks pass.
     BOOST_CHECK(TestSequenceLocks(tx, flags));
     tx.vin[0].nSequence = 1;
     // Sequence locks fail.
     BOOST_CHECK(!TestSequenceLocks(tx, flags));
     tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG;
     // Sequence locks pass.
     BOOST_CHECK(TestSequenceLocks(tx, flags));
     tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | 1;
     // Sequence locks fail.
     BOOST_CHECK(!TestSequenceLocks(tx, flags));
 
     BOOST_CHECK(
         pblocktemplate =
             BlockAssembler(config, chainparams).CreateNewBlock(scriptPubKey));
 
     // None of the of the absolute height/time locked tx should have made it
     // into the template because we still check IsFinalTx in CreateNewBlock, but
     // relative locked txs will if inconsistently added to mempool. For now
     // these will still generate a valid template until BIP68 soft fork.
     BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3);
     // However if we advance height by 1 and time by 512, all of them should be
     // mined.
     for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++) {
         // Trick the MedianTimePast.
         chainActive.Tip()->GetAncestor(chainActive.Tip()->nHeight - i)->nTime +=
             512;
     }
     chainActive.Tip()->nHeight++;
     SetMockTime(chainActive.Tip()->GetMedianTimePast() + 1);
 
     BOOST_CHECK(
         pblocktemplate =
             BlockAssembler(config, chainparams).CreateNewBlock(scriptPubKey));
     BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 5);
 
     chainActive.Tip()->nHeight--;
     SetMockTime(0);
     mempool.clear();
 
     TestPackageSelection(chainparams, scriptPubKey, txFirst);
 
     fCheckpointsEnabled = true;
 }
 
 void CheckBlockMaxSize(const CChainParams &chainparams, uint64_t size,
                        uint64_t expected) {
     GlobalConfig config;
 
     ForceSetArg("-blockmaxsize", std::to_string(size));
 
     BlockAssembler ba(config, chainparams);
     BOOST_CHECK_EQUAL(ba.GetMaxGeneratedBlockSize(), expected);
 }
 
 BOOST_AUTO_TEST_CASE(BlockAssembler_construction) {
     GlobalConfig config;
     const CChainParams &chainparams = Params();
 
     // We are working on a fake chain and need to protect ourselves.
     LOCK(cs_main);
 
     // Activate UAHF
     const int64_t hfStartTime = config.GetUAHFStartTime();
     auto pindex = chainActive.Tip();
     for (size_t i = 0; pindex && i < 5; i++) {
         pindex->nTime = hfStartTime;
         pindex = pindex->pprev;
     }
 
     BOOST_CHECK(IsUAHFenabledForCurrentBlock(config));
 
     // Test around historical 1MB (plus one byte because that's mandatory)
     config.SetMaxBlockSize(ONE_MEGABYTE + 1);
     CheckBlockMaxSize(chainparams, 0, 1000);
     CheckBlockMaxSize(chainparams, 1000, 1000);
     CheckBlockMaxSize(chainparams, 1001, 1001);
     CheckBlockMaxSize(chainparams, 12345, 12345);
 
     CheckBlockMaxSize(chainparams, ONE_MEGABYTE - 1001, ONE_MEGABYTE - 1001);
     CheckBlockMaxSize(chainparams, ONE_MEGABYTE - 1000, ONE_MEGABYTE - 1000);
     CheckBlockMaxSize(chainparams, ONE_MEGABYTE - 999, ONE_MEGABYTE - 999);
     CheckBlockMaxSize(chainparams, ONE_MEGABYTE, ONE_MEGABYTE - 999);
 
     // Test around higher limit such as 8MB
     static const auto EIGHT_MEGABYTES = 8 * ONE_MEGABYTE;
     config.SetMaxBlockSize(EIGHT_MEGABYTES);
     CheckBlockMaxSize(chainparams, EIGHT_MEGABYTES - 1001,
                       EIGHT_MEGABYTES - 1001);
     CheckBlockMaxSize(chainparams, EIGHT_MEGABYTES - 1000,
                       EIGHT_MEGABYTES - 1000);
     CheckBlockMaxSize(chainparams, EIGHT_MEGABYTES - 999,
                       EIGHT_MEGABYTES - 1000);
     CheckBlockMaxSize(chainparams, EIGHT_MEGABYTES, EIGHT_MEGABYTES - 1000);
 
     // Test around default cap
     config.SetMaxBlockSize(DEFAULT_MAX_BLOCK_SIZE);
     CheckBlockMaxSize(chainparams, DEFAULT_MAX_BLOCK_SIZE - 1001,
                       DEFAULT_MAX_BLOCK_SIZE - 1001);
     CheckBlockMaxSize(chainparams, DEFAULT_MAX_BLOCK_SIZE - 1000,
                       DEFAULT_MAX_BLOCK_SIZE - 1000);
     CheckBlockMaxSize(chainparams, DEFAULT_MAX_BLOCK_SIZE - 999,
                       DEFAULT_MAX_BLOCK_SIZE - 1000);
     CheckBlockMaxSize(chainparams, DEFAULT_MAX_BLOCK_SIZE,
                       DEFAULT_MAX_BLOCK_SIZE - 1000);
 
     // If the parameter is not specified, we use
     // DEFAULT_MAX_GENERATED_BLOCK_SIZE
     {
         ClearArg("-blockmaxsize");
         BlockAssembler ba(config, chainparams);
         BOOST_CHECK_EQUAL(ba.GetMaxGeneratedBlockSize(),
                           DEFAULT_MAX_GENERATED_BLOCK_SIZE);
     }
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp
index a0ffd9fc5..72ce51c96 100644
--- a/src/test/multisig_tests.cpp
+++ b/src/test/multisig_tests.cpp
@@ -1,359 +1,359 @@
 // Copyright (c) 2011-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.
 
 #include "key.h"
 #include "keystore.h"
 #include "policy/policy.h"
 #include "script/interpreter.h"
 #include "script/ismine.h"
 #include "script/script.h"
 #include "script/script_error.h"
 #include "script/sign.h"
 #include "test/test_bitcoin.h"
 #include "uint256.h"
 
 #include <boost/test/unit_test.hpp>
 
-typedef std::vector<unsigned char> valtype;
+typedef std::vector<uint8_t> valtype;
 
 BOOST_FIXTURE_TEST_SUITE(multisig_tests, BasicTestingSetup)
 
 CScript sign_multisig(CScript scriptPubKey, std::vector<CKey> keys,
                       CTransaction transaction, int whichIn) {
     uint256 hash =
         SignatureHash(scriptPubKey, transaction, whichIn, SIGHASH_ALL, 0);
 
     CScript result;
     // CHECKMULTISIG bug workaround
     result << OP_0;
     for (const CKey &key : keys) {
-        std::vector<unsigned char> vchSig;
+        std::vector<uint8_t> vchSig;
         BOOST_CHECK(key.Sign(hash, vchSig));
-        vchSig.push_back((unsigned char)SIGHASH_ALL);
+        vchSig.push_back(uint8_t(SIGHASH_ALL));
         result << vchSig;
     }
     return result;
 }
 
 BOOST_AUTO_TEST_CASE(multisig_verify) {
     unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC;
 
     ScriptError err;
     CKey key[4];
     CAmount amount = 0;
     for (int i = 0; i < 4; i++)
         key[i].MakeNewKey(true);
 
     CScript a_and_b;
     a_and_b << OP_2 << ToByteVector(key[0].GetPubKey())
             << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
 
     CScript a_or_b;
     a_or_b << OP_1 << ToByteVector(key[0].GetPubKey())
            << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
 
     CScript escrow;
     escrow << OP_2 << ToByteVector(key[0].GetPubKey())
            << ToByteVector(key[1].GetPubKey())
            << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
 
     // Funding transaction
     CMutableTransaction txFrom;
     txFrom.vout.resize(3);
     txFrom.vout[0].scriptPubKey = a_and_b;
     txFrom.vout[1].scriptPubKey = a_or_b;
     txFrom.vout[2].scriptPubKey = escrow;
 
     // Spending transaction
     CMutableTransaction txTo[3];
     for (int i = 0; i < 3; i++) {
         txTo[i].vin.resize(1);
         txTo[i].vout.resize(1);
         txTo[i].vin[0].prevout.n = i;
         txTo[i].vin[0].prevout.hash = txFrom.GetId();
         txTo[i].vout[0].nValue = 1;
     }
 
     std::vector<CKey> keys;
     CScript s;
 
     // Test a AND b:
     keys.assign(1, key[0]);
     keys.push_back(key[1]);
     s = sign_multisig(a_and_b, keys, txTo[0], 0);
     BOOST_CHECK(VerifyScript(
         s, a_and_b, flags,
         MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err));
     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
 
     for (int i = 0; i < 4; i++) {
         keys.assign(1, key[i]);
         s = sign_multisig(a_and_b, keys, txTo[0], 0);
         BOOST_CHECK_MESSAGE(
             !VerifyScript(
                 s, a_and_b, flags,
                 MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err),
             strprintf("a&b 1: %d", i));
         BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION,
                             ScriptErrorString(err));
 
         keys.assign(1, key[1]);
         keys.push_back(key[i]);
         s = sign_multisig(a_and_b, keys, txTo[0], 0);
         BOOST_CHECK_MESSAGE(
             !VerifyScript(
                 s, a_and_b, flags,
                 MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err),
             strprintf("a&b 2: %d", i));
         BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE,
                             ScriptErrorString(err));
     }
 
     // Test a OR b:
     for (int i = 0; i < 4; i++) {
         keys.assign(1, key[i]);
         s = sign_multisig(a_or_b, keys, txTo[1], 0);
         if (i == 0 || i == 1) {
             BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, flags,
                                              MutableTransactionSignatureChecker(
                                                  &txTo[1], 0, amount),
                                              &err),
                                 strprintf("a|b: %d", i));
             BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
         } else {
             BOOST_CHECK_MESSAGE(
                 !VerifyScript(
                     s, a_or_b, flags,
                     MutableTransactionSignatureChecker(&txTo[1], 0, amount),
                     &err),
                 strprintf("a|b: %d", i));
             BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE,
                                 ScriptErrorString(err));
         }
     }
     s.clear();
     s << OP_0 << OP_1;
     BOOST_CHECK(!VerifyScript(
         s, a_or_b, flags,
         MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err));
     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err));
 
     for (int i = 0; i < 4; i++)
         for (int j = 0; j < 4; j++) {
             keys.assign(1, key[i]);
             keys.push_back(key[j]);
             s = sign_multisig(escrow, keys, txTo[2], 0);
             if (i < j && i < 3 && j < 3) {
                 BOOST_CHECK_MESSAGE(
                     VerifyScript(
                         s, escrow, flags,
                         MutableTransactionSignatureChecker(&txTo[2], 0, amount),
                         &err),
                     strprintf("escrow 1: %d %d", i, j));
                 BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK,
                                     ScriptErrorString(err));
             } else {
                 BOOST_CHECK_MESSAGE(
                     !VerifyScript(
                         s, escrow, flags,
                         MutableTransactionSignatureChecker(&txTo[2], 0, amount),
                         &err),
                     strprintf("escrow 2: %d %d", i, j));
                 BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE,
                                     ScriptErrorString(err));
             }
         }
 }
 
 BOOST_AUTO_TEST_CASE(multisig_IsStandard) {
     CKey key[4];
     for (int i = 0; i < 4; i++)
         key[i].MakeNewKey(true);
 
     txnouttype whichType;
 
     CScript a_and_b;
     a_and_b << OP_2 << ToByteVector(key[0].GetPubKey())
             << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
     BOOST_CHECK(::IsStandard(a_and_b, whichType));
 
     CScript a_or_b;
     a_or_b << OP_1 << ToByteVector(key[0].GetPubKey())
            << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
     BOOST_CHECK(::IsStandard(a_or_b, whichType));
 
     CScript escrow;
     escrow << OP_2 << ToByteVector(key[0].GetPubKey())
            << ToByteVector(key[1].GetPubKey())
            << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
     BOOST_CHECK(::IsStandard(escrow, whichType));
 
     CScript one_of_four;
     one_of_four << OP_1 << ToByteVector(key[0].GetPubKey())
                 << ToByteVector(key[1].GetPubKey())
                 << ToByteVector(key[2].GetPubKey())
                 << ToByteVector(key[3].GetPubKey()) << OP_4 << OP_CHECKMULTISIG;
     BOOST_CHECK(!::IsStandard(one_of_four, whichType));
 
     CScript malformed[6];
     malformed[0] << OP_3 << ToByteVector(key[0].GetPubKey())
                  << ToByteVector(key[1].GetPubKey()) << OP_2
                  << OP_CHECKMULTISIG;
     malformed[1] << OP_2 << ToByteVector(key[0].GetPubKey())
                  << ToByteVector(key[1].GetPubKey()) << OP_3
                  << OP_CHECKMULTISIG;
     malformed[2] << OP_0 << ToByteVector(key[0].GetPubKey())
                  << ToByteVector(key[1].GetPubKey()) << OP_2
                  << OP_CHECKMULTISIG;
     malformed[3] << OP_1 << ToByteVector(key[0].GetPubKey())
                  << ToByteVector(key[1].GetPubKey()) << OP_0
                  << OP_CHECKMULTISIG;
     malformed[4] << OP_1 << ToByteVector(key[0].GetPubKey())
                  << ToByteVector(key[1].GetPubKey()) << OP_CHECKMULTISIG;
     malformed[5] << OP_1 << ToByteVector(key[0].GetPubKey())
                  << ToByteVector(key[1].GetPubKey());
 
     for (int i = 0; i < 6; i++)
         BOOST_CHECK(!::IsStandard(malformed[i], whichType));
 }
 
 BOOST_AUTO_TEST_CASE(multisig_Solver1) {
     // Tests Solver() that returns lists of keys that are required to satisfy a
     // ScriptPubKey
     //
     // Also tests IsMine() and ExtractDestination()
     //
     // Note: ExtractDestination for the multisignature transactions always
     // returns false for this release, even if you have one key that would
     // satisfy an (a|b) or 2-of-3 keys needed to spend an escrow transaction.
     //
     CBasicKeyStore keystore, emptykeystore, partialkeystore;
     CKey key[3];
     CTxDestination keyaddr[3];
     for (int i = 0; i < 3; i++) {
         key[i].MakeNewKey(true);
         keystore.AddKey(key[i]);
         keyaddr[i] = key[i].GetPubKey().GetID();
     }
     partialkeystore.AddKey(key[0]);
 
     {
         std::vector<valtype> solutions;
         txnouttype whichType;
         CScript s;
         s << ToByteVector(key[0].GetPubKey()) << OP_CHECKSIG;
         BOOST_CHECK(Solver(s, whichType, solutions));
         BOOST_CHECK(solutions.size() == 1);
         CTxDestination addr;
         BOOST_CHECK(ExtractDestination(s, addr));
         BOOST_CHECK(addr == keyaddr[0]);
         BOOST_CHECK(IsMine(keystore, s));
         BOOST_CHECK(!IsMine(emptykeystore, s));
     }
     {
         std::vector<valtype> solutions;
         txnouttype whichType;
         CScript s;
         s << OP_DUP << OP_HASH160 << ToByteVector(key[0].GetPubKey().GetID())
           << OP_EQUALVERIFY << OP_CHECKSIG;
         BOOST_CHECK(Solver(s, whichType, solutions));
         BOOST_CHECK(solutions.size() == 1);
         CTxDestination addr;
         BOOST_CHECK(ExtractDestination(s, addr));
         BOOST_CHECK(addr == keyaddr[0]);
         BOOST_CHECK(IsMine(keystore, s));
         BOOST_CHECK(!IsMine(emptykeystore, s));
     }
     {
         std::vector<valtype> solutions;
         txnouttype whichType;
         CScript s;
         s << OP_2 << ToByteVector(key[0].GetPubKey())
           << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
         BOOST_CHECK(Solver(s, whichType, solutions));
         BOOST_CHECK_EQUAL(solutions.size(), 4U);
         CTxDestination addr;
         BOOST_CHECK(!ExtractDestination(s, addr));
         BOOST_CHECK(IsMine(keystore, s));
         BOOST_CHECK(!IsMine(emptykeystore, s));
         BOOST_CHECK(!IsMine(partialkeystore, s));
     }
     {
         std::vector<valtype> solutions;
         txnouttype whichType;
         CScript s;
         s << OP_1 << ToByteVector(key[0].GetPubKey())
           << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
         BOOST_CHECK(Solver(s, whichType, solutions));
         BOOST_CHECK_EQUAL(solutions.size(), 4U);
         std::vector<CTxDestination> addrs;
         int nRequired;
         BOOST_CHECK(ExtractDestinations(s, whichType, addrs, nRequired));
         BOOST_CHECK(addrs[0] == keyaddr[0]);
         BOOST_CHECK(addrs[1] == keyaddr[1]);
         BOOST_CHECK(nRequired == 1);
         BOOST_CHECK(IsMine(keystore, s));
         BOOST_CHECK(!IsMine(emptykeystore, s));
         BOOST_CHECK(!IsMine(partialkeystore, s));
     }
     {
         std::vector<valtype> solutions;
         txnouttype whichType;
         CScript s;
         s << OP_2 << ToByteVector(key[0].GetPubKey())
           << ToByteVector(key[1].GetPubKey())
           << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
         BOOST_CHECK(Solver(s, whichType, solutions));
         BOOST_CHECK(solutions.size() == 5);
     }
 }
 
 BOOST_AUTO_TEST_CASE(multisig_Sign) {
     // Test SignSignature() (and therefore the version of Solver() that signs
     // transactions)
     CBasicKeyStore keystore;
     CKey key[4];
     for (int i = 0; i < 4; i++) {
         key[i].MakeNewKey(true);
         keystore.AddKey(key[i]);
     }
 
     CScript a_and_b;
     a_and_b << OP_2 << ToByteVector(key[0].GetPubKey())
             << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
 
     CScript a_or_b;
     a_or_b << OP_1 << ToByteVector(key[0].GetPubKey())
            << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
 
     CScript escrow;
     escrow << OP_2 << ToByteVector(key[0].GetPubKey())
            << ToByteVector(key[1].GetPubKey())
            << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
 
     // Funding transaction
     CMutableTransaction txFrom;
     txFrom.vout.resize(3);
     txFrom.vout[0].scriptPubKey = a_and_b;
     txFrom.vout[1].scriptPubKey = a_or_b;
     txFrom.vout[2].scriptPubKey = escrow;
 
     // Spending transaction
     CMutableTransaction txTo[3];
     for (int i = 0; i < 3; i++) {
         txTo[i].vin.resize(1);
         txTo[i].vout.resize(1);
         txTo[i].vin[0].prevout.n = i;
         txTo[i].vin[0].prevout.hash = txFrom.GetId();
         txTo[i].vout[0].nValue = 1;
     }
 
     for (int i = 0; i < 3; i++) {
         BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0,
                                           SIGHASH_ALL | SIGHASH_FORKID),
                             strprintf("SignSignature %d", i));
     }
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp
index 91dab563d..cc9cf4511 100644
--- a/src/test/net_tests.cpp
+++ b/src/test/net_tests.cpp
@@ -1,205 +1,205 @@
 // Copyright (c) 2012-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.
 #include "net.h"
 #include "addrman.h"
 #include "chainparams.h"
 #include "config.h"
 #include "hash.h"
 #include "netbase.h"
 #include "serialize.h"
 #include "streams.h"
 #include "test/test_bitcoin.h"
 
 #include <string>
 
 #include <boost/test/unit_test.hpp>
 
 class CAddrManSerializationMock : public CAddrMan {
 public:
     virtual void Serialize(CDataStream &s) const = 0;
 
     //! Ensure that bucket placement is always the same for testing purposes.
     void MakeDeterministic() {
         nKey.SetNull();
         insecure_rand = FastRandomContext(true);
     }
 };
 
 class CAddrManUncorrupted : public CAddrManSerializationMock {
 public:
     void Serialize(CDataStream &s) const { CAddrMan::Serialize(s); }
 };
 
 class CAddrManCorrupted : public CAddrManSerializationMock {
 public:
     void Serialize(CDataStream &s) const {
         // Produces corrupt output that claims addrman has 20 addrs when it only
         // has one addr.
-        unsigned char nVersion = 1;
+        uint8_t nVersion = 1;
         s << nVersion;
         s << uint8_t(32);
         s << nKey;
         s << 10; // nNew
         s << 10; // nTried
 
         int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30);
         s << nUBuckets;
 
         CService serv;
         Lookup("252.1.1.1", serv, 7777, false);
         CAddress addr = CAddress(serv, NODE_NONE);
         CNetAddr resolved;
         LookupHost("252.2.2.2", resolved, false);
         CAddrInfo info = CAddrInfo(addr, resolved);
         s << info;
     }
 };
 
 CDataStream AddrmanToStream(CAddrManSerializationMock &_addrman) {
     CDataStream ssPeersIn(SER_DISK, CLIENT_VERSION);
     ssPeersIn << FLATDATA(Params().MessageStart());
     ssPeersIn << _addrman;
     std::string str = ssPeersIn.str();
     std::vector<uint8_t> vchData(str.begin(), str.end());
     return CDataStream(vchData, SER_DISK, CLIENT_VERSION);
 }
 
 BOOST_FIXTURE_TEST_SUITE(net_tests, BasicTestingSetup)
 
 BOOST_AUTO_TEST_CASE(caddrdb_read) {
     CAddrManUncorrupted addrmanUncorrupted;
     addrmanUncorrupted.MakeDeterministic();
 
     CService addr1, addr2, addr3;
     Lookup("250.7.1.1", addr1, 8333, false);
     Lookup("250.7.2.2", addr2, 9999, false);
     Lookup("250.7.3.3", addr3, 9999, false);
 
     // Add three addresses to new table.
     CService source;
     Lookup("252.5.1.1", source, 8333, false);
     addrmanUncorrupted.Add(CAddress(addr1, NODE_NONE), source);
     addrmanUncorrupted.Add(CAddress(addr2, NODE_NONE), source);
     addrmanUncorrupted.Add(CAddress(addr3, NODE_NONE), source);
 
     // Test that the de-serialization does not throw an exception.
     CDataStream ssPeers1 = AddrmanToStream(addrmanUncorrupted);
     bool exceptionThrown = false;
     CAddrMan addrman1;
 
     BOOST_CHECK(addrman1.size() == 0);
     try {
         uint8_t pchMsgTmp[4];
         ssPeers1 >> FLATDATA(pchMsgTmp);
         ssPeers1 >> addrman1;
     } catch (const std::exception &e) {
         exceptionThrown = true;
     }
 
     BOOST_CHECK(addrman1.size() == 3);
     BOOST_CHECK(exceptionThrown == false);
 
     // Test that CAddrDB::Read creates an addrman with the correct number of
     // addrs.
     CDataStream ssPeers2 = AddrmanToStream(addrmanUncorrupted);
 
     CAddrMan addrman2;
     CAddrDB adb;
     BOOST_CHECK(addrman2.size() == 0);
     adb.Read(addrman2, ssPeers2);
     BOOST_CHECK(addrman2.size() == 3);
 }
 
 BOOST_AUTO_TEST_CASE(caddrdb_read_corrupted) {
     CAddrManCorrupted addrmanCorrupted;
     addrmanCorrupted.MakeDeterministic();
 
     // Test that the de-serialization of corrupted addrman throws an exception.
     CDataStream ssPeers1 = AddrmanToStream(addrmanCorrupted);
     bool exceptionThrown = false;
     CAddrMan addrman1;
     BOOST_CHECK(addrman1.size() == 0);
     try {
         uint8_t pchMsgTmp[4];
         ssPeers1 >> FLATDATA(pchMsgTmp);
         ssPeers1 >> addrman1;
     } catch (const std::exception &e) {
         exceptionThrown = true;
     }
     // Even through de-serialization failed addrman is not left in a clean
     // state.
     BOOST_CHECK(addrman1.size() == 1);
     BOOST_CHECK(exceptionThrown);
 
     // Test that CAddrDB::Read leaves addrman in a clean state if
     // de-serialization fails.
     CDataStream ssPeers2 = AddrmanToStream(addrmanCorrupted);
 
     CAddrMan addrman2;
     CAddrDB adb;
     BOOST_CHECK(addrman2.size() == 0);
     adb.Read(addrman2, ssPeers2);
     BOOST_CHECK(addrman2.size() == 0);
 }
 
 BOOST_AUTO_TEST_CASE(cnode_simple_test) {
     SOCKET hSocket = INVALID_SOCKET;
     NodeId id = 0;
     int height = 0;
 
     in_addr ipv4Addr;
     ipv4Addr.s_addr = 0xa0b0c001;
 
     CAddress addr = CAddress(CService(ipv4Addr, 7777), NODE_NETWORK);
     std::string pszDest = "";
     bool fInboundIn = false;
 
     // Test that fFeeler is false by default.
     std::unique_ptr<CNode> pnode1(new CNode(id++, NODE_NETWORK, height, hSocket,
                                             addr, 0, 0, pszDest, fInboundIn));
     BOOST_CHECK(pnode1->fInbound == false);
     BOOST_CHECK(pnode1->fFeeler == false);
 
     fInboundIn = true;
     std::unique_ptr<CNode> pnode2(new CNode(id++, NODE_NETWORK, height, hSocket,
                                             addr, 1, 1, pszDest, fInboundIn));
     BOOST_CHECK(pnode2->fInbound == true);
     BOOST_CHECK(pnode2->fFeeler == false);
 }
 
 BOOST_AUTO_TEST_CASE(test_getSubVersionEB) {
     BOOST_CHECK_EQUAL(getSubVersionEB(13800000000), "13800.0");
     BOOST_CHECK_EQUAL(getSubVersionEB(3800000000), "3800.0");
     BOOST_CHECK_EQUAL(getSubVersionEB(14000000), "14.0");
     BOOST_CHECK_EQUAL(getSubVersionEB(1540000), "1.5");
     BOOST_CHECK_EQUAL(getSubVersionEB(1560000), "1.5");
     BOOST_CHECK_EQUAL(getSubVersionEB(210000), "0.2");
     BOOST_CHECK_EQUAL(getSubVersionEB(10000), "0.0");
     BOOST_CHECK_EQUAL(getSubVersionEB(0), "0.0");
 }
 
 BOOST_AUTO_TEST_CASE(test_userAgentLength) {
     GlobalConfig config;
 
     config.SetMaxBlockSize(8000000);
     std::string long_uacomment = "very very very very very very very very very "
                                  "very very very very very very very very very "
                                  "very very very very very very very very very "
                                  "very very very very very very very very very "
                                  "very very very very very very very very very "
                                  "very very very very very very very very very "
                                  "very very very very very very very very very "
                                  "very very very very very very long comment";
     ForceSetMultiArg("-uacomment", long_uacomment);
 
     BOOST_CHECK_EQUAL(userAgent(config).size(), MAX_SUBVERSION_LENGTH);
     BOOST_CHECK_EQUAL(userAgent(config),
                       "/Bitcoin ABC:0.15.0(EB8.0; very very very very very "
                       "very very very very very very very very very very very "
                       "very very very very very very very very very very very "
                       "very very very very very very very very very very very "
                       "very very very very very very very ve)/");
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp
index 10503a5f8..eb2f07919 100644
--- a/src/test/netbase_tests.cpp
+++ b/src/test/netbase_tests.cpp
@@ -1,313 +1,309 @@
 // Copyright (c) 2012-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.
 
 #include "netbase.h"
 #include "test/test_bitcoin.h"
 
 #include <string>
 
 #include <boost/assign/list_of.hpp>
 #include <boost/test/unit_test.hpp>
 
 BOOST_FIXTURE_TEST_SUITE(netbase_tests, BasicTestingSetup)
 
 static CNetAddr ResolveIP(const char *ip) {
     CNetAddr addr;
     LookupHost(ip, addr, false);
     return addr;
 }
 
 static CSubNet ResolveSubNet(const char *subnet) {
     CSubNet ret;
     LookupSubNet(subnet, ret);
     return ret;
 }
 
 BOOST_AUTO_TEST_CASE(netbase_networks) {
     BOOST_CHECK(ResolveIP("127.0.0.1").GetNetwork() == NET_UNROUTABLE);
     BOOST_CHECK(ResolveIP("::1").GetNetwork() == NET_UNROUTABLE);
     BOOST_CHECK(ResolveIP("8.8.8.8").GetNetwork() == NET_IPV4);
     BOOST_CHECK(ResolveIP("2001::8888").GetNetwork() == NET_IPV6);
     BOOST_CHECK(
         ResolveIP("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").GetNetwork() ==
         NET_TOR);
 }
 
 BOOST_AUTO_TEST_CASE(netbase_properties) {
 
     BOOST_CHECK(ResolveIP("127.0.0.1").IsIPv4());
     BOOST_CHECK(ResolveIP("::FFFF:192.168.1.1").IsIPv4());
     BOOST_CHECK(ResolveIP("::1").IsIPv6());
     BOOST_CHECK(ResolveIP("10.0.0.1").IsRFC1918());
     BOOST_CHECK(ResolveIP("192.168.1.1").IsRFC1918());
     BOOST_CHECK(ResolveIP("172.31.255.255").IsRFC1918());
     BOOST_CHECK(ResolveIP("2001:0DB8::").IsRFC3849());
     BOOST_CHECK(ResolveIP("169.254.1.1").IsRFC3927());
     BOOST_CHECK(ResolveIP("2002::1").IsRFC3964());
     BOOST_CHECK(ResolveIP("FC00::").IsRFC4193());
     BOOST_CHECK(ResolveIP("2001::2").IsRFC4380());
     BOOST_CHECK(ResolveIP("2001:10::").IsRFC4843());
     BOOST_CHECK(ResolveIP("FE80::").IsRFC4862());
     BOOST_CHECK(ResolveIP("64:FF9B::").IsRFC6052());
     BOOST_CHECK(ResolveIP("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").IsTor());
     BOOST_CHECK(ResolveIP("127.0.0.1").IsLocal());
     BOOST_CHECK(ResolveIP("::1").IsLocal());
     BOOST_CHECK(ResolveIP("8.8.8.8").IsRoutable());
     BOOST_CHECK(ResolveIP("2001::1").IsRoutable());
     BOOST_CHECK(ResolveIP("127.0.0.1").IsValid());
 }
 
 static bool TestSplitHost(std::string test, std::string host, int port) {
     std::string hostOut;
     int portOut = -1;
     SplitHostPort(test, portOut, hostOut);
     return hostOut == host && port == portOut;
 }
 
 BOOST_AUTO_TEST_CASE(netbase_splithost) {
     BOOST_CHECK(TestSplitHost("www.bitcoin.org", "www.bitcoin.org", -1));
     BOOST_CHECK(TestSplitHost("[www.bitcoin.org]", "www.bitcoin.org", -1));
     BOOST_CHECK(TestSplitHost("www.bitcoin.org:80", "www.bitcoin.org", 80));
     BOOST_CHECK(TestSplitHost("[www.bitcoin.org]:80", "www.bitcoin.org", 80));
     BOOST_CHECK(TestSplitHost("127.0.0.1", "127.0.0.1", -1));
     BOOST_CHECK(TestSplitHost("127.0.0.1:8333", "127.0.0.1", 8333));
     BOOST_CHECK(TestSplitHost("[127.0.0.1]", "127.0.0.1", -1));
     BOOST_CHECK(TestSplitHost("[127.0.0.1]:8333", "127.0.0.1", 8333));
     BOOST_CHECK(TestSplitHost("::ffff:127.0.0.1", "::ffff:127.0.0.1", -1));
     BOOST_CHECK(
         TestSplitHost("[::ffff:127.0.0.1]:8333", "::ffff:127.0.0.1", 8333));
     BOOST_CHECK(TestSplitHost("[::]:8333", "::", 8333));
     BOOST_CHECK(TestSplitHost("::8333", "::8333", -1));
     BOOST_CHECK(TestSplitHost(":8333", "", 8333));
     BOOST_CHECK(TestSplitHost("[]:8333", "", 8333));
     BOOST_CHECK(TestSplitHost("", "", -1));
 }
 
 static bool TestParse(std::string src, std::string canon) {
     CService addr(LookupNumeric(src.c_str(), 65535));
     return canon == addr.ToString();
 }
 
 BOOST_AUTO_TEST_CASE(netbase_lookupnumeric) {
     BOOST_CHECK(TestParse("127.0.0.1", "127.0.0.1:65535"));
     BOOST_CHECK(TestParse("127.0.0.1:8333", "127.0.0.1:8333"));
     BOOST_CHECK(TestParse("::ffff:127.0.0.1", "127.0.0.1:65535"));
     BOOST_CHECK(TestParse("::", "[::]:65535"));
     BOOST_CHECK(TestParse("[::]:8333", "[::]:8333"));
     BOOST_CHECK(TestParse("[127.0.0.1]", "127.0.0.1:65535"));
     BOOST_CHECK(TestParse(":::", "[::]:0"));
 }
 
 BOOST_AUTO_TEST_CASE(onioncat_test) {
 
     // values from
     // https://web.archive.org/web/20121122003543/http://www.cypherpunk.at/onioncat/wiki/OnionCat
     CNetAddr addr1(ResolveIP("5wyqrzbvrdsumnok.onion"));
     CNetAddr addr2(ResolveIP("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca"));
     BOOST_CHECK(addr1 == addr2);
     BOOST_CHECK(addr1.IsTor());
     BOOST_CHECK(addr1.ToStringIP() == "5wyqrzbvrdsumnok.onion");
     BOOST_CHECK(addr1.IsRoutable());
 }
 
 BOOST_AUTO_TEST_CASE(subnet_test) {
 
     BOOST_CHECK(ResolveSubNet("1.2.3.0/24") ==
                 ResolveSubNet("1.2.3.0/255.255.255.0"));
     BOOST_CHECK(ResolveSubNet("1.2.3.0/24") !=
                 ResolveSubNet("1.2.4.0/255.255.255.0"));
     BOOST_CHECK(ResolveSubNet("1.2.3.0/24").Match(ResolveIP("1.2.3.4")));
     BOOST_CHECK(!ResolveSubNet("1.2.2.0/24").Match(ResolveIP("1.2.3.4")));
     BOOST_CHECK(ResolveSubNet("1.2.3.4").Match(ResolveIP("1.2.3.4")));
     BOOST_CHECK(ResolveSubNet("1.2.3.4/32").Match(ResolveIP("1.2.3.4")));
     BOOST_CHECK(!ResolveSubNet("1.2.3.4").Match(ResolveIP("5.6.7.8")));
     BOOST_CHECK(!ResolveSubNet("1.2.3.4/32").Match(ResolveIP("5.6.7.8")));
     BOOST_CHECK(
         ResolveSubNet("::ffff:127.0.0.1").Match(ResolveIP("127.0.0.1")));
     BOOST_CHECK(
         ResolveSubNet("1:2:3:4:5:6:7:8").Match(ResolveIP("1:2:3:4:5:6:7:8")));
     BOOST_CHECK(
         !ResolveSubNet("1:2:3:4:5:6:7:8").Match(ResolveIP("1:2:3:4:5:6:7:9")));
     BOOST_CHECK(ResolveSubNet("1:2:3:4:5:6:7:0/112")
                     .Match(ResolveIP("1:2:3:4:5:6:7:1234")));
     BOOST_CHECK(
         ResolveSubNet("192.168.0.1/24").Match(ResolveIP("192.168.0.2")));
     BOOST_CHECK(
         ResolveSubNet("192.168.0.20/29").Match(ResolveIP("192.168.0.18")));
     BOOST_CHECK(ResolveSubNet("1.2.2.1/24").Match(ResolveIP("1.2.2.4")));
     BOOST_CHECK(ResolveSubNet("1.2.2.110/31").Match(ResolveIP("1.2.2.111")));
     BOOST_CHECK(ResolveSubNet("1.2.2.20/26").Match(ResolveIP("1.2.2.63")));
     // All-Matching IPv6 Matches arbitrary IPv4 and IPv6
     BOOST_CHECK(ResolveSubNet("::/0").Match(ResolveIP("1:2:3:4:5:6:7:1234")));
     BOOST_CHECK(ResolveSubNet("::/0").Match(ResolveIP("1.2.3.4")));
     // All-Matching IPv4 does not Match IPv6
     BOOST_CHECK(
         !ResolveSubNet("0.0.0.0/0").Match(ResolveIP("1:2:3:4:5:6:7:1234")));
     // Invalid subnets Match nothing (not even invalid addresses)
     BOOST_CHECK(!CSubNet().Match(ResolveIP("1.2.3.4")));
     BOOST_CHECK(!ResolveSubNet("").Match(ResolveIP("4.5.6.7")));
     BOOST_CHECK(!ResolveSubNet("bloop").Match(ResolveIP("0.0.0.0")));
     BOOST_CHECK(!ResolveSubNet("bloop").Match(ResolveIP("hab")));
     // Check valid/invalid
     BOOST_CHECK(ResolveSubNet("1.2.3.0/0").IsValid());
     BOOST_CHECK(!ResolveSubNet("1.2.3.0/-1").IsValid());
     BOOST_CHECK(ResolveSubNet("1.2.3.0/32").IsValid());
     BOOST_CHECK(!ResolveSubNet("1.2.3.0/33").IsValid());
     BOOST_CHECK(ResolveSubNet("1:2:3:4:5:6:7:8/0").IsValid());
     BOOST_CHECK(ResolveSubNet("1:2:3:4:5:6:7:8/33").IsValid());
     BOOST_CHECK(!ResolveSubNet("1:2:3:4:5:6:7:8/-1").IsValid());
     BOOST_CHECK(ResolveSubNet("1:2:3:4:5:6:7:8/128").IsValid());
     BOOST_CHECK(!ResolveSubNet("1:2:3:4:5:6:7:8/129").IsValid());
     BOOST_CHECK(!ResolveSubNet("fuzzy").IsValid());
 
     // CNetAddr constructor test
     BOOST_CHECK(CSubNet(ResolveIP("127.0.0.1")).IsValid());
     BOOST_CHECK(CSubNet(ResolveIP("127.0.0.1")).Match(ResolveIP("127.0.0.1")));
     BOOST_CHECK(!CSubNet(ResolveIP("127.0.0.1")).Match(ResolveIP("127.0.0.2")));
     BOOST_CHECK(CSubNet(ResolveIP("127.0.0.1")).ToString() == "127.0.0.1/32");
 
     CSubNet subnet = CSubNet(ResolveIP("1.2.3.4"), 32);
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/32");
     subnet = CSubNet(ResolveIP("1.2.3.4"), 8);
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/8");
     subnet = CSubNet(ResolveIP("1.2.3.4"), 0);
     BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/0");
 
     subnet = CSubNet(ResolveIP("1.2.3.4"), ResolveIP("255.255.255.255"));
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/32");
     subnet = CSubNet(ResolveIP("1.2.3.4"), ResolveIP("255.0.0.0"));
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/8");
     subnet = CSubNet(ResolveIP("1.2.3.4"), ResolveIP("0.0.0.0"));
     BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/0");
 
     BOOST_CHECK(CSubNet(ResolveIP("1:2:3:4:5:6:7:8")).IsValid());
     BOOST_CHECK(CSubNet(ResolveIP("1:2:3:4:5:6:7:8"))
                     .Match(ResolveIP("1:2:3:4:5:6:7:8")));
     BOOST_CHECK(!CSubNet(ResolveIP("1:2:3:4:5:6:7:8"))
                      .Match(ResolveIP("1:2:3:4:5:6:7:9")));
     BOOST_CHECK(CSubNet(ResolveIP("1:2:3:4:5:6:7:8")).ToString() ==
                 "1:2:3:4:5:6:7:8/128");
 
     subnet = ResolveSubNet("1.2.3.4/255.255.255.255");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/32");
     subnet = ResolveSubNet("1.2.3.4/255.255.255.254");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/31");
     subnet = ResolveSubNet("1.2.3.4/255.255.255.252");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/30");
     subnet = ResolveSubNet("1.2.3.4/255.255.255.248");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/29");
     subnet = ResolveSubNet("1.2.3.4/255.255.255.240");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/28");
     subnet = ResolveSubNet("1.2.3.4/255.255.255.224");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/27");
     subnet = ResolveSubNet("1.2.3.4/255.255.255.192");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/26");
     subnet = ResolveSubNet("1.2.3.4/255.255.255.128");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/25");
     subnet = ResolveSubNet("1.2.3.4/255.255.255.0");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/24");
     subnet = ResolveSubNet("1.2.3.4/255.255.254.0");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.2.0/23");
     subnet = ResolveSubNet("1.2.3.4/255.255.252.0");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/22");
     subnet = ResolveSubNet("1.2.3.4/255.255.248.0");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/21");
     subnet = ResolveSubNet("1.2.3.4/255.255.240.0");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/20");
     subnet = ResolveSubNet("1.2.3.4/255.255.224.0");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/19");
     subnet = ResolveSubNet("1.2.3.4/255.255.192.0");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/18");
     subnet = ResolveSubNet("1.2.3.4/255.255.128.0");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/17");
     subnet = ResolveSubNet("1.2.3.4/255.255.0.0");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/16");
     subnet = ResolveSubNet("1.2.3.4/255.254.0.0");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/15");
     subnet = ResolveSubNet("1.2.3.4/255.252.0.0");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/14");
     subnet = ResolveSubNet("1.2.3.4/255.248.0.0");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/13");
     subnet = ResolveSubNet("1.2.3.4/255.240.0.0");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/12");
     subnet = ResolveSubNet("1.2.3.4/255.224.0.0");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/11");
     subnet = ResolveSubNet("1.2.3.4/255.192.0.0");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/10");
     subnet = ResolveSubNet("1.2.3.4/255.128.0.0");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/9");
     subnet = ResolveSubNet("1.2.3.4/255.0.0.0");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/8");
     subnet = ResolveSubNet("1.2.3.4/254.0.0.0");
     BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/7");
     subnet = ResolveSubNet("1.2.3.4/252.0.0.0");
     BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/6");
     subnet = ResolveSubNet("1.2.3.4/248.0.0.0");
     BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/5");
     subnet = ResolveSubNet("1.2.3.4/240.0.0.0");
     BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/4");
     subnet = ResolveSubNet("1.2.3.4/224.0.0.0");
     BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/3");
     subnet = ResolveSubNet("1.2.3.4/192.0.0.0");
     BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/2");
     subnet = ResolveSubNet("1.2.3.4/128.0.0.0");
     BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/1");
     subnet = ResolveSubNet("1.2.3.4/0.0.0.0");
     BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/0");
 
     subnet = ResolveSubNet(
         "1:2:3:4:5:6:7:8/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1:2:3:4:5:6:7:8/128");
     subnet = ResolveSubNet(
         "1:2:3:4:5:6:7:8/ffff:0000:0000:0000:0000:0000:0000:0000");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1::/16");
     subnet = ResolveSubNet(
         "1:2:3:4:5:6:7:8/0000:0000:0000:0000:0000:0000:0000:0000");
     BOOST_CHECK_EQUAL(subnet.ToString(), "::/0");
     subnet = ResolveSubNet("1.2.3.4/255.255.232.0");
     BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/255.255.232.0");
     subnet = ResolveSubNet(
         "1:2:3:4:5:6:7:8/ffff:ffff:ffff:fffe:ffff:ffff:ffff:ff0f");
     BOOST_CHECK_EQUAL(
         subnet.ToString(),
         "1:2:3:4:5:6:7:8/ffff:ffff:ffff:fffe:ffff:ffff:ffff:ff0f");
 }
 
 BOOST_AUTO_TEST_CASE(netbase_getgroup) {
 
     BOOST_CHECK(ResolveIP("127.0.0.1").GetGroup() ==
                 boost::assign::list_of(0)); // Local -> !Routable()
     BOOST_CHECK(ResolveIP("257.0.0.1").GetGroup() ==
                 boost::assign::list_of(0)); // !Valid -> !Routable()
     BOOST_CHECK(ResolveIP("10.0.0.1").GetGroup() ==
                 boost::assign::list_of(0)); // RFC1918 -> !Routable()
     BOOST_CHECK(ResolveIP("169.254.1.1").GetGroup() ==
                 boost::assign::list_of(0)); // RFC3927 -> !Routable()
     BOOST_CHECK(ResolveIP("1.2.3.4").GetGroup() ==
-                boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // IPv4
-    BOOST_CHECK(
-        ResolveIP("::FFFF:0:102:304").GetGroup() ==
-        boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC6145
-    BOOST_CHECK(
-        ResolveIP("64:FF9B::102:304").GetGroup() ==
-        boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC6052
-    BOOST_CHECK(
-        ResolveIP("2002:102:304:9999:9999:9999:9999:9999").GetGroup() ==
-        boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC3964
-    BOOST_CHECK(
-        ResolveIP("2001:0:9999:9999:9999:9999:FEFD:FCFB").GetGroup() ==
-        boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC4380
+                boost::assign::list_of((uint8_t)NET_IPV4)(1)(2)); // IPv4
+    BOOST_CHECK(ResolveIP("::FFFF:0:102:304").GetGroup() ==
+                boost::assign::list_of((uint8_t)NET_IPV4)(1)(2)); // RFC6145
+    BOOST_CHECK(ResolveIP("64:FF9B::102:304").GetGroup() ==
+                boost::assign::list_of((uint8_t)NET_IPV4)(1)(2)); // RFC6052
+    BOOST_CHECK(ResolveIP("2002:102:304:9999:9999:9999:9999:9999").GetGroup() ==
+                boost::assign::list_of((uint8_t)NET_IPV4)(1)(2)); // RFC3964
+    BOOST_CHECK(ResolveIP("2001:0:9999:9999:9999:9999:FEFD:FCFB").GetGroup() ==
+                boost::assign::list_of((uint8_t)NET_IPV4)(1)(2)); // RFC4380
     BOOST_CHECK(
         ResolveIP("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").GetGroup() ==
-        boost::assign::list_of((unsigned char)NET_TOR)(239)); // Tor
+        boost::assign::list_of((uint8_t)NET_TOR)(239)); // Tor
     BOOST_CHECK(
         ResolveIP("2001:470:abcd:9999:9999:9999:9999:9999").GetGroup() ==
-        boost::assign::list_of((unsigned char)NET_IPV6)(32)(1)(4)(112)(
+        boost::assign::list_of((uint8_t)NET_IPV6)(32)(1)(4)(112)(
             175)); // he.net
     BOOST_CHECK(
         ResolveIP("2001:2001:9999:9999:9999:9999:9999:9999").GetGroup() ==
-        boost::assign::list_of((unsigned char)NET_IPV6)(32)(1)(32)(1)); // IPv6
+        boost::assign::list_of((uint8_t)NET_IPV6)(32)(1)(32)(1)); // IPv6
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp
index dd2567f32..6a3462014 100644
--- a/src/test/script_P2SH_tests.cpp
+++ b/src/test/script_P2SH_tests.cpp
@@ -1,441 +1,441 @@
 // Copyright (c) 2012-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.
 
 #include "script/script.h"
 #include "core_io.h"
 #include "key.h"
 #include "keystore.h"
 #include "policy/policy.h"
 #include "script/ismine.h"
 #include "script/script_error.h"
 #include "script/sign.h"
 #include "test/test_bitcoin.h"
 #include "validation.h"
 
 #include <vector>
 
 #include <boost/test/unit_test.hpp>
 
 // Helpers:
-static std::vector<unsigned char> Serialize(const CScript &s) {
-    std::vector<unsigned char> sSerialized(s.begin(), s.end());
+static std::vector<uint8_t> Serialize(const CScript &s) {
+    std::vector<uint8_t> sSerialized(s.begin(), s.end());
     return sSerialized;
 }
 
 static bool Verify(const CScript &scriptSig, const CScript &scriptPubKey,
                    bool fStrict, ScriptError &err) {
     // Create dummy to/from transactions:
     CMutableTransaction txFrom;
     txFrom.vout.resize(1);
     txFrom.vout[0].scriptPubKey = scriptPubKey;
 
     CMutableTransaction txTo;
     txTo.vin.resize(1);
     txTo.vout.resize(1);
     txTo.vin[0].prevout.n = 0;
     txTo.vin[0].prevout.hash = txFrom.GetId();
     txTo.vin[0].scriptSig = scriptSig;
     txTo.vout[0].nValue = 1;
 
     return VerifyScript(
         scriptSig, scriptPubKey,
         (fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE) |
             SCRIPT_ENABLE_SIGHASH_FORKID,
         MutableTransactionSignatureChecker(&txTo, 0, txFrom.vout[0].nValue),
         &err);
 }
 
 BOOST_FIXTURE_TEST_SUITE(script_P2SH_tests, BasicTestingSetup)
 
 BOOST_AUTO_TEST_CASE(sign) {
     LOCK(cs_main);
     // Pay-to-script-hash looks like this:
     // scriptSig:    <sig> <sig...> <serialized_script>
     // scriptPubKey: HASH160 <hash> EQUAL
 
     // Test SignSignature() (and therefore the version of Solver() that signs
     // transactions)
     CBasicKeyStore keystore;
     CKey key[4];
     for (int i = 0; i < 4; i++) {
         key[i].MakeNewKey(true);
         keystore.AddKey(key[i]);
     }
 
     // 8 Scripts: checking all combinations of
     // different keys, straight/P2SH, pubkey/pubkeyhash
     CScript standardScripts[4];
     standardScripts[0] << ToByteVector(key[0].GetPubKey()) << OP_CHECKSIG;
     standardScripts[1] = GetScriptForDestination(key[1].GetPubKey().GetID());
     standardScripts[2] << ToByteVector(key[1].GetPubKey()) << OP_CHECKSIG;
     standardScripts[3] = GetScriptForDestination(key[2].GetPubKey().GetID());
     CScript evalScripts[4];
     for (int i = 0; i < 4; i++) {
         keystore.AddCScript(standardScripts[i]);
         evalScripts[i] = GetScriptForDestination(CScriptID(standardScripts[i]));
     }
 
     CMutableTransaction txFrom; // Funding transaction:
     std::string reason;
     txFrom.vout.resize(8);
     for (int i = 0; i < 4; i++) {
         txFrom.vout[i].scriptPubKey = evalScripts[i];
         txFrom.vout[i].nValue = COIN;
         txFrom.vout[i + 4].scriptPubKey = standardScripts[i];
         txFrom.vout[i + 4].nValue = COIN;
     }
     BOOST_CHECK(IsStandardTx(txFrom, reason));
 
     CMutableTransaction txTo[8]; // Spending transactions
     for (int i = 0; i < 8; i++) {
         txTo[i].vin.resize(1);
         txTo[i].vout.resize(1);
         txTo[i].vin[0].prevout.n = i;
         txTo[i].vin[0].prevout.hash = txFrom.GetId();
         txTo[i].vout[0].nValue = 1;
         BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey),
                             strprintf("IsMine %d", i));
     }
     for (int i = 0; i < 8; i++) {
         BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0,
                                           SIGHASH_ALL | SIGHASH_FORKID),
                             strprintf("SignSignature %d", i));
     }
     // All of the above should be OK, and the txTos have valid signatures
     // Check to make sure signature verification fails if we use the wrong
     // ScriptSig:
     for (int i = 0; i < 8; i++) {
         PrecomputedTransactionData txdata(txTo[i]);
         for (int j = 0; j < 8; j++) {
             CScript sigSave = txTo[i].vin[0].scriptSig;
             txTo[i].vin[0].scriptSig = txTo[j].vin[0].scriptSig;
             const CTxOut &output = txFrom.vout[txTo[i].vin[0].prevout.n];
             bool sigOK =
                 CScriptCheck(output.scriptPubKey, output.nValue, txTo[i], 0,
                              SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC |
                                  SCRIPT_ENABLE_SIGHASH_FORKID,
                              false, txdata)();
             if (i == j) {
                 BOOST_CHECK_MESSAGE(sigOK,
                                     strprintf("VerifySignature %d %d", i, j));
             } else {
                 BOOST_CHECK_MESSAGE(!sigOK,
                                     strprintf("VerifySignature %d %d", i, j));
             }
             txTo[i].vin[0].scriptSig = sigSave;
         }
     }
 }
 
 BOOST_AUTO_TEST_CASE(norecurse) {
     ScriptError err;
     // Make sure only the outer pay-to-script-hash does the
     // extra-validation thing:
     CScript invalidAsScript;
     invalidAsScript << OP_INVALIDOPCODE << OP_INVALIDOPCODE;
 
     CScript p2sh = GetScriptForDestination(CScriptID(invalidAsScript));
 
     CScript scriptSig;
     scriptSig << Serialize(invalidAsScript);
 
     // Should not verify, because it will try to execute OP_INVALIDOPCODE
     BOOST_CHECK(!Verify(scriptSig, p2sh, true, err));
     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_BAD_OPCODE, ScriptErrorString(err));
 
     // Try to recur, and verification should succeed because
     // the inner HASH160 <> EQUAL should only check the hash:
     CScript p2sh2 = GetScriptForDestination(CScriptID(p2sh));
     CScript scriptSig2;
     scriptSig2 << Serialize(invalidAsScript) << Serialize(p2sh);
 
     BOOST_CHECK(Verify(scriptSig2, p2sh2, true, err));
     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
 }
 
 BOOST_AUTO_TEST_CASE(set) {
     LOCK(cs_main);
     // Test the CScript::Set* methods
     CBasicKeyStore keystore;
     CKey key[4];
     std::vector<CPubKey> keys;
     for (int i = 0; i < 4; i++) {
         key[i].MakeNewKey(true);
         keystore.AddKey(key[i]);
         keys.push_back(key[i].GetPubKey());
     }
 
     CScript inner[4];
     inner[0] = GetScriptForDestination(key[0].GetPubKey().GetID());
     inner[1] = GetScriptForMultisig(
         2, std::vector<CPubKey>(keys.begin(), keys.begin() + 2));
     inner[2] = GetScriptForMultisig(
         1, std::vector<CPubKey>(keys.begin(), keys.begin() + 2));
     inner[3] = GetScriptForMultisig(
         2, std::vector<CPubKey>(keys.begin(), keys.begin() + 3));
 
     CScript outer[4];
     for (int i = 0; i < 4; i++) {
         outer[i] = GetScriptForDestination(CScriptID(inner[i]));
         keystore.AddCScript(inner[i]);
     }
 
     // Funding transaction:
     CMutableTransaction txFrom;
     std::string reason;
     txFrom.vout.resize(4);
     for (int i = 0; i < 4; i++) {
         txFrom.vout[i].scriptPubKey = outer[i];
         txFrom.vout[i].nValue = CENT;
     }
     BOOST_CHECK(IsStandardTx(txFrom, reason));
 
     // Spending transactions
     CMutableTransaction txTo[4];
     for (int i = 0; i < 4; i++) {
         txTo[i].vin.resize(1);
         txTo[i].vout.resize(1);
         txTo[i].vin[0].prevout.n = i;
         txTo[i].vin[0].prevout.hash = txFrom.GetId();
         txTo[i].vout[0].nValue = 1 * CENT;
         txTo[i].vout[0].scriptPubKey = inner[i];
         BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey),
                             strprintf("IsMine %d", i));
     }
     for (int i = 0; i < 4; i++) {
         BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0,
                                           SIGHASH_ALL | SIGHASH_FORKID),
                             strprintf("SignSignature %d", i));
         BOOST_CHECK_MESSAGE(IsStandardTx(txTo[i], reason),
                             strprintf("txTo[%d].IsStandard", i));
     }
 }
 
 BOOST_AUTO_TEST_CASE(is) {
     // Test CScript::IsPayToScriptHash()
     uint160 dummy;
     CScript p2sh;
     p2sh << OP_HASH160 << ToByteVector(dummy) << OP_EQUAL;
     BOOST_CHECK(p2sh.IsPayToScriptHash());
 
     // Not considered pay-to-script-hash if using one of the OP_PUSHDATA
     // opcodes:
-    static const unsigned char direct[] = {
-        OP_HASH160, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0,       0,
-        0,          0,  0, 0, 0, 0, 0, 0, 0, 0, OP_EQUAL};
+    static const uint8_t direct[] = {OP_HASH160, 20, 0, 0, 0, 0, 0,       0,
+                                     0,          0,  0, 0, 0, 0, 0,       0,
+                                     0,          0,  0, 0, 0, 0, OP_EQUAL};
     BOOST_CHECK(CScript(direct, direct + sizeof(direct)).IsPayToScriptHash());
-    static const unsigned char pushdata1[] = {OP_HASH160, OP_PUSHDATA1,
-                                              20,         0,
-                                              0,          0,
-                                              0,          0,
-                                              0,          0,
-                                              0,          0,
-                                              0,          0,
-                                              0,          0,
-                                              0,          0,
-                                              0,          0,
-                                              0,          0,
-                                              0,          OP_EQUAL};
+    static const uint8_t pushdata1[] = {OP_HASH160, OP_PUSHDATA1,
+                                        20,         0,
+                                        0,          0,
+                                        0,          0,
+                                        0,          0,
+                                        0,          0,
+                                        0,          0,
+                                        0,          0,
+                                        0,          0,
+                                        0,          0,
+                                        0,          0,
+                                        0,          OP_EQUAL};
     BOOST_CHECK(
         !CScript(pushdata1, pushdata1 + sizeof(pushdata1)).IsPayToScriptHash());
-    static const unsigned char pushdata2[] = {OP_HASH160, OP_PUSHDATA2,
-                                              20,         0,
-                                              0,          0,
-                                              0,          0,
-                                              0,          0,
-                                              0,          0,
-                                              0,          0,
-                                              0,          0,
-                                              0,          0,
-                                              0,          0,
-                                              0,          0,
-                                              0,          0,
-                                              OP_EQUAL};
+    static const uint8_t pushdata2[] = {OP_HASH160, OP_PUSHDATA2,
+                                        20,         0,
+                                        0,          0,
+                                        0,          0,
+                                        0,          0,
+                                        0,          0,
+                                        0,          0,
+                                        0,          0,
+                                        0,          0,
+                                        0,          0,
+                                        0,          0,
+                                        0,          0,
+                                        OP_EQUAL};
     BOOST_CHECK(
         !CScript(pushdata2, pushdata2 + sizeof(pushdata2)).IsPayToScriptHash());
-    static const unsigned char pushdata4[] = {OP_HASH160, OP_PUSHDATA4,
-                                              20,         0,
-                                              0,          0,
-                                              0,          0,
-                                              0,          0,
-                                              0,          0,
-                                              0,          0,
-                                              0,          0,
-                                              0,          0,
-                                              0,          0,
-                                              0,          0,
-                                              0,          0,
-                                              0,          0,
-                                              OP_EQUAL};
+    static const uint8_t pushdata4[] = {OP_HASH160, OP_PUSHDATA4,
+                                        20,         0,
+                                        0,          0,
+                                        0,          0,
+                                        0,          0,
+                                        0,          0,
+                                        0,          0,
+                                        0,          0,
+                                        0,          0,
+                                        0,          0,
+                                        0,          0,
+                                        0,          0,
+                                        0,          0,
+                                        OP_EQUAL};
     BOOST_CHECK(
         !CScript(pushdata4, pushdata4 + sizeof(pushdata4)).IsPayToScriptHash());
 
     CScript not_p2sh;
     BOOST_CHECK(!not_p2sh.IsPayToScriptHash());
 
     not_p2sh.clear();
     not_p2sh << OP_HASH160 << ToByteVector(dummy) << ToByteVector(dummy)
              << OP_EQUAL;
     BOOST_CHECK(!not_p2sh.IsPayToScriptHash());
 
     not_p2sh.clear();
     not_p2sh << OP_NOP << ToByteVector(dummy) << OP_EQUAL;
     BOOST_CHECK(!not_p2sh.IsPayToScriptHash());
 
     not_p2sh.clear();
     not_p2sh << OP_HASH160 << ToByteVector(dummy) << OP_CHECKSIG;
     BOOST_CHECK(!not_p2sh.IsPayToScriptHash());
 }
 
 BOOST_AUTO_TEST_CASE(switchover) {
     // Test switch over code
     CScript notValid;
     ScriptError err;
     notValid << OP_11 << OP_12 << OP_EQUALVERIFY;
     CScript scriptSig;
     scriptSig << Serialize(notValid);
 
     CScript fund = GetScriptForDestination(CScriptID(notValid));
 
     // Validation should succeed under old rules (hash is correct):
     BOOST_CHECK(Verify(scriptSig, fund, false, err));
     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
     // Fail under new:
     BOOST_CHECK(!Verify(scriptSig, fund, true, err));
     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EQUALVERIFY, ScriptErrorString(err));
 }
 
 BOOST_AUTO_TEST_CASE(AreInputsStandard) {
     LOCK(cs_main);
     CCoinsView coinsDummy;
     CCoinsViewCache coins(&coinsDummy);
     CBasicKeyStore keystore;
     CKey key[6];
     std::vector<CPubKey> keys;
     for (int i = 0; i < 6; i++) {
         key[i].MakeNewKey(true);
         keystore.AddKey(key[i]);
     }
     for (int i = 0; i < 3; i++)
         keys.push_back(key[i].GetPubKey());
 
     CMutableTransaction txFrom;
     txFrom.vout.resize(7);
 
     // First three are standard:
     CScript pay1 = GetScriptForDestination(key[0].GetPubKey().GetID());
     keystore.AddCScript(pay1);
     CScript pay1of3 = GetScriptForMultisig(1, keys);
 
     // P2SH (OP_CHECKSIG)
     txFrom.vout[0].scriptPubKey = GetScriptForDestination(CScriptID(pay1));
     txFrom.vout[0].nValue = 1000;
     // ordinary OP_CHECKSIG
     txFrom.vout[1].scriptPubKey = pay1;
     txFrom.vout[1].nValue = 2000;
     // ordinary OP_CHECKMULTISIG
     txFrom.vout[2].scriptPubKey = pay1of3;
     txFrom.vout[2].nValue = 3000;
 
     // vout[3] is complicated 1-of-3 AND 2-of-3
     // ... that is OK if wrapped in P2SH:
     CScript oneAndTwo;
     oneAndTwo << OP_1 << ToByteVector(key[0].GetPubKey())
               << ToByteVector(key[1].GetPubKey())
               << ToByteVector(key[2].GetPubKey());
     oneAndTwo << OP_3 << OP_CHECKMULTISIGVERIFY;
     oneAndTwo << OP_2 << ToByteVector(key[3].GetPubKey())
               << ToByteVector(key[4].GetPubKey())
               << ToByteVector(key[5].GetPubKey());
     oneAndTwo << OP_3 << OP_CHECKMULTISIG;
     keystore.AddCScript(oneAndTwo);
     txFrom.vout[3].scriptPubKey = GetScriptForDestination(CScriptID(oneAndTwo));
     txFrom.vout[3].nValue = 4000;
 
     // vout[4] is max sigops:
     CScript fifteenSigops;
     fifteenSigops << OP_1;
     for (unsigned i = 0; i < MAX_P2SH_SIGOPS; i++)
         fifteenSigops << ToByteVector(key[i % 3].GetPubKey());
     fifteenSigops << OP_15 << OP_CHECKMULTISIG;
     keystore.AddCScript(fifteenSigops);
     txFrom.vout[4].scriptPubKey =
         GetScriptForDestination(CScriptID(fifteenSigops));
     txFrom.vout[4].nValue = 5000;
 
     // vout[5/6] are non-standard because they exceed MAX_P2SH_SIGOPS
     CScript sixteenSigops;
     sixteenSigops << OP_16 << OP_CHECKMULTISIG;
     keystore.AddCScript(sixteenSigops);
     txFrom.vout[5].scriptPubKey =
         GetScriptForDestination(CScriptID(fifteenSigops));
     txFrom.vout[5].nValue = 5000;
     CScript twentySigops;
     twentySigops << OP_CHECKMULTISIG;
     keystore.AddCScript(twentySigops);
     txFrom.vout[6].scriptPubKey =
         GetScriptForDestination(CScriptID(twentySigops));
     txFrom.vout[6].nValue = 6000;
 
     coins.ModifyCoins(txFrom.GetId())->FromTx(txFrom, 0);
 
     CMutableTransaction txTo;
     txTo.vout.resize(1);
     txTo.vout[0].scriptPubKey =
         GetScriptForDestination(key[1].GetPubKey().GetID());
 
     txTo.vin.resize(5);
     for (int i = 0; i < 5; i++) {
         txTo.vin[i].prevout.n = i;
         txTo.vin[i].prevout.hash = txFrom.GetId();
     }
     BOOST_CHECK(
         SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL | SIGHASH_FORKID));
     BOOST_CHECK(
         SignSignature(keystore, txFrom, txTo, 1, SIGHASH_ALL | SIGHASH_FORKID));
     BOOST_CHECK(
         SignSignature(keystore, txFrom, txTo, 2, SIGHASH_ALL | SIGHASH_FORKID));
     // SignSignature doesn't know how to sign these. We're not testing
     // validating signatures, so just create dummy signatures that DO include
     // the correct P2SH scripts:
     txTo.vin[3].scriptSig << OP_11 << OP_11
-                          << std::vector<unsigned char>(oneAndTwo.begin(),
-                                                        oneAndTwo.end());
-    txTo.vin[4].scriptSig << std::vector<unsigned char>(fifteenSigops.begin(),
-                                                        fifteenSigops.end());
+                          << std::vector<uint8_t>(oneAndTwo.begin(),
+                                                  oneAndTwo.end());
+    txTo.vin[4].scriptSig << std::vector<uint8_t>(fifteenSigops.begin(),
+                                                  fifteenSigops.end());
 
     BOOST_CHECK(::AreInputsStandard(txTo, coins));
     // 22 P2SH sigops for all inputs (1 for vin[0], 6 for vin[3], 15 for vin[4]
     BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txTo, coins), 22U);
 
     CMutableTransaction txToNonStd1;
     txToNonStd1.vout.resize(1);
     txToNonStd1.vout[0].scriptPubKey =
         GetScriptForDestination(key[1].GetPubKey().GetID());
     txToNonStd1.vout[0].nValue = 1000;
     txToNonStd1.vin.resize(1);
     txToNonStd1.vin[0].prevout.n = 5;
     txToNonStd1.vin[0].prevout.hash = txFrom.GetId();
-    txToNonStd1.vin[0].scriptSig << std::vector<unsigned char>(
-        sixteenSigops.begin(), sixteenSigops.end());
+    txToNonStd1.vin[0].scriptSig
+        << std::vector<uint8_t>(sixteenSigops.begin(), sixteenSigops.end());
 
     BOOST_CHECK(!::AreInputsStandard(txToNonStd1, coins));
     BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txToNonStd1, coins), 16U);
 
     CMutableTransaction txToNonStd2;
     txToNonStd2.vout.resize(1);
     txToNonStd2.vout[0].scriptPubKey =
         GetScriptForDestination(key[1].GetPubKey().GetID());
     txToNonStd2.vout[0].nValue = 1000;
     txToNonStd2.vin.resize(1);
     txToNonStd2.vin[0].prevout.n = 6;
     txToNonStd2.vin[0].prevout.hash = txFrom.GetId();
     txToNonStd2.vin[0].scriptSig
-        << std::vector<unsigned char>(twentySigops.begin(), twentySigops.end());
+        << std::vector<uint8_t>(twentySigops.begin(), twentySigops.end());
 
     BOOST_CHECK(!::AreInputsStandard(txToNonStd2, coins));
     BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txToNonStd2, coins), 20U);
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/script_antireplay_tests.cpp b/src/test/script_antireplay_tests.cpp
index c3cbb9eb1..083136394 100644
--- a/src/test/script_antireplay_tests.cpp
+++ b/src/test/script_antireplay_tests.cpp
@@ -1,152 +1,152 @@
 // Copyright (c) 2017 The Bitcoin developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #include "script/script.h"
 #include "test/test_bitcoin.h"
 
 #include "chainparams.h"
 #include "config.h"
 #include "consensus/validation.h"
 #include "validation.h"
 
 #include <boost/test/unit_test.hpp>
 
 #include <string>
 #include <vector>
 
 BOOST_FIXTURE_TEST_SUITE(script_antireplay_tests, BasicTestingSetup)
 
 BOOST_AUTO_TEST_CASE(test_is_commitment) {
-    std::vector<unsigned char> data{};
+    std::vector<uint8_t> data{};
 
     // Empty commitment.
     auto s = CScript() << OP_RETURN << data;
     BOOST_CHECK(s.IsCommitment(data));
 
     // Commitment to a value of the wrong size.
     data.push_back(42);
     BOOST_CHECK(!s.IsCommitment(data));
 
     // Not a commitment.
     s = CScript() << data;
     BOOST_CHECK(!s.IsCommitment(data));
 
     // Non empty commitment.
     s = CScript() << OP_RETURN << data;
     BOOST_CHECK(s.IsCommitment(data));
 
     // Commitment to the wrong value.
     data[0] = 0x42;
     BOOST_CHECK(!s.IsCommitment(data));
 
     // Commitment to a larger value.
     std::string str = "Bitcoin: A peer-to-peer Electronic Cash System";
-    data = std::vector<unsigned char>(str.begin(), str.end());
+    data = std::vector<uint8_t>(str.begin(), str.end());
     BOOST_CHECK(!s.IsCommitment(data));
 
     s = CScript() << OP_RETURN << data;
     BOOST_CHECK(s.IsCommitment(data));
 
     // 64 bytes commitment, still valid.
     data.resize(64);
     s = CScript() << OP_RETURN << data;
     BOOST_CHECK(s.IsCommitment(data));
 
     // Commitment is too large.
     data.push_back(23);
     s = CScript() << OP_RETURN << data;
     BOOST_CHECK(!s.IsCommitment(data));
 
     // Check with the actual replay commitment we are going to use.
     SelectParams(CBaseChainParams::MAIN);
     const Consensus::Params &params = Params().GetConsensus();
     s = CScript() << OP_RETURN << params.antiReplayOpReturnCommitment;
     BOOST_CHECK(s.IsCommitment(params.antiReplayOpReturnCommitment));
 }
 
 BOOST_AUTO_TEST_CASE(test_antireplay) {
     SelectParams(CBaseChainParams::MAIN);
 
     GlobalConfig config;
     const Consensus::Params &params = config.GetChainParams().GetConsensus();
 
     // The anti replay rule start at hfStartTime and stops at
     // antiReplayOpReturnSunsetHeight.
     const int nSunsetHeight = params.antiReplayOpReturnSunsetHeight;
     const int64_t nUAHFStartTime = config.GetUAHFStartTime();
 
     CMutableTransaction tx;
     tx.nVersion = 1;
     tx.vin.resize(1);
     tx.vin[0].prevout.hash = GetRandHash();
     tx.vin[0].prevout.n = 0;
     tx.vin[0].scriptSig = CScript();
     tx.vout.resize(1);
     tx.vout[0].nValue = 1;
     tx.vout[0].scriptPubKey = CScript();
 
     {
         // Base transaction is valid.
         CValidationState state;
         BOOST_CHECK(ContextualCheckTransaction(config, tx, state, params,
                                                nSunsetHeight, nUAHFStartTime,
                                                nUAHFStartTime));
     }
 
     {
         // Base transaction is still valid after sunset.
         CValidationState state;
         BOOST_CHECK(ContextualCheckTransaction(config, tx, state, params,
                                                nSunsetHeight + 1,
                                                nUAHFStartTime, nUAHFStartTime));
     }
 
     {
         // Base transaction is valid before the fork.
         CValidationState state;
         BOOST_CHECK(
             ContextualCheckTransaction(config, tx, state, params, nSunsetHeight,
                                        nUAHFStartTime - 1, nUAHFStartTime - 1));
     }
 
     tx.vout[0].scriptPubKey = CScript() << OP_RETURN << OP_0;
 
     {
         // Wrong commitment, still valid.
         CValidationState state;
         BOOST_CHECK(ContextualCheckTransaction(config, tx, state, params,
                                                nSunsetHeight, nUAHFStartTime,
                                                nUAHFStartTime));
     }
 
     tx.vout[0].scriptPubKey = CScript() << OP_RETURN
                                         << params.antiReplayOpReturnCommitment;
 
     {
         // Anti replay commitment, not valid anymore.
         CValidationState state;
         BOOST_CHECK(!ContextualCheckTransaction(config, tx, state, params,
                                                 nSunsetHeight, nUAHFStartTime,
                                                 nUAHFStartTime));
         BOOST_CHECK_EQUAL(state.GetRejectReason(), "bad-txn-replay");
     }
 
     {
         // Anti replay commitment, disabled before start time.
         CValidationState state;
         BOOST_CHECK(
             ContextualCheckTransaction(config, tx, state, params, nSunsetHeight,
                                        nUAHFStartTime - 1, nUAHFStartTime - 1));
     }
 
     {
         // Anti replay commitment, disabled after sunset.
         CValidationState state;
         BOOST_CHECK(ContextualCheckTransaction(config, tx, state, params,
                                                nSunsetHeight + 1,
                                                nUAHFStartTime, nUAHFStartTime));
     }
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index 9d6bc3abc..ab867e329 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -1,1813 +1,1807 @@
 // Copyright (c) 2011-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.
 
 #include "data/script_tests.json.h"
 
 #include "core_io.h"
 #include "key.h"
 #include "keystore.h"
 #include "rpc/server.h"
 #include "script/script.h"
 #include "script/script_error.h"
 #include "script/sign.h"
 #include "test/scriptflags.h"
 #include "test/test_bitcoin.h"
 #include "util.h"
 #include "utilstrencodings.h"
 
 #if defined(HAVE_CONSENSUS_LIB)
 #include "script/bitcoinconsensus.h"
 #endif
 
 #include <cstdint>
 #include <fstream>
 #include <string>
 #include <vector>
 
 #include <boost/test/unit_test.hpp>
 
 #include <univalue.h>
 
 // Uncomment if you want to output updated JSON tests.
 // #define UPDATE_JSON_TESTS
 
 static const unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC;
 
 UniValue read_json(const std::string &jsondata) {
     UniValue v;
 
     if (!v.read(jsondata) || !v.isArray()) {
         BOOST_ERROR("Parse error.");
         return UniValue(UniValue::VARR);
     }
     return v.get_array();
 }
 
 struct ScriptErrorDesc {
     ScriptError_t err;
     const char *name;
 };
 
 static ScriptErrorDesc script_errors[] = {
     {SCRIPT_ERR_OK, "OK"},
     {SCRIPT_ERR_UNKNOWN_ERROR, "UNKNOWN_ERROR"},
     {SCRIPT_ERR_EVAL_FALSE, "EVAL_FALSE"},
     {SCRIPT_ERR_OP_RETURN, "OP_RETURN"},
     {SCRIPT_ERR_SCRIPT_SIZE, "SCRIPT_SIZE"},
     {SCRIPT_ERR_PUSH_SIZE, "PUSH_SIZE"},
     {SCRIPT_ERR_OP_COUNT, "OP_COUNT"},
     {SCRIPT_ERR_STACK_SIZE, "STACK_SIZE"},
     {SCRIPT_ERR_SIG_COUNT, "SIG_COUNT"},
     {SCRIPT_ERR_PUBKEY_COUNT, "PUBKEY_COUNT"},
     {SCRIPT_ERR_VERIFY, "VERIFY"},
     {SCRIPT_ERR_EQUALVERIFY, "EQUALVERIFY"},
     {SCRIPT_ERR_CHECKMULTISIGVERIFY, "CHECKMULTISIGVERIFY"},
     {SCRIPT_ERR_CHECKSIGVERIFY, "CHECKSIGVERIFY"},
     {SCRIPT_ERR_NUMEQUALVERIFY, "NUMEQUALVERIFY"},
     {SCRIPT_ERR_BAD_OPCODE, "BAD_OPCODE"},
     {SCRIPT_ERR_DISABLED_OPCODE, "DISABLED_OPCODE"},
     {SCRIPT_ERR_INVALID_STACK_OPERATION, "INVALID_STACK_OPERATION"},
     {SCRIPT_ERR_INVALID_ALTSTACK_OPERATION, "INVALID_ALTSTACK_OPERATION"},
     {SCRIPT_ERR_UNBALANCED_CONDITIONAL, "UNBALANCED_CONDITIONAL"},
     {SCRIPT_ERR_NEGATIVE_LOCKTIME, "NEGATIVE_LOCKTIME"},
     {SCRIPT_ERR_UNSATISFIED_LOCKTIME, "UNSATISFIED_LOCKTIME"},
     {SCRIPT_ERR_SIG_HASHTYPE, "SIG_HASHTYPE"},
     {SCRIPT_ERR_SIG_DER, "SIG_DER"},
     {SCRIPT_ERR_MINIMALDATA, "MINIMALDATA"},
     {SCRIPT_ERR_SIG_PUSHONLY, "SIG_PUSHONLY"},
     {SCRIPT_ERR_SIG_HIGH_S, "SIG_HIGH_S"},
     {SCRIPT_ERR_SIG_NULLDUMMY, "SIG_NULLDUMMY"},
     {SCRIPT_ERR_PUBKEYTYPE, "PUBKEYTYPE"},
     {SCRIPT_ERR_CLEANSTACK, "CLEANSTACK"},
     {SCRIPT_ERR_MINIMALIF, "MINIMALIF"},
     {SCRIPT_ERR_SIG_NULLFAIL, "NULLFAIL"},
     {SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS, "DISCOURAGE_UPGRADABLE_NOPS"},
     {SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM,
      "DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"},
     {SCRIPT_ERR_NONCOMPRESSED_PUBKEY, "NONCOMPRESSED_PUBKEY"},
     {SCRIPT_ERR_ILLEGAL_FORKID, "ILLEGAL_FORKID"},
     {SCRIPT_ERR_MUST_USE_FORKID, "MISSING_FORKID"},
 };
 
 const char *FormatScriptError(ScriptError_t err) {
     for (size_t i = 0; i < ARRAYLEN(script_errors); ++i) {
         if (script_errors[i].err == err) {
             return script_errors[i].name;
         }
     }
 
     BOOST_ERROR("Unknown scripterror enumeration value, update script_errors "
                 "in script_tests.cpp.");
     return "";
 }
 
 ScriptError_t ParseScriptError(const std::string &name) {
     for (size_t i = 0; i < ARRAYLEN(script_errors); ++i) {
         if (script_errors[i].name == name) {
             return script_errors[i].err;
         }
     }
 
     BOOST_ERROR("Unknown scripterror \"" << name << "\" in test description");
     return SCRIPT_ERR_UNKNOWN_ERROR;
 }
 
 BOOST_FIXTURE_TEST_SUITE(script_tests, BasicTestingSetup)
 
 static CMutableTransaction
 BuildCreditingTransaction(const CScript &scriptPubKey, CAmount nValue) {
     CMutableTransaction txCredit;
     txCredit.nVersion = 1;
     txCredit.nLockTime = 0;
     txCredit.vin.resize(1);
     txCredit.vout.resize(1);
     txCredit.vin[0].prevout.SetNull();
     txCredit.vin[0].scriptSig = CScript() << CScriptNum(0) << CScriptNum(0);
     txCredit.vin[0].nSequence = CTxIn::SEQUENCE_FINAL;
     txCredit.vout[0].scriptPubKey = scriptPubKey;
     txCredit.vout[0].nValue = nValue;
 
     return txCredit;
 }
 
 static CMutableTransaction
 BuildSpendingTransaction(const CScript &scriptSig,
                          const CMutableTransaction &txCredit) {
     CMutableTransaction txSpend;
     txSpend.nVersion = 1;
     txSpend.nLockTime = 0;
     txSpend.vin.resize(1);
     txSpend.vout.resize(1);
     txSpend.vin[0].prevout.hash = txCredit.GetId();
     txSpend.vin[0].prevout.n = 0;
     txSpend.vin[0].scriptSig = scriptSig;
     txSpend.vin[0].nSequence = CTxIn::SEQUENCE_FINAL;
     txSpend.vout[0].scriptPubKey = CScript();
     txSpend.vout[0].nValue = txCredit.vout[0].nValue;
 
     return txSpend;
 }
 
 static void DoTest(const CScript &scriptPubKey, const CScript &scriptSig,
                    int flags, const std::string &message, int scriptError,
                    CAmount nValue) {
     bool expect = (scriptError == SCRIPT_ERR_OK);
     if (flags & SCRIPT_VERIFY_CLEANSTACK) {
         flags |= SCRIPT_VERIFY_P2SH;
     }
 
     ScriptError err;
     CMutableTransaction txCredit =
         BuildCreditingTransaction(scriptPubKey, nValue);
     CMutableTransaction tx = BuildSpendingTransaction(scriptSig, txCredit);
     CMutableTransaction tx2 = tx;
     BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags,
                                      MutableTransactionSignatureChecker(
                                          &tx, 0, txCredit.vout[0].nValue),
                                      &err) == expect,
                         message);
     BOOST_CHECK_MESSAGE(
         err == scriptError,
         std::string(FormatScriptError(err)) + " where " +
             std::string(FormatScriptError((ScriptError_t)scriptError)) +
             " expected: " + message);
 #if defined(HAVE_CONSENSUS_LIB)
     CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
     stream << tx2;
     int libconsensus_flags = flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_ALL;
     if (libconsensus_flags == flags) {
         if (flags & bitcoinconsensus_SCRIPT_ENABLE_SIGHASH_FORKID) {
-            BOOST_CHECK_MESSAGE(
-                bitcoinconsensus_verify_script_with_amount(
-                    scriptPubKey.data(), scriptPubKey.size(),
-                    txCredit.vout[0].nValue, (const unsigned char *)&stream[0],
-                    stream.size(), 0, libconsensus_flags, nullptr) == expect,
-                message);
+            BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(
+                                    scriptPubKey.data(), scriptPubKey.size(),
+                                    txCredit.vout[0].nValue,
+                                    (const uint8_t *)&stream[0], stream.size(),
+                                    0, libconsensus_flags, nullptr) == expect,
+                                message);
         } else {
             BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(
                                     scriptPubKey.data(), scriptPubKey.size(), 0,
-                                    (const unsigned char *)&stream[0],
-                                    stream.size(), 0, libconsensus_flags,
-                                    nullptr) == expect,
+                                    (const uint8_t *)&stream[0], stream.size(),
+                                    0, libconsensus_flags, nullptr) == expect,
                                 message);
             BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(
                                     scriptPubKey.data(), scriptPubKey.size(),
-                                    (const unsigned char *)&stream[0],
-                                    stream.size(), 0, libconsensus_flags,
-                                    nullptr) == expect,
+                                    (const uint8_t *)&stream[0], stream.size(),
+                                    0, libconsensus_flags, nullptr) == expect,
                                 message);
         }
     }
 #endif
 }
 
-static void NegateSignatureS(std::vector<unsigned char> &vchSig) {
+static void NegateSignatureS(std::vector<uint8_t> &vchSig) {
     // Parse the signature.
-    std::vector<unsigned char> r, s;
-    r = std::vector<unsigned char>(vchSig.begin() + 4,
-                                   vchSig.begin() + 4 + vchSig[3]);
-    s = std::vector<unsigned char>(vchSig.begin() + 6 + vchSig[3],
-                                   vchSig.begin() + 6 + vchSig[3] +
-                                       vchSig[5 + vchSig[3]]);
+    std::vector<uint8_t> r, s;
+    r = std::vector<uint8_t>(vchSig.begin() + 4,
+                             vchSig.begin() + 4 + vchSig[3]);
+    s = std::vector<uint8_t>(vchSig.begin() + 6 + vchSig[3],
+                             vchSig.begin() + 6 + vchSig[3] +
+                                 vchSig[5 + vchSig[3]]);
 
     // Really ugly to implement mod-n negation here, but it would be feature
     // creep to expose such functionality from libsecp256k1.
-    static const unsigned char order[33] = {
+    static const uint8_t order[33] = {
         0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF,
         0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41};
     while (s.size() < 33) {
         s.insert(s.begin(), 0x00);
     }
 
     int carry = 0;
     for (int p = 32; p >= 1; p--) {
         int n = (int)order[p] - s[p] - carry;
         s[p] = (n + 256) & 0xFF;
         carry = (n < 0);
     }
 
     assert(carry == 0);
     if (s.size() > 1 && s[0] == 0 && s[1] < 0x80) {
         s.erase(s.begin());
     }
 
     // Reconstruct the signature.
     vchSig.clear();
     vchSig.push_back(0x30);
     vchSig.push_back(4 + r.size() + s.size());
     vchSig.push_back(0x02);
     vchSig.push_back(r.size());
     vchSig.insert(vchSig.end(), r.begin(), r.end());
     vchSig.push_back(0x02);
     vchSig.push_back(s.size());
     vchSig.insert(vchSig.end(), s.begin(), s.end());
 }
 
 namespace {
-const unsigned char vchKey0[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                                   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                                   0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
-const unsigned char vchKey1[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                                   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                                   0, 0, 0, 0, 0, 0, 0, 0, 1, 0};
-const unsigned char vchKey2[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                                   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                                   0, 0, 0, 0, 0, 0, 0, 1, 0, 0};
+const uint8_t vchKey0[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
+const uint8_t vchKey1[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0};
+const uint8_t vchKey2[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0};
 
 struct KeyData {
     CKey key0, key0C, key1, key1C, key2, key2C;
     CPubKey pubkey0, pubkey0C, pubkey0H;
     CPubKey pubkey1, pubkey1C;
     CPubKey pubkey2, pubkey2C;
 
     KeyData() {
 
         key0.Set(vchKey0, vchKey0 + 32, false);
         key0C.Set(vchKey0, vchKey0 + 32, true);
         pubkey0 = key0.GetPubKey();
         pubkey0H = key0.GetPubKey();
         pubkey0C = key0C.GetPubKey();
-        *const_cast<unsigned char *>(&pubkey0H[0]) = 0x06 | (pubkey0H[64] & 1);
+        *const_cast<uint8_t *>(&pubkey0H[0]) = 0x06 | (pubkey0H[64] & 1);
 
         key1.Set(vchKey1, vchKey1 + 32, false);
         key1C.Set(vchKey1, vchKey1 + 32, true);
         pubkey1 = key1.GetPubKey();
         pubkey1C = key1C.GetPubKey();
 
         key2.Set(vchKey2, vchKey2 + 32, false);
         key2C.Set(vchKey2, vchKey2 + 32, true);
         pubkey2 = key2.GetPubKey();
         pubkey2C = key2C.GetPubKey();
     }
 };
 
 class TestBuilder {
 private:
     //! Actually executed script
     CScript script;
     //! The P2SH redeemscript
     CScript redeemscript;
     CTransactionRef creditTx;
     CMutableTransaction spendTx;
     bool havePush;
-    std::vector<unsigned char> push;
+    std::vector<uint8_t> push;
     std::string comment;
     int flags;
     int scriptError;
     CAmount nValue;
 
     void DoPush() {
         if (havePush) {
             spendTx.vin[0].scriptSig << push;
             havePush = false;
         }
     }
 
-    void DoPush(const std::vector<unsigned char> &data) {
+    void DoPush(const std::vector<uint8_t> &data) {
         DoPush();
         push = data;
         havePush = true;
     }
 
 public:
     TestBuilder(const CScript &script_, const std::string &comment_, int flags_,
                 bool P2SH = false, CAmount nValue_ = 0)
         : script(script_), havePush(false), comment(comment_), flags(flags_),
           scriptError(SCRIPT_ERR_OK), nValue(nValue_) {
         CScript scriptPubKey = script;
         if (P2SH) {
             redeemscript = scriptPubKey;
             scriptPubKey = CScript() << OP_HASH160
                                      << ToByteVector(CScriptID(redeemscript))
                                      << OP_EQUAL;
         }
         creditTx =
             MakeTransactionRef(BuildCreditingTransaction(scriptPubKey, nValue));
         spendTx = BuildSpendingTransaction(CScript(), *creditTx);
     }
 
     TestBuilder &ScriptError(ScriptError_t err) {
         scriptError = err;
         return *this;
     }
 
     TestBuilder &Add(const CScript &_script) {
         DoPush();
         spendTx.vin[0].scriptSig += _script;
         return *this;
     }
 
     TestBuilder &Num(int num) {
         DoPush();
         spendTx.vin[0].scriptSig << num;
         return *this;
     }
 
     TestBuilder &Push(const std::string &hex) {
         DoPush(ParseHex(hex));
         return *this;
     }
 
     TestBuilder &Push(const CScript &_script) {
-        DoPush(std::vector<unsigned char>(_script.begin(), _script.end()));
+        DoPush(std::vector<uint8_t>(_script.begin(), _script.end()));
         return *this;
     }
 
     TestBuilder &PushSig(const CKey &key, int nHashType = SIGHASH_ALL,
                          unsigned int lenR = 32, unsigned int lenS = 32,
                          CAmount amount = 0) {
         uint256 hash = SignatureHash(script, spendTx, 0, nHashType, amount);
-        std::vector<unsigned char> vchSig, r, s;
+        std::vector<uint8_t> vchSig, r, s;
         uint32_t iter = 0;
         do {
             key.Sign(hash, vchSig, iter++);
             if ((lenS == 33) != (vchSig[5 + vchSig[3]] == 33)) {
                 NegateSignatureS(vchSig);
             }
 
-            r = std::vector<unsigned char>(vchSig.begin() + 4,
-                                           vchSig.begin() + 4 + vchSig[3]);
-            s = std::vector<unsigned char>(vchSig.begin() + 6 + vchSig[3],
-                                           vchSig.begin() + 6 + vchSig[3] +
-                                               vchSig[5 + vchSig[3]]);
+            r = std::vector<uint8_t>(vchSig.begin() + 4,
+                                     vchSig.begin() + 4 + vchSig[3]);
+            s = std::vector<uint8_t>(vchSig.begin() + 6 + vchSig[3],
+                                     vchSig.begin() + 6 + vchSig[3] +
+                                         vchSig[5 + vchSig[3]]);
         } while (lenR != r.size() || lenS != s.size());
 
-        vchSig.push_back(static_cast<unsigned char>(nHashType));
+        vchSig.push_back(static_cast<uint8_t>(nHashType));
         DoPush(vchSig);
         return *this;
     }
 
     TestBuilder &Push(const CPubKey &pubkey) {
-        DoPush(std::vector<unsigned char>(pubkey.begin(), pubkey.end()));
+        DoPush(std::vector<uint8_t>(pubkey.begin(), pubkey.end()));
         return *this;
     }
 
     TestBuilder &PushRedeem() {
-        DoPush(std::vector<unsigned char>(redeemscript.begin(),
-                                          redeemscript.end()));
+        DoPush(std::vector<uint8_t>(redeemscript.begin(), redeemscript.end()));
         return *this;
     }
 
     TestBuilder &EditPush(unsigned int pos, const std::string &hexin,
                           const std::string &hexout) {
         assert(havePush);
-        std::vector<unsigned char> datain = ParseHex(hexin);
-        std::vector<unsigned char> dataout = ParseHex(hexout);
+        std::vector<uint8_t> datain = ParseHex(hexin);
+        std::vector<uint8_t> dataout = ParseHex(hexout);
         assert(pos + datain.size() <= push.size());
-        BOOST_CHECK_MESSAGE(std::vector<unsigned char>(
-                                push.begin() + pos,
-                                push.begin() + pos + datain.size()) == datain,
-                            comment);
+        BOOST_CHECK_MESSAGE(
+            std::vector<uint8_t>(push.begin() + pos,
+                                 push.begin() + pos + datain.size()) == datain,
+            comment);
         push.erase(push.begin() + pos, push.begin() + pos + datain.size());
         push.insert(push.begin() + pos, dataout.begin(), dataout.end());
         return *this;
     }
 
     TestBuilder &DamagePush(unsigned int pos) {
         assert(havePush);
         assert(pos < push.size());
         push[pos] ^= 1;
         return *this;
     }
 
     TestBuilder &Test() {
         // Make a copy so we can rollback the push.
         TestBuilder copy = *this;
         DoPush();
         DoTest(creditTx->vout[0].scriptPubKey, spendTx.vin[0].scriptSig, flags,
                comment, scriptError, nValue);
         *this = copy;
         return *this;
     }
 
     UniValue GetJSON() {
         DoPush();
         UniValue array(UniValue::VARR);
         if (nValue != 0) {
             UniValue amount(UniValue::VARR);
             amount.push_back(ValueFromAmount(nValue));
             array.push_back(amount);
         }
 
         array.push_back(FormatScript(spendTx.vin[0].scriptSig));
         array.push_back(FormatScript(creditTx->vout[0].scriptPubKey));
         array.push_back(FormatScriptFlags(flags));
         array.push_back(FormatScriptError((ScriptError_t)scriptError));
         array.push_back(comment);
         return array;
     }
 
     std::string GetComment() { return comment; }
 
     const CScript &GetScriptPubKey() { return creditTx->vout[0].scriptPubKey; }
 };
 
 std::string JSONPrettyPrint(const UniValue &univalue) {
     std::string ret = univalue.write(4);
     // Workaround for libunivalue pretty printer, which puts a space between
     // commas and newlines
     size_t pos = 0;
     while ((pos = ret.find(" \n", pos)) != std::string::npos) {
         ret.replace(pos, 2, "\n");
         pos++;
     }
 
     return ret;
 }
 }
 
 BOOST_AUTO_TEST_CASE(script_build) {
     const KeyData keys;
 
     std::vector<TestBuilder> tests;
 
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
                     "P2PK", 0)
             .PushSig(keys.key0));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
                     "P2PK, bad sig", 0)
             .PushSig(keys.key0)
             .DamagePush(10)
             .ScriptError(SCRIPT_ERR_EVAL_FALSE));
 
     tests.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160
                                           << ToByteVector(keys.pubkey1C.GetID())
                                           << OP_EQUALVERIFY << OP_CHECKSIG,
                                 "P2PKH", 0)
                         .PushSig(keys.key1)
                         .Push(keys.pubkey1C));
     tests.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160
                                           << ToByteVector(keys.pubkey2C.GetID())
                                           << OP_EQUALVERIFY << OP_CHECKSIG,
                                 "P2PKH, bad pubkey", 0)
                         .PushSig(keys.key2)
                         .Push(keys.pubkey2C)
                         .DamagePush(5)
                         .ScriptError(SCRIPT_ERR_EQUALVERIFY));
 
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
                     "P2PK anyonecanpay", 0)
             .PushSig(keys.key1, SIGHASH_ALL | SIGHASH_ANYONECANPAY));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
                     "P2PK anyonecanpay marked with normal hashtype", 0)
             .PushSig(keys.key1, SIGHASH_ALL | SIGHASH_ANYONECANPAY)
             .EditPush(70, "81", "01")
             .ScriptError(SCRIPT_ERR_EVAL_FALSE));
 
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG,
                     "P2SH(P2PK)", SCRIPT_VERIFY_P2SH, true)
             .PushSig(keys.key0)
             .PushRedeem());
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG,
                     "P2SH(P2PK), bad redeemscript", SCRIPT_VERIFY_P2SH, true)
             .PushSig(keys.key0)
             .PushRedeem()
             .DamagePush(10)
             .ScriptError(SCRIPT_ERR_EVAL_FALSE));
 
     tests.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160
                                           << ToByteVector(keys.pubkey0.GetID())
                                           << OP_EQUALVERIFY << OP_CHECKSIG,
                                 "P2SH(P2PKH)", SCRIPT_VERIFY_P2SH, true)
                         .PushSig(keys.key0)
                         .Push(keys.pubkey0)
                         .PushRedeem());
     tests.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160
                                           << ToByteVector(keys.pubkey1.GetID())
                                           << OP_EQUALVERIFY << OP_CHECKSIG,
                                 "P2SH(P2PKH), bad sig but no VERIFY_P2SH", 0,
                                 true)
                         .PushSig(keys.key0)
                         .DamagePush(10)
                         .PushRedeem());
     tests.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160
                                           << ToByteVector(keys.pubkey1.GetID())
                                           << OP_EQUALVERIFY << OP_CHECKSIG,
                                 "P2SH(P2PKH), bad sig", SCRIPT_VERIFY_P2SH,
                                 true)
                         .PushSig(keys.key0)
                         .DamagePush(10)
                         .PushRedeem()
                         .ScriptError(SCRIPT_ERR_EQUALVERIFY));
 
     tests.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C)
                                           << ToByteVector(keys.pubkey1C)
                                           << ToByteVector(keys.pubkey2C) << OP_3
                                           << OP_CHECKMULTISIG,
                                 "3-of-3", 0)
                         .Num(0)
                         .PushSig(keys.key0)
                         .PushSig(keys.key1)
                         .PushSig(keys.key2));
     tests.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C)
                                           << ToByteVector(keys.pubkey1C)
                                           << ToByteVector(keys.pubkey2C) << OP_3
                                           << OP_CHECKMULTISIG,
                                 "3-of-3, 2 sigs", 0)
                         .Num(0)
                         .PushSig(keys.key0)
                         .PushSig(keys.key1)
                         .Num(0)
                         .ScriptError(SCRIPT_ERR_EVAL_FALSE));
 
     tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C)
                                           << ToByteVector(keys.pubkey1C)
                                           << ToByteVector(keys.pubkey2C) << OP_3
                                           << OP_CHECKMULTISIG,
                                 "P2SH(2-of-3)", SCRIPT_VERIFY_P2SH, true)
                         .Num(0)
                         .PushSig(keys.key1)
                         .PushSig(keys.key2)
                         .PushRedeem());
     tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C)
                                           << ToByteVector(keys.pubkey1C)
                                           << ToByteVector(keys.pubkey2C) << OP_3
                                           << OP_CHECKMULTISIG,
                                 "P2SH(2-of-3), 1 sig", SCRIPT_VERIFY_P2SH, true)
                         .Num(0)
                         .PushSig(keys.key1)
                         .Num(0)
                         .PushRedeem()
                         .ScriptError(SCRIPT_ERR_EVAL_FALSE));
 
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
                     "P2PK with too much R padding but no DERSIG", 0)
             .PushSig(keys.key1, SIGHASH_ALL, 31, 32)
             .EditPush(1, "43021F", "44022000"));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
                     "P2PK with too much R padding", SCRIPT_VERIFY_DERSIG)
             .PushSig(keys.key1, SIGHASH_ALL, 31, 32)
             .EditPush(1, "43021F", "44022000")
             .ScriptError(SCRIPT_ERR_SIG_DER));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
                     "P2PK with too much S padding but no DERSIG", 0)
             .PushSig(keys.key1, SIGHASH_ALL)
             .EditPush(1, "44", "45")
             .EditPush(37, "20", "2100"));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
                     "P2PK with too much S padding", SCRIPT_VERIFY_DERSIG)
             .PushSig(keys.key1, SIGHASH_ALL)
             .EditPush(1, "44", "45")
             .EditPush(37, "20", "2100")
             .ScriptError(SCRIPT_ERR_SIG_DER));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
                     "P2PK with too little R padding but no DERSIG", 0)
             .PushSig(keys.key1, SIGHASH_ALL, 33, 32)
             .EditPush(1, "45022100", "440220"));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
                     "P2PK with too little R padding", SCRIPT_VERIFY_DERSIG)
             .PushSig(keys.key1, SIGHASH_ALL, 33, 32)
             .EditPush(1, "45022100", "440220")
             .ScriptError(SCRIPT_ERR_SIG_DER));
     tests.push_back(
         TestBuilder(
             CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT,
             "P2PK NOT with bad sig with too much R padding but no DERSIG", 0)
             .PushSig(keys.key2, SIGHASH_ALL, 31, 32)
             .EditPush(1, "43021F", "44022000")
             .DamagePush(10));
     tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C)
                                           << OP_CHECKSIG << OP_NOT,
                                 "P2PK NOT with bad sig with too much R padding",
                                 SCRIPT_VERIFY_DERSIG)
                         .PushSig(keys.key2, SIGHASH_ALL, 31, 32)
                         .EditPush(1, "43021F", "44022000")
                         .DamagePush(10)
                         .ScriptError(SCRIPT_ERR_SIG_DER));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG
                               << OP_NOT,
                     "P2PK NOT with too much R padding but no DERSIG", 0)
             .PushSig(keys.key2, SIGHASH_ALL, 31, 32)
             .EditPush(1, "43021F", "44022000")
             .ScriptError(SCRIPT_ERR_EVAL_FALSE));
     tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C)
                                           << OP_CHECKSIG << OP_NOT,
                                 "P2PK NOT with too much R padding",
                                 SCRIPT_VERIFY_DERSIG)
                         .PushSig(keys.key2, SIGHASH_ALL, 31, 32)
                         .EditPush(1, "43021F", "44022000")
                         .ScriptError(SCRIPT_ERR_SIG_DER));
 
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
                     "BIP66 example 1, without DERSIG", 0)
             .PushSig(keys.key1, SIGHASH_ALL, 33, 32)
             .EditPush(1, "45022100", "440220"));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
                     "BIP66 example 1, with DERSIG", SCRIPT_VERIFY_DERSIG)
             .PushSig(keys.key1, SIGHASH_ALL, 33, 32)
             .EditPush(1, "45022100", "440220")
             .ScriptError(SCRIPT_ERR_SIG_DER));
     tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C)
                                           << OP_CHECKSIG << OP_NOT,
                                 "BIP66 example 2, without DERSIG", 0)
                         .PushSig(keys.key1, SIGHASH_ALL, 33, 32)
                         .EditPush(1, "45022100", "440220")
                         .ScriptError(SCRIPT_ERR_EVAL_FALSE));
     tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C)
                                           << OP_CHECKSIG << OP_NOT,
                                 "BIP66 example 2, with DERSIG",
                                 SCRIPT_VERIFY_DERSIG)
                         .PushSig(keys.key1, SIGHASH_ALL, 33, 32)
                         .EditPush(1, "45022100", "440220")
                         .ScriptError(SCRIPT_ERR_SIG_DER));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
                     "BIP66 example 3, without DERSIG", 0)
             .Num(0)
             .ScriptError(SCRIPT_ERR_EVAL_FALSE));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
                     "BIP66 example 3, with DERSIG", SCRIPT_VERIFY_DERSIG)
             .Num(0)
             .ScriptError(SCRIPT_ERR_EVAL_FALSE));
     tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C)
                                           << OP_CHECKSIG << OP_NOT,
                                 "BIP66 example 4, without DERSIG", 0)
                         .Num(0));
     tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C)
                                           << OP_CHECKSIG << OP_NOT,
                                 "BIP66 example 4, with DERSIG",
                                 SCRIPT_VERIFY_DERSIG)
                         .Num(0));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
                     "BIP66 example 5, without DERSIG", 0)
             .Num(1)
             .ScriptError(SCRIPT_ERR_EVAL_FALSE));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
                     "BIP66 example 5, with DERSIG", SCRIPT_VERIFY_DERSIG)
             .Num(1)
             .ScriptError(SCRIPT_ERR_SIG_DER));
     tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C)
                                           << OP_CHECKSIG << OP_NOT,
                                 "BIP66 example 6, without DERSIG", 0)
                         .Num(1));
     tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C)
                                           << OP_CHECKSIG << OP_NOT,
                                 "BIP66 example 6, with DERSIG",
                                 SCRIPT_VERIFY_DERSIG)
                         .Num(1)
                         .ScriptError(SCRIPT_ERR_SIG_DER));
     tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C)
                                           << ToByteVector(keys.pubkey2C) << OP_2
                                           << OP_CHECKMULTISIG,
                                 "BIP66 example 7, without DERSIG", 0)
                         .Num(0)
                         .PushSig(keys.key1, SIGHASH_ALL, 33, 32)
                         .EditPush(1, "45022100", "440220")
                         .PushSig(keys.key2));
     tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C)
                                           << ToByteVector(keys.pubkey2C) << OP_2
                                           << OP_CHECKMULTISIG,
                                 "BIP66 example 7, with DERSIG",
                                 SCRIPT_VERIFY_DERSIG)
                         .Num(0)
                         .PushSig(keys.key1, SIGHASH_ALL, 33, 32)
                         .EditPush(1, "45022100", "440220")
                         .PushSig(keys.key2)
                         .ScriptError(SCRIPT_ERR_SIG_DER));
     tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C)
                                           << ToByteVector(keys.pubkey2C) << OP_2
                                           << OP_CHECKMULTISIG << OP_NOT,
                                 "BIP66 example 8, without DERSIG", 0)
                         .Num(0)
                         .PushSig(keys.key1, SIGHASH_ALL, 33, 32)
                         .EditPush(1, "45022100", "440220")
                         .PushSig(keys.key2)
                         .ScriptError(SCRIPT_ERR_EVAL_FALSE));
     tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C)
                                           << ToByteVector(keys.pubkey2C) << OP_2
                                           << OP_CHECKMULTISIG << OP_NOT,
                                 "BIP66 example 8, with DERSIG",
                                 SCRIPT_VERIFY_DERSIG)
                         .Num(0)
                         .PushSig(keys.key1, SIGHASH_ALL, 33, 32)
                         .EditPush(1, "45022100", "440220")
                         .PushSig(keys.key2)
                         .ScriptError(SCRIPT_ERR_SIG_DER));
     tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C)
                                           << ToByteVector(keys.pubkey2C) << OP_2
                                           << OP_CHECKMULTISIG,
                                 "BIP66 example 9, without DERSIG", 0)
                         .Num(0)
                         .Num(0)
                         .PushSig(keys.key2, SIGHASH_ALL, 33, 32)
                         .EditPush(1, "45022100", "440220")
                         .ScriptError(SCRIPT_ERR_EVAL_FALSE));
     tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C)
                                           << ToByteVector(keys.pubkey2C) << OP_2
                                           << OP_CHECKMULTISIG,
                                 "BIP66 example 9, with DERSIG",
                                 SCRIPT_VERIFY_DERSIG)
                         .Num(0)
                         .Num(0)
                         .PushSig(keys.key2, SIGHASH_ALL, 33, 32)
                         .EditPush(1, "45022100", "440220")
                         .ScriptError(SCRIPT_ERR_SIG_DER));
     tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C)
                                           << ToByteVector(keys.pubkey2C) << OP_2
                                           << OP_CHECKMULTISIG << OP_NOT,
                                 "BIP66 example 10, without DERSIG", 0)
                         .Num(0)
                         .Num(0)
                         .PushSig(keys.key2, SIGHASH_ALL, 33, 32)
                         .EditPush(1, "45022100", "440220"));
     tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C)
                                           << ToByteVector(keys.pubkey2C) << OP_2
                                           << OP_CHECKMULTISIG << OP_NOT,
                                 "BIP66 example 10, with DERSIG",
                                 SCRIPT_VERIFY_DERSIG)
                         .Num(0)
                         .Num(0)
                         .PushSig(keys.key2, SIGHASH_ALL, 33, 32)
                         .EditPush(1, "45022100", "440220")
                         .ScriptError(SCRIPT_ERR_SIG_DER));
     tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C)
                                           << ToByteVector(keys.pubkey2C) << OP_2
                                           << OP_CHECKMULTISIG,
                                 "BIP66 example 11, without DERSIG", 0)
                         .Num(0)
                         .PushSig(keys.key1, SIGHASH_ALL, 33, 32)
                         .EditPush(1, "45022100", "440220")
                         .Num(0)
                         .ScriptError(SCRIPT_ERR_EVAL_FALSE));
     tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C)
                                           << ToByteVector(keys.pubkey2C) << OP_2
                                           << OP_CHECKMULTISIG,
                                 "BIP66 example 11, with DERSIG",
                                 SCRIPT_VERIFY_DERSIG)
                         .Num(0)
                         .PushSig(keys.key1, SIGHASH_ALL, 33, 32)
                         .EditPush(1, "45022100", "440220")
                         .Num(0)
                         .ScriptError(SCRIPT_ERR_EVAL_FALSE));
     tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C)
                                           << ToByteVector(keys.pubkey2C) << OP_2
                                           << OP_CHECKMULTISIG << OP_NOT,
                                 "BIP66 example 12, without DERSIG", 0)
                         .Num(0)
                         .PushSig(keys.key1, SIGHASH_ALL, 33, 32)
                         .EditPush(1, "45022100", "440220")
                         .Num(0));
     tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C)
                                           << ToByteVector(keys.pubkey2C) << OP_2
                                           << OP_CHECKMULTISIG << OP_NOT,
                                 "BIP66 example 12, with DERSIG",
                                 SCRIPT_VERIFY_DERSIG)
                         .Num(0)
                         .PushSig(keys.key1, SIGHASH_ALL, 33, 32)
                         .EditPush(1, "45022100", "440220")
                         .Num(0));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
                     "P2PK with multi-byte hashtype, without DERSIG", 0)
             .PushSig(keys.key2, SIGHASH_ALL)
             .EditPush(70, "01", "0101"));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
                     "P2PK with multi-byte hashtype, with DERSIG",
                     SCRIPT_VERIFY_DERSIG)
             .PushSig(keys.key2, SIGHASH_ALL)
             .EditPush(70, "01", "0101")
             .ScriptError(SCRIPT_ERR_SIG_DER));
 
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
                     "P2PK with high S but no LOW_S", 0)
             .PushSig(keys.key2, SIGHASH_ALL, 32, 33));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
                     "P2PK with high S", SCRIPT_VERIFY_LOW_S)
             .PushSig(keys.key2, SIGHASH_ALL, 32, 33)
             .ScriptError(SCRIPT_ERR_SIG_HIGH_S));
 
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG,
                     "P2PK with hybrid pubkey but no STRICTENC", 0)
             .PushSig(keys.key0, SIGHASH_ALL));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG,
                     "P2PK with hybrid pubkey", SCRIPT_VERIFY_STRICTENC)
             .PushSig(keys.key0, SIGHASH_ALL)
             .ScriptError(SCRIPT_ERR_PUBKEYTYPE));
     tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H)
                                           << OP_CHECKSIG << OP_NOT,
                                 "P2PK NOT with hybrid pubkey but no STRICTENC",
                                 0)
                         .PushSig(keys.key0, SIGHASH_ALL)
                         .ScriptError(SCRIPT_ERR_EVAL_FALSE));
     tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H)
                                           << OP_CHECKSIG << OP_NOT,
                                 "P2PK NOT with hybrid pubkey",
                                 SCRIPT_VERIFY_STRICTENC)
                         .PushSig(keys.key0, SIGHASH_ALL)
                         .ScriptError(SCRIPT_ERR_PUBKEYTYPE));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG
                               << OP_NOT,
                     "P2PK NOT with invalid hybrid pubkey but no STRICTENC", 0)
             .PushSig(keys.key0, SIGHASH_ALL)
             .DamagePush(10));
     tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H)
                                           << OP_CHECKSIG << OP_NOT,
                                 "P2PK NOT with invalid hybrid pubkey",
                                 SCRIPT_VERIFY_STRICTENC)
                         .PushSig(keys.key0, SIGHASH_ALL)
                         .DamagePush(10)
                         .ScriptError(SCRIPT_ERR_PUBKEYTYPE));
     tests.push_back(
         TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey0H)
                               << ToByteVector(keys.pubkey1C) << OP_2
                               << OP_CHECKMULTISIG,
                     "1-of-2 with the second 1 hybrid pubkey and no STRICTENC",
                     0)
             .Num(0)
             .PushSig(keys.key1, SIGHASH_ALL));
     tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey0H)
                                           << ToByteVector(keys.pubkey1C) << OP_2
                                           << OP_CHECKMULTISIG,
                                 "1-of-2 with the second 1 hybrid pubkey",
                                 SCRIPT_VERIFY_STRICTENC)
                         .Num(0)
                         .PushSig(keys.key1, SIGHASH_ALL));
     tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C)
                                           << ToByteVector(keys.pubkey0H) << OP_2
                                           << OP_CHECKMULTISIG,
                                 "1-of-2 with the first 1 hybrid pubkey",
                                 SCRIPT_VERIFY_STRICTENC)
                         .Num(0)
                         .PushSig(keys.key1, SIGHASH_ALL)
                         .ScriptError(SCRIPT_ERR_PUBKEYTYPE));
 
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
                     "P2PK with undefined hashtype but no STRICTENC", 0)
             .PushSig(keys.key1, 5));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
                     "P2PK with undefined hashtype", SCRIPT_VERIFY_STRICTENC)
             .PushSig(keys.key1, 5)
             .ScriptError(SCRIPT_ERR_SIG_HASHTYPE));
     tests.push_back(
         TestBuilder(
             CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG << OP_NOT,
             "P2PK NOT with invalid sig and undefined hashtype but no STRICTENC",
             0)
             .PushSig(keys.key1, 5)
             .DamagePush(10));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG
                               << OP_NOT,
                     "P2PK NOT with invalid sig and undefined hashtype",
                     SCRIPT_VERIFY_STRICTENC)
             .PushSig(keys.key1, 5)
             .DamagePush(10)
             .ScriptError(SCRIPT_ERR_SIG_HASHTYPE));
 
     tests.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C)
                                           << ToByteVector(keys.pubkey1C)
                                           << ToByteVector(keys.pubkey2C) << OP_3
                                           << OP_CHECKMULTISIG,
                                 "3-of-3 with nonzero dummy but no NULLDUMMY", 0)
                         .Num(1)
                         .PushSig(keys.key0)
                         .PushSig(keys.key1)
                         .PushSig(keys.key2));
     tests.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C)
                                           << ToByteVector(keys.pubkey1C)
                                           << ToByteVector(keys.pubkey2C) << OP_3
                                           << OP_CHECKMULTISIG,
                                 "3-of-3 with nonzero dummy",
                                 SCRIPT_VERIFY_NULLDUMMY)
                         .Num(1)
                         .PushSig(keys.key0)
                         .PushSig(keys.key1)
                         .PushSig(keys.key2)
                         .ScriptError(SCRIPT_ERR_SIG_NULLDUMMY));
     tests.push_back(
         TestBuilder(
             CScript() << OP_3 << ToByteVector(keys.pubkey0C)
                       << ToByteVector(keys.pubkey1C)
                       << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG
                       << OP_NOT,
             "3-of-3 NOT with invalid sig and nonzero dummy but no NULLDUMMY", 0)
             .Num(1)
             .PushSig(keys.key0)
             .PushSig(keys.key1)
             .PushSig(keys.key2)
             .DamagePush(10));
     tests.push_back(
         TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C)
                               << ToByteVector(keys.pubkey1C)
                               << ToByteVector(keys.pubkey2C) << OP_3
                               << OP_CHECKMULTISIG << OP_NOT,
                     "3-of-3 NOT with invalid sig with nonzero dummy",
                     SCRIPT_VERIFY_NULLDUMMY)
             .Num(1)
             .PushSig(keys.key0)
             .PushSig(keys.key1)
             .PushSig(keys.key2)
             .DamagePush(10)
             .ScriptError(SCRIPT_ERR_SIG_NULLDUMMY));
 
     tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C)
                                           << ToByteVector(keys.pubkey1C) << OP_2
                                           << OP_CHECKMULTISIG,
                                 "2-of-2 with two identical keys and sigs "
                                 "pushed using OP_DUP but no SIGPUSHONLY",
                                 0)
                         .Num(0)
                         .PushSig(keys.key1)
                         .Add(CScript() << OP_DUP));
     tests.push_back(
         TestBuilder(
             CScript() << OP_2 << ToByteVector(keys.pubkey1C)
                       << ToByteVector(keys.pubkey1C) << OP_2
                       << OP_CHECKMULTISIG,
             "2-of-2 with two identical keys and sigs pushed using OP_DUP",
             SCRIPT_VERIFY_SIGPUSHONLY)
             .Num(0)
             .PushSig(keys.key1)
             .Add(CScript() << OP_DUP)
             .ScriptError(SCRIPT_ERR_SIG_PUSHONLY));
     tests.push_back(
         TestBuilder(
             CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
             "P2SH(P2PK) with non-push scriptSig but no P2SH or SIGPUSHONLY", 0,
             true)
             .PushSig(keys.key2)
             .Add(CScript() << OP_NOP8)
             .PushRedeem());
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
                     "P2PK with non-push scriptSig but with P2SH validation", 0)
             .PushSig(keys.key2)
             .Add(CScript() << OP_NOP8));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
                     "P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY",
                     SCRIPT_VERIFY_P2SH, true)
             .PushSig(keys.key2)
             .Add(CScript() << OP_NOP8)
             .PushRedeem()
             .ScriptError(SCRIPT_ERR_SIG_PUSHONLY));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
                     "P2SH(P2PK) with non-push scriptSig but not P2SH",
                     SCRIPT_VERIFY_SIGPUSHONLY, true)
             .PushSig(keys.key2)
             .Add(CScript() << OP_NOP8)
             .PushRedeem()
             .ScriptError(SCRIPT_ERR_SIG_PUSHONLY));
     tests.push_back(
         TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C)
                               << ToByteVector(keys.pubkey1C) << OP_2
                               << OP_CHECKMULTISIG,
                     "2-of-2 with two identical keys and sigs pushed",
                     SCRIPT_VERIFY_SIGPUSHONLY)
             .Num(0)
             .PushSig(keys.key1)
             .PushSig(keys.key1));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
                     "P2PK with unnecessary input but no CLEANSTACK",
                     SCRIPT_VERIFY_P2SH)
             .Num(11)
             .PushSig(keys.key0));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
                     "P2PK with unnecessary input",
                     SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH)
             .Num(11)
             .PushSig(keys.key0)
             .ScriptError(SCRIPT_ERR_CLEANSTACK));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
                     "P2SH with unnecessary input but no CLEANSTACK",
                     SCRIPT_VERIFY_P2SH, true)
             .Num(11)
             .PushSig(keys.key0)
             .PushRedeem());
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
                     "P2SH with unnecessary input",
                     SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH, true)
             .Num(11)
             .PushSig(keys.key0)
             .PushRedeem()
             .ScriptError(SCRIPT_ERR_CLEANSTACK));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
                     "P2SH with CLEANSTACK",
                     SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH, true)
             .PushSig(keys.key0)
             .PushRedeem());
 
     static const CAmount TEST_AMOUNT = 12345000000000;
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
                     "P2PK FORKID", SCRIPT_ENABLE_SIGHASH_FORKID, false,
                     TEST_AMOUNT)
             .PushSig(keys.key0, SIGHASH_ALL | SIGHASH_FORKID, 32, 32,
                      TEST_AMOUNT));
 
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
                     "P2PK INVALID AMOUNT", SCRIPT_ENABLE_SIGHASH_FORKID, false,
                     TEST_AMOUNT)
             .PushSig(keys.key0, SIGHASH_ALL | SIGHASH_FORKID, 32, 32,
                      TEST_AMOUNT + 1)
             .ScriptError(SCRIPT_ERR_EVAL_FALSE));
     tests.push_back(
         TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
                     "P2PK INVALID FORKID", SCRIPT_VERIFY_STRICTENC, false,
                     TEST_AMOUNT)
             .PushSig(keys.key0, SIGHASH_ALL | SIGHASH_FORKID, 32, 32,
                      TEST_AMOUNT)
             .ScriptError(SCRIPT_ERR_ILLEGAL_FORKID));
 
     std::set<std::string> tests_set;
 
     {
         UniValue json_tests = read_json(std::string(
             json_tests::script_tests,
             json_tests::script_tests + sizeof(json_tests::script_tests)));
 
         for (unsigned int idx = 0; idx < json_tests.size(); idx++) {
             const UniValue &tv = json_tests[idx];
             tests_set.insert(JSONPrettyPrint(tv.get_array()));
         }
     }
 
     std::string strGen;
 
     for (TestBuilder &test : tests) {
         test.Test();
         std::string str = JSONPrettyPrint(test.GetJSON());
 #ifndef UPDATE_JSON_TESTS
         if (tests_set.count(str) == 0) {
             BOOST_CHECK_MESSAGE(false, "Missing auto script_valid test: " +
                                            test.GetComment());
         }
 #endif
         strGen += str + ",\n";
     }
 
 #ifdef UPDATE_JSON_TESTS
     FILE *file = fopen("script_tests.json.gen", "w");
     fputs(strGen.c_str(), file);
     fclose(file);
 #endif
 }
 
 BOOST_AUTO_TEST_CASE(script_json_test) {
     // Read tests from test/data/script_tests.json
     // Format is an array of arrays
     // Inner arrays are [ ["wit"..., nValue]?, "scriptSig", "scriptPubKey",
     // "flags", "expected_scripterror" ]
     // ... where scriptSig and scriptPubKey are stringified
     // scripts.
     UniValue tests = read_json(std::string(
         json_tests::script_tests,
         json_tests::script_tests + sizeof(json_tests::script_tests)));
 
     for (unsigned int idx = 0; idx < tests.size(); idx++) {
         UniValue test = tests[idx];
         std::string strTest = test.write();
         CAmount nValue = 0;
         unsigned int pos = 0;
         if (test.size() > 0 && test[pos].isArray()) {
             nValue = AmountFromValue(test[pos][0]);
             pos++;
         }
 
         // Allow size > 3; extra stuff ignored (useful for comments)
         if (test.size() < 4 + pos) {
             if (test.size() != 1) {
                 BOOST_ERROR("Bad test: " << strTest);
             }
             continue;
         }
 
         std::string scriptSigString = test[pos++].get_str();
         CScript scriptSig = ParseScript(scriptSigString);
         std::string scriptPubKeyString = test[pos++].get_str();
         CScript scriptPubKey = ParseScript(scriptPubKeyString);
         unsigned int scriptflags = ParseScriptFlags(test[pos++].get_str());
         int scriptError = ParseScriptError(test[pos++].get_str());
 
         DoTest(scriptPubKey, scriptSig, scriptflags, strTest, scriptError,
                nValue);
     }
 }
 
 BOOST_AUTO_TEST_CASE(script_PushData) {
     // Check that PUSHDATA1, PUSHDATA2, and PUSHDATA4 create the same value on
     // the stack as the 1-75 opcodes do.
-    static const unsigned char direct[] = {1, 0x5a};
-    static const unsigned char pushdata1[] = {OP_PUSHDATA1, 1, 0x5a};
-    static const unsigned char pushdata2[] = {OP_PUSHDATA2, 1, 0, 0x5a};
-    static const unsigned char pushdata4[] = {OP_PUSHDATA4, 1, 0, 0, 0, 0x5a};
+    static const uint8_t direct[] = {1, 0x5a};
+    static const uint8_t pushdata1[] = {OP_PUSHDATA1, 1, 0x5a};
+    static const uint8_t pushdata2[] = {OP_PUSHDATA2, 1, 0, 0x5a};
+    static const uint8_t pushdata4[] = {OP_PUSHDATA4, 1, 0, 0, 0, 0x5a};
 
     ScriptError err;
-    std::vector<std::vector<unsigned char>> directStack;
+    std::vector<std::vector<uint8_t>> directStack;
     BOOST_CHECK(EvalScript(directStack,
                            CScript(&direct[0], &direct[sizeof(direct)]),
                            SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err));
     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
 
-    std::vector<std::vector<unsigned char>> pushdata1Stack;
+    std::vector<std::vector<uint8_t>> pushdata1Stack;
     BOOST_CHECK(EvalScript(
         pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]),
         SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err));
     BOOST_CHECK(pushdata1Stack == directStack);
     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
 
-    std::vector<std::vector<unsigned char>> pushdata2Stack;
+    std::vector<std::vector<uint8_t>> pushdata2Stack;
     BOOST_CHECK(EvalScript(
         pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]),
         SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err));
     BOOST_CHECK(pushdata2Stack == directStack);
     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
 
-    std::vector<std::vector<unsigned char>> pushdata4Stack;
+    std::vector<std::vector<uint8_t>> pushdata4Stack;
     BOOST_CHECK(EvalScript(
         pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]),
         SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err));
     BOOST_CHECK(pushdata4Stack == directStack);
     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
 }
 
 CScript sign_multisig(CScript scriptPubKey, std::vector<CKey> keys,
                       CTransaction transaction) {
     uint256 hash = SignatureHash(scriptPubKey, transaction, 0, SIGHASH_ALL, 0);
 
     CScript result;
     //
     // NOTE: CHECKMULTISIG has an unfortunate bug; it requires one extra item on
     // the stack, before the signatures. Putting OP_0 on the stack is the
     // workaround; fixing the bug would mean splitting the block chain (old
     // clients would not accept new CHECKMULTISIG transactions, and vice-versa)
     //
     result << OP_0;
     for (const CKey &key : keys) {
-        std::vector<unsigned char> vchSig;
+        std::vector<uint8_t> vchSig;
         BOOST_CHECK(key.Sign(hash, vchSig));
-        vchSig.push_back((unsigned char)SIGHASH_ALL);
+        vchSig.push_back(uint8_t(SIGHASH_ALL));
         result << vchSig;
     }
 
     return result;
 }
 
 CScript sign_multisig(CScript scriptPubKey, const CKey &key,
                       CTransaction transaction) {
     std::vector<CKey> keys;
     keys.push_back(key);
     return sign_multisig(scriptPubKey, keys, transaction);
 }
 
 BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12) {
     ScriptError err;
     CKey key1, key2, key3;
     key1.MakeNewKey(true);
     key2.MakeNewKey(false);
     key3.MakeNewKey(true);
 
     CScript scriptPubKey12;
     scriptPubKey12 << OP_1 << ToByteVector(key1.GetPubKey())
                    << ToByteVector(key2.GetPubKey()) << OP_2
                    << OP_CHECKMULTISIG;
 
     CMutableTransaction txFrom12 = BuildCreditingTransaction(scriptPubKey12, 0);
     CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), txFrom12);
 
     CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12);
     BOOST_CHECK(VerifyScript(
         goodsig1, scriptPubKey12, flags,
         MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue),
         &err));
     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
     txTo12.vout[0].nValue = 2;
     BOOST_CHECK(!VerifyScript(
         goodsig1, scriptPubKey12, flags,
         MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue),
         &err));
     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
 
     CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12);
     BOOST_CHECK(VerifyScript(
         goodsig2, scriptPubKey12, flags,
         MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue),
         &err));
     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
 
     CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12);
     BOOST_CHECK(!VerifyScript(
         badsig1, scriptPubKey12, flags,
         MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue),
         &err));
     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
 }
 
 BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23) {
     ScriptError err;
     CKey key1, key2, key3, key4;
     key1.MakeNewKey(true);
     key2.MakeNewKey(false);
     key3.MakeNewKey(true);
     key4.MakeNewKey(false);
 
     CScript scriptPubKey23;
     scriptPubKey23 << OP_2 << ToByteVector(key1.GetPubKey())
                    << ToByteVector(key2.GetPubKey())
                    << ToByteVector(key3.GetPubKey()) << OP_3
                    << OP_CHECKMULTISIG;
 
     CMutableTransaction txFrom23 = BuildCreditingTransaction(scriptPubKey23, 0);
     CMutableTransaction txTo23 = BuildSpendingTransaction(CScript(), txFrom23);
 
     std::vector<CKey> keys;
     keys.push_back(key1);
     keys.push_back(key2);
     CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23);
     BOOST_CHECK(VerifyScript(
         goodsig1, scriptPubKey23, flags,
         MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue),
         &err));
     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
 
     keys.clear();
     keys.push_back(key1);
     keys.push_back(key3);
     CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23);
     BOOST_CHECK(VerifyScript(
         goodsig2, scriptPubKey23, flags,
         MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue),
         &err));
     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
 
     keys.clear();
     keys.push_back(key2);
     keys.push_back(key3);
     CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23);
     BOOST_CHECK(VerifyScript(
         goodsig3, scriptPubKey23, flags,
         MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue),
         &err));
     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
 
     keys.clear();
     keys.push_back(key2);
     keys.push_back(key2); // Can't re-use sig
     CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23);
     BOOST_CHECK(!VerifyScript(
         badsig1, scriptPubKey23, flags,
         MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue),
         &err));
     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
 
     keys.clear();
     keys.push_back(key2);
     keys.push_back(key1); // sigs must be in correct order
     CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23);
     BOOST_CHECK(!VerifyScript(
         badsig2, scriptPubKey23, flags,
         MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue),
         &err));
     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
 
     keys.clear();
     keys.push_back(key3);
     keys.push_back(key2); // sigs must be in correct order
     CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23);
     BOOST_CHECK(!VerifyScript(
         badsig3, scriptPubKey23, flags,
         MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue),
         &err));
     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
 
     keys.clear();
     keys.push_back(key4);
     keys.push_back(key2); // sigs must match pubkeys
     CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23);
     BOOST_CHECK(!VerifyScript(
         badsig4, scriptPubKey23, flags,
         MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue),
         &err));
     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
 
     keys.clear();
     keys.push_back(key1);
     keys.push_back(key4); // sigs must match pubkeys
     CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23);
     BOOST_CHECK(!VerifyScript(
         badsig5, scriptPubKey23, flags,
         MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue),
         &err));
     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
 
     keys.clear(); // Must have signatures
     CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23);
     BOOST_CHECK(!VerifyScript(
         badsig6, scriptPubKey23, flags,
         MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue),
         &err));
     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION,
                         ScriptErrorString(err));
 }
 
 BOOST_AUTO_TEST_CASE(script_combineSigs) {
     // Test the CombineSignatures function
     CAmount amount = 0;
     CBasicKeyStore keystore;
     std::vector<CKey> keys;
     std::vector<CPubKey> pubkeys;
     for (int i = 0; i < 3; i++) {
         CKey key;
         key.MakeNewKey(i % 2 == 1);
         keys.push_back(key);
         pubkeys.push_back(key.GetPubKey());
         keystore.AddKey(key);
     }
 
     CMutableTransaction txFrom = BuildCreditingTransaction(
         GetScriptForDestination(keys[0].GetPubKey().GetID()), 0);
     CMutableTransaction txTo = BuildSpendingTransaction(CScript(), txFrom);
     CScript &scriptPubKey = txFrom.vout[0].scriptPubKey;
     CScript &scriptSig = txTo.vin[0].scriptSig;
 
     SignatureData empty;
     SignatureData combined = CombineSignatures(
         scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount),
         empty, empty);
     BOOST_CHECK(combined.scriptSig.empty());
 
     // Single signature case:
     SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL); // changes scriptSig
     combined = CombineSignatures(
         scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount),
         SignatureData(scriptSig), empty);
     BOOST_CHECK(combined.scriptSig == scriptSig);
     combined = CombineSignatures(
         scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount),
         empty, SignatureData(scriptSig));
     BOOST_CHECK(combined.scriptSig == scriptSig);
     CScript scriptSigCopy = scriptSig;
     // Signing again will give a different, valid signature:
     SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL);
     combined = CombineSignatures(
         scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount),
         SignatureData(scriptSigCopy), SignatureData(scriptSig));
     BOOST_CHECK(combined.scriptSig == scriptSigCopy ||
                 combined.scriptSig == scriptSig);
 
     // P2SH, single-signature case:
     CScript pkSingle;
     pkSingle << ToByteVector(keys[0].GetPubKey()) << OP_CHECKSIG;
     keystore.AddCScript(pkSingle);
     scriptPubKey = GetScriptForDestination(CScriptID(pkSingle));
     SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL);
     combined = CombineSignatures(
         scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount),
         SignatureData(scriptSig), empty);
     BOOST_CHECK(combined.scriptSig == scriptSig);
     combined = CombineSignatures(
         scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount),
         empty, SignatureData(scriptSig));
     BOOST_CHECK(combined.scriptSig == scriptSig);
     scriptSigCopy = scriptSig;
     SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL);
     combined = CombineSignatures(
         scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount),
         SignatureData(scriptSigCopy), SignatureData(scriptSig));
     BOOST_CHECK(combined.scriptSig == scriptSigCopy ||
                 combined.scriptSig == scriptSig);
     // dummy scriptSigCopy with placeholder, should always choose
     // non-placeholder:
-    scriptSigCopy = CScript() << OP_0 << std::vector<unsigned char>(
-                                             pkSingle.begin(), pkSingle.end());
+    scriptSigCopy = CScript() << OP_0 << std::vector<uint8_t>(pkSingle.begin(),
+                                                              pkSingle.end());
     combined = CombineSignatures(
         scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount),
         SignatureData(scriptSigCopy), SignatureData(scriptSig));
     BOOST_CHECK(combined.scriptSig == scriptSig);
     combined = CombineSignatures(
         scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount),
         SignatureData(scriptSig), SignatureData(scriptSigCopy));
     BOOST_CHECK(combined.scriptSig == scriptSig);
 
     // Hardest case:  Multisig 2-of-3
     scriptPubKey = GetScriptForMultisig(2, pubkeys);
     keystore.AddCScript(scriptPubKey);
     SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL);
     combined = CombineSignatures(
         scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount),
         SignatureData(scriptSig), empty);
     BOOST_CHECK(combined.scriptSig == scriptSig);
     combined = CombineSignatures(
         scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount),
         empty, SignatureData(scriptSig));
     BOOST_CHECK(combined.scriptSig == scriptSig);
 
     // A couple of partially-signed versions:
-    std::vector<unsigned char> sig1;
+    std::vector<uint8_t> sig1;
     uint256 hash1 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_ALL, 0);
     BOOST_CHECK(keys[0].Sign(hash1, sig1));
     sig1.push_back(SIGHASH_ALL);
-    std::vector<unsigned char> sig2;
+    std::vector<uint8_t> sig2;
     uint256 hash2 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_NONE, 0);
     BOOST_CHECK(keys[1].Sign(hash2, sig2));
     sig2.push_back(SIGHASH_NONE);
-    std::vector<unsigned char> sig3;
+    std::vector<uint8_t> sig3;
     uint256 hash3 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_SINGLE, 0);
     BOOST_CHECK(keys[2].Sign(hash3, sig3));
     sig3.push_back(SIGHASH_SINGLE);
 
     // Not fussy about order (or even existence) of placeholders or signatures:
     CScript partial1a = CScript() << OP_0 << sig1 << OP_0;
     CScript partial1b = CScript() << OP_0 << OP_0 << sig1;
     CScript partial2a = CScript() << OP_0 << sig2;
     CScript partial2b = CScript() << sig2 << OP_0;
     CScript partial3a = CScript() << sig3;
     CScript partial3b = CScript() << OP_0 << OP_0 << sig3;
     CScript partial3c = CScript() << OP_0 << sig3 << OP_0;
     CScript complete12 = CScript() << OP_0 << sig1 << sig2;
     CScript complete13 = CScript() << OP_0 << sig1 << sig3;
     CScript complete23 = CScript() << OP_0 << sig2 << sig3;
 
     combined = CombineSignatures(
         scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount),
         SignatureData(partial1a), SignatureData(partial1b));
     BOOST_CHECK(combined.scriptSig == partial1a);
     combined = CombineSignatures(
         scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount),
         SignatureData(partial1a), SignatureData(partial2a));
     BOOST_CHECK(combined.scriptSig == complete12);
     combined = CombineSignatures(
         scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount),
         SignatureData(partial2a), SignatureData(partial1a));
     BOOST_CHECK(combined.scriptSig == complete12);
     combined = CombineSignatures(
         scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount),
         SignatureData(partial1b), SignatureData(partial2b));
     BOOST_CHECK(combined.scriptSig == complete12);
     combined = CombineSignatures(
         scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount),
         SignatureData(partial3b), SignatureData(partial1b));
     BOOST_CHECK(combined.scriptSig == complete13);
     combined = CombineSignatures(
         scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount),
         SignatureData(partial2a), SignatureData(partial3a));
     BOOST_CHECK(combined.scriptSig == complete23);
     combined = CombineSignatures(
         scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount),
         SignatureData(partial3b), SignatureData(partial2b));
     BOOST_CHECK(combined.scriptSig == complete23);
     combined = CombineSignatures(
         scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount),
         SignatureData(partial3b), SignatureData(partial3a));
     BOOST_CHECK(combined.scriptSig == partial3c);
 }
 
 BOOST_AUTO_TEST_CASE(script_standard_push) {
     ScriptError err;
     for (int i = 0; i < 67000; i++) {
         CScript script;
         script << i;
         BOOST_CHECK_MESSAGE(script.IsPushOnly(),
                             "Number " << i << " is not pure push.");
         BOOST_CHECK_MESSAGE(VerifyScript(script, CScript() << OP_1,
                                          SCRIPT_VERIFY_MINIMALDATA,
                                          BaseSignatureChecker(), &err),
                             "Number " << i << " push is not minimal data.");
         BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
     }
 
     for (unsigned int i = 0; i <= MAX_SCRIPT_ELEMENT_SIZE; i++) {
-        std::vector<unsigned char> data(i, '\111');
+        std::vector<uint8_t> data(i, '\111');
         CScript script;
         script << data;
         BOOST_CHECK_MESSAGE(script.IsPushOnly(),
                             "Length " << i << " is not pure push.");
         BOOST_CHECK_MESSAGE(VerifyScript(script, CScript() << OP_1,
                                          SCRIPT_VERIFY_MINIMALDATA,
                                          BaseSignatureChecker(), &err),
                             "Length " << i << " push is not minimal data.");
         BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
     }
 }
 
 BOOST_AUTO_TEST_CASE(script_IsPushOnly_on_invalid_scripts) {
     // IsPushOnly returns false when given a script containing only pushes that
     // are invalid due to truncation. IsPushOnly() is consensus critical because
     // P2SH evaluation uses it, although this specific behavior should not be
     // consensus critical as the P2SH evaluation would fail first due to the
     // invalid push. Still, it doesn't hurt to test it explicitly.
-    static const unsigned char direct[] = {1};
+    static const uint8_t direct[] = {1};
     BOOST_CHECK(!CScript(direct, direct + sizeof(direct)).IsPushOnly());
 }
 
 BOOST_AUTO_TEST_CASE(script_GetScriptAsm) {
     BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY",
                       ScriptToAsmStr(CScript() << OP_NOP2, true));
     BOOST_CHECK_EQUAL(
         "OP_CHECKLOCKTIMEVERIFY",
         ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY, true));
     BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY",
                       ScriptToAsmStr(CScript() << OP_NOP2));
     BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY",
                       ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY));
 
     std::string derSig("304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e"
                        "3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38"
                        "d782e53023ee313d741ad0cfbc0c5090");
     std::string pubKey(
         "03b0da749730dc9b4b1f4a14d6902877a92541f5368778853d9c4a0cb7802dcfb2");
-    std::vector<unsigned char> vchPubKey = ToByteVector(ParseHex(pubKey));
+    std::vector<uint8_t> vchPubKey = ToByteVector(ParseHex(pubKey));
 
     BOOST_CHECK_EQUAL(
         derSig + "00 " + pubKey,
         ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "00"))
                                  << vchPubKey,
                        true));
     BOOST_CHECK_EQUAL(
         derSig + "80 " + pubKey,
         ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "80"))
                                  << vchPubKey,
                        true));
     BOOST_CHECK_EQUAL(
         derSig + "[ALL] " + pubKey,
         ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "01"))
                                  << vchPubKey,
                        true));
     BOOST_CHECK_EQUAL(
         derSig + "[ALL|ANYONECANPAY] " + pubKey,
         ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "81"))
                                  << vchPubKey,
                        true));
     BOOST_CHECK_EQUAL(
         derSig + "[ALL|FORKID] " + pubKey,
         ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "41"))
                                  << vchPubKey,
                        true));
     BOOST_CHECK_EQUAL(
         derSig + "[ALL|FORKID|ANYONECANPAY] " + pubKey,
         ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "c1"))
                                  << vchPubKey,
                        true));
     BOOST_CHECK_EQUAL(
         derSig + "[NONE] " + pubKey,
         ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "02"))
                                  << vchPubKey,
                        true));
     BOOST_CHECK_EQUAL(
         derSig + "[NONE|ANYONECANPAY] " + pubKey,
         ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "82"))
                                  << vchPubKey,
                        true));
     BOOST_CHECK_EQUAL(
         derSig + "[NONE|FORKID] " + pubKey,
         ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "42"))
                                  << vchPubKey,
                        true));
     BOOST_CHECK_EQUAL(
         derSig + "[NONE|FORKID|ANYONECANPAY] " + pubKey,
         ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "c2"))
                                  << vchPubKey,
                        true));
     BOOST_CHECK_EQUAL(
         derSig + "[SINGLE] " + pubKey,
         ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "03"))
                                  << vchPubKey,
                        true));
     BOOST_CHECK_EQUAL(
         derSig + "[SINGLE|ANYONECANPAY] " + pubKey,
         ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "83"))
                                  << vchPubKey,
                        true));
     BOOST_CHECK_EQUAL(
         derSig + "[SINGLE|FORKID] " + pubKey,
         ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "43"))
                                  << vchPubKey,
                        true));
     BOOST_CHECK_EQUAL(
         derSig + "[SINGLE|FORKID|ANYONECANPAY] " + pubKey,
         ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "c3"))
                                  << vchPubKey,
                        true));
 
     BOOST_CHECK_EQUAL(derSig + "00 " + pubKey,
                       ScriptToAsmStr(CScript()
                                      << ToByteVector(ParseHex(derSig + "00"))
                                      << vchPubKey));
     BOOST_CHECK_EQUAL(derSig + "80 " + pubKey,
                       ScriptToAsmStr(CScript()
                                      << ToByteVector(ParseHex(derSig + "80"))
                                      << vchPubKey));
     BOOST_CHECK_EQUAL(derSig + "01 " + pubKey,
                       ScriptToAsmStr(CScript()
                                      << ToByteVector(ParseHex(derSig + "01"))
                                      << vchPubKey));
     BOOST_CHECK_EQUAL(derSig + "02 " + pubKey,
                       ScriptToAsmStr(CScript()
                                      << ToByteVector(ParseHex(derSig + "02"))
                                      << vchPubKey));
     BOOST_CHECK_EQUAL(derSig + "03 " + pubKey,
                       ScriptToAsmStr(CScript()
                                      << ToByteVector(ParseHex(derSig + "03"))
                                      << vchPubKey));
     BOOST_CHECK_EQUAL(derSig + "81 " + pubKey,
                       ScriptToAsmStr(CScript()
                                      << ToByteVector(ParseHex(derSig + "81"))
                                      << vchPubKey));
     BOOST_CHECK_EQUAL(derSig + "82 " + pubKey,
                       ScriptToAsmStr(CScript()
                                      << ToByteVector(ParseHex(derSig + "82"))
                                      << vchPubKey));
     BOOST_CHECK_EQUAL(derSig + "83 " + pubKey,
                       ScriptToAsmStr(CScript()
                                      << ToByteVector(ParseHex(derSig + "83"))
                                      << vchPubKey));
 }
 
 static CScript ScriptFromHex(const char *hex) {
-    std::vector<unsigned char> data = ParseHex(hex);
+    std::vector<uint8_t> data = ParseHex(hex);
     return CScript(data.begin(), data.end());
 }
 
 BOOST_AUTO_TEST_CASE(script_FindAndDelete) {
     // Exercise the FindAndDelete functionality
     CScript s;
     CScript d;
     CScript expect;
 
     s = CScript() << OP_1 << OP_2;
     // delete nothing should be a no-op
     d = CScript();
     expect = s;
     BOOST_CHECK_EQUAL(s.FindAndDelete(d), 0);
     BOOST_CHECK(s == expect);
 
     s = CScript() << OP_1 << OP_2 << OP_3;
     d = CScript() << OP_2;
     expect = CScript() << OP_1 << OP_3;
     BOOST_CHECK_EQUAL(s.FindAndDelete(d), 1);
     BOOST_CHECK(s == expect);
 
     s = CScript() << OP_3 << OP_1 << OP_3 << OP_3 << OP_4 << OP_3;
     d = CScript() << OP_3;
     expect = CScript() << OP_1 << OP_4;
     BOOST_CHECK_EQUAL(s.FindAndDelete(d), 4);
     BOOST_CHECK(s == expect);
 
     // PUSH 0x02ff03 onto stack
     s = ScriptFromHex("0302ff03");
     d = ScriptFromHex("0302ff03");
     expect = CScript();
     BOOST_CHECK_EQUAL(s.FindAndDelete(d), 1);
     BOOST_CHECK(s == expect);
 
     // PUSH 0x2ff03 PUSH 0x2ff03
     s = ScriptFromHex("0302ff030302ff03");
     d = ScriptFromHex("0302ff03");
     expect = CScript();
     BOOST_CHECK_EQUAL(s.FindAndDelete(d), 2);
     BOOST_CHECK(s == expect);
 
     s = ScriptFromHex("0302ff030302ff03");
     d = ScriptFromHex("02");
     expect = s; // FindAndDelete matches entire opcodes
     BOOST_CHECK_EQUAL(s.FindAndDelete(d), 0);
     BOOST_CHECK(s == expect);
 
     s = ScriptFromHex("0302ff030302ff03");
     d = ScriptFromHex("ff");
     expect = s;
     BOOST_CHECK_EQUAL(s.FindAndDelete(d), 0);
     BOOST_CHECK(s == expect);
 
     // This is an odd edge case: strip of the push-three-bytes prefix, leaving
     // 02ff03 which is push-two-bytes:
     s = ScriptFromHex("0302ff030302ff03");
     d = ScriptFromHex("03");
     expect = CScript() << ParseHex("ff03") << ParseHex("ff03");
     BOOST_CHECK_EQUAL(s.FindAndDelete(d), 2);
     BOOST_CHECK(s == expect);
 
     // Byte sequence that spans multiple opcodes:
     // PUSH(0xfeed) OP_1 OP_VERIFY
     s = ScriptFromHex("02feed5169");
     d = ScriptFromHex("feed51");
     expect = s;
     // doesn't match 'inside' opcodes
     BOOST_CHECK_EQUAL(s.FindAndDelete(d), 0);
     BOOST_CHECK(s == expect);
 
     // PUSH(0xfeed) OP_1 OP_VERIFY
     s = ScriptFromHex("02feed5169");
     d = ScriptFromHex("02feed51");
     expect = ScriptFromHex("69");
     BOOST_CHECK_EQUAL(s.FindAndDelete(d), 1);
     BOOST_CHECK(s == expect);
 
     s = ScriptFromHex("516902feed5169");
     d = ScriptFromHex("feed51");
     expect = s;
     BOOST_CHECK_EQUAL(s.FindAndDelete(d), 0);
     BOOST_CHECK(s == expect);
 
     s = ScriptFromHex("516902feed5169");
     d = ScriptFromHex("02feed51");
     expect = ScriptFromHex("516969");
     BOOST_CHECK_EQUAL(s.FindAndDelete(d), 1);
     BOOST_CHECK(s == expect);
 
     s = CScript() << OP_0 << OP_0 << OP_1 << OP_1;
     d = CScript() << OP_0 << OP_1;
     // FindAndDelete is single-pass
     expect = CScript() << OP_0 << OP_1;
     BOOST_CHECK_EQUAL(s.FindAndDelete(d), 1);
     BOOST_CHECK(s == expect);
 
     s = CScript() << OP_0 << OP_0 << OP_1 << OP_0 << OP_1 << OP_1;
     d = CScript() << OP_0 << OP_1;
     // FindAndDelete is single-pass
     expect = CScript() << OP_0 << OP_1;
     BOOST_CHECK_EQUAL(s.FindAndDelete(d), 2);
     BOOST_CHECK(s == expect);
 
     // Another weird edge case:
     // End with invalid push (not enough data)...
     s = ScriptFromHex("0003feed");
     // ... can remove the invalid push
     d = ScriptFromHex("03feed");
     expect = ScriptFromHex("00");
     BOOST_CHECK_EQUAL(s.FindAndDelete(d), 1);
     BOOST_CHECK(s == expect);
 
     s = ScriptFromHex("0003feed");
     d = ScriptFromHex("00");
     expect = ScriptFromHex("03feed");
     BOOST_CHECK_EQUAL(s.FindAndDelete(d), 1);
     BOOST_CHECK(s == expect);
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/scriptnum10.h b/src/test/scriptnum10.h
index 6f8e2d2b9..faa4e0573 100644
--- a/src/test/scriptnum10.h
+++ b/src/test/scriptnum10.h
@@ -1,196 +1,195 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-2015 The Bitcoin Core developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #ifndef BITCOIN_TEST_SCRIPTNUM10_H
 #define BITCOIN_TEST_SCRIPTNUM10_H
 
 #include <algorithm>
 #include <cassert>
 #include <cstdint>
 #include <limits>
 #include <stdexcept>
 #include <string>
 #include <vector>
 
 class scriptnum10_error : public std::runtime_error {
 public:
     explicit scriptnum10_error(const std::string &str)
         : std::runtime_error(str) {}
 };
 
 class CScriptNum10 {
     /**
      * The ScriptNum implementation from Bitcoin Core 0.10.0, for
      * cross-comparison.
      */
 public:
     explicit CScriptNum10(const int64_t &n) { m_value = n; }
 
     static const size_t nDefaultMaxNumSize = 4;
 
-    explicit CScriptNum10(const std::vector<unsigned char> &vch,
-                          bool fRequireMinimal,
+    explicit CScriptNum10(const std::vector<uint8_t> &vch, bool fRequireMinimal,
                           const size_t nMaxNumSize = nDefaultMaxNumSize) {
         if (vch.size() > nMaxNumSize) {
             throw scriptnum10_error("script number overflow");
         }
         if (fRequireMinimal && vch.size() > 0) {
             // Check that the number is encoded with the minimum possible number
             // of bytes.
             //
             // If the most-significant-byte - excluding the sign bit - is zero
             // then we're not minimal. Note how this test also rejects the
             // negative-zero encoding, 0x80.
             if ((vch.back() & 0x7f) == 0) {
                 // One exception: if there's more than one byte and the most
                 // significant bit of the second-most-significant-byte is set it
                 // would conflict with the sign bit. An example of this case is
                 // +-255, which encode to 0xff00 and 0xff80 respectively.
                 // (big-endian).
                 if (vch.size() <= 1 || (vch[vch.size() - 2] & 0x80) == 0) {
                     throw scriptnum10_error(
                         "non-minimally encoded script number");
                 }
             }
         }
         m_value = set_vch(vch);
     }
 
     inline bool operator==(const int64_t &rhs) const { return m_value == rhs; }
     inline bool operator!=(const int64_t &rhs) const { return m_value != rhs; }
     inline bool operator<=(const int64_t &rhs) const { return m_value <= rhs; }
     inline bool operator<(const int64_t &rhs) const { return m_value < rhs; }
     inline bool operator>=(const int64_t &rhs) const { return m_value >= rhs; }
     inline bool operator>(const int64_t &rhs) const { return m_value > rhs; }
 
     inline bool operator==(const CScriptNum10 &rhs) const {
         return operator==(rhs.m_value);
     }
     inline bool operator!=(const CScriptNum10 &rhs) const {
         return operator!=(rhs.m_value);
     }
     inline bool operator<=(const CScriptNum10 &rhs) const {
         return operator<=(rhs.m_value);
     }
     inline bool operator<(const CScriptNum10 &rhs) const {
         return operator<(rhs.m_value);
     }
     inline bool operator>=(const CScriptNum10 &rhs) const {
         return operator>=(rhs.m_value);
     }
     inline bool operator>(const CScriptNum10 &rhs) const {
         return operator>(rhs.m_value);
     }
 
     inline CScriptNum10 operator+(const int64_t &rhs) const {
         return CScriptNum10(m_value + rhs);
     }
     inline CScriptNum10 operator-(const int64_t &rhs) const {
         return CScriptNum10(m_value - rhs);
     }
     inline CScriptNum10 operator+(const CScriptNum10 &rhs) const {
         return operator+(rhs.m_value);
     }
     inline CScriptNum10 operator-(const CScriptNum10 &rhs) const {
         return operator-(rhs.m_value);
     }
 
     inline CScriptNum10 &operator+=(const CScriptNum10 &rhs) {
         return operator+=(rhs.m_value);
     }
     inline CScriptNum10 &operator-=(const CScriptNum10 &rhs) {
         return operator-=(rhs.m_value);
     }
 
     inline CScriptNum10 operator-() const {
         assert(m_value != std::numeric_limits<int64_t>::min());
         return CScriptNum10(-m_value);
     }
 
     inline CScriptNum10 &operator=(const int64_t &rhs) {
         m_value = rhs;
         return *this;
     }
 
     inline CScriptNum10 &operator+=(const int64_t &rhs) {
         assert(
             rhs == 0 ||
             (rhs > 0 && m_value <= std::numeric_limits<int64_t>::max() - rhs) ||
             (rhs < 0 && m_value >= std::numeric_limits<int64_t>::min() - rhs));
         m_value += rhs;
         return *this;
     }
 
     inline CScriptNum10 &operator-=(const int64_t &rhs) {
         assert(
             rhs == 0 ||
             (rhs > 0 && m_value >= std::numeric_limits<int64_t>::min() + rhs) ||
             (rhs < 0 && m_value <= std::numeric_limits<int64_t>::max() + rhs));
         m_value -= rhs;
         return *this;
     }
 
     int getint() const {
         if (m_value > std::numeric_limits<int>::max())
             return std::numeric_limits<int>::max();
         else if (m_value < std::numeric_limits<int>::min())
             return std::numeric_limits<int>::min();
         return m_value;
     }
 
-    std::vector<unsigned char> getvch() const { return serialize(m_value); }
+    std::vector<uint8_t> getvch() const { return serialize(m_value); }
 
-    static std::vector<unsigned char> serialize(const int64_t &value) {
-        if (value == 0) return std::vector<unsigned char>();
+    static std::vector<uint8_t> serialize(const int64_t &value) {
+        if (value == 0) return std::vector<uint8_t>();
 
-        std::vector<unsigned char> result;
+        std::vector<uint8_t> result;
         const bool neg = value < 0;
         uint64_t absvalue = neg ? -value : value;
 
         while (absvalue) {
             result.push_back(absvalue & 0xff);
             absvalue >>= 8;
         }
 
         //    - If the most significant byte is >= 0x80 and the value is
         //    positive, push a new zero-byte to make the significant byte < 0x80
         //    again.
 
         //    - If the most significant byte is >= 0x80 and the value is
         //    negative, push a new 0x80 byte that will be popped off when
         //    converting to an integral.
 
         //    - If the most significant byte is < 0x80 and the value is
         //    negative, add 0x80 to it, since it will be subtracted and
         //    interpreted as a negative when converting to an integral.
 
         if (result.back() & 0x80)
             result.push_back(neg ? 0x80 : 0);
         else if (neg)
             result.back() |= 0x80;
 
         return result;
     }
 
 private:
-    static int64_t set_vch(const std::vector<unsigned char> &vch) {
+    static int64_t set_vch(const std::vector<uint8_t> &vch) {
         if (vch.empty()) return 0;
 
         int64_t result = 0;
         for (size_t i = 0; i != vch.size(); ++i)
             result |= static_cast<int64_t>(vch[i]) << 8 * i;
 
         // If the input vector's most significant byte is 0x80, remove it from
         // the result's msb and return a negative.
         if (vch.back() & 0x80)
             return -((int64_t)(result & ~(0x80ULL << (8 * (vch.size() - 1)))));
 
         return result;
     }
 
     int64_t m_value;
 };
 
 #endif // BITCOIN_TEST_BIGNUM_H
diff --git a/src/test/scriptnum_tests.cpp b/src/test/scriptnum_tests.cpp
index 8688815b3..b3bbd6418 100644
--- a/src/test/scriptnum_tests.cpp
+++ b/src/test/scriptnum_tests.cpp
@@ -1,205 +1,205 @@
 // Copyright (c) 2012-2015 The Bitcoin Core developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #include "script/script.h"
 #include "scriptnum10.h"
 #include "test/test_bitcoin.h"
 
 #include <boost/test/unit_test.hpp>
 #include <climits>
 #include <cstdint>
 
 BOOST_FIXTURE_TEST_SUITE(scriptnum_tests, BasicTestingSetup)
 
 /** A selection of numbers that do not trigger int64_t overflow
  *  when added/subtracted. */
 static const int64_t values[] = {0,
                                  1,
                                  -2,
                                  127,
                                  128,
                                  -255,
                                  256,
                                  (1LL << 15) - 1,
                                  -(1LL << 16),
                                  (1LL << 24) - 1,
                                  (1LL << 31),
                                  1 - (1LL << 32),
                                  1LL << 40};
 
 static const int64_t offsets[] = {1,      0x79,   0x80,   0x81,   0xFF,
                                   0x7FFF, 0x8000, 0xFFFF, 0x10000};
 
 static bool verify(const CScriptNum10 &bignum, const CScriptNum &scriptnum) {
     return bignum.getvch() == scriptnum.getvch() &&
            bignum.getint() == scriptnum.getint();
 }
 
 static void CheckCreateVch(const int64_t &num) {
     CScriptNum10 bignum(num);
     CScriptNum scriptnum(num);
     BOOST_CHECK(verify(bignum, scriptnum));
 
-    std::vector<unsigned char> vch = bignum.getvch();
+    std::vector<uint8_t> vch = bignum.getvch();
 
     CScriptNum10 bignum2(bignum.getvch(), false);
     vch = scriptnum.getvch();
     CScriptNum scriptnum2(scriptnum.getvch(), false);
     BOOST_CHECK(verify(bignum2, scriptnum2));
 
     CScriptNum10 bignum3(scriptnum2.getvch(), false);
     CScriptNum scriptnum3(bignum2.getvch(), false);
     BOOST_CHECK(verify(bignum3, scriptnum3));
 }
 
 static void CheckCreateInt(const int64_t &num) {
     CScriptNum10 bignum(num);
     CScriptNum scriptnum(num);
     BOOST_CHECK(verify(bignum, scriptnum));
     BOOST_CHECK(
         verify(CScriptNum10(bignum.getint()), CScriptNum(scriptnum.getint())));
     BOOST_CHECK(
         verify(CScriptNum10(scriptnum.getint()), CScriptNum(bignum.getint())));
     BOOST_CHECK(verify(CScriptNum10(CScriptNum10(scriptnum.getint()).getint()),
                        CScriptNum(CScriptNum(bignum.getint()).getint())));
 }
 
 static void CheckAdd(const int64_t &num1, const int64_t &num2) {
     const CScriptNum10 bignum1(num1);
     const CScriptNum10 bignum2(num2);
     const CScriptNum scriptnum1(num1);
     const CScriptNum scriptnum2(num2);
     CScriptNum10 bignum3(num1);
     CScriptNum10 bignum4(num1);
     CScriptNum scriptnum3(num1);
     CScriptNum scriptnum4(num1);
 
     // int64_t overflow is undefined.
     bool invalid =
         (((num2 > 0) &&
           (num1 > (std::numeric_limits<int64_t>::max() - num2))) ||
          ((num2 < 0) && (num1 < (std::numeric_limits<int64_t>::min() - num2))));
     if (!invalid) {
         BOOST_CHECK(verify(bignum1 + bignum2, scriptnum1 + scriptnum2));
         BOOST_CHECK(verify(bignum1 + bignum2, scriptnum1 + num2));
         BOOST_CHECK(verify(bignum1 + bignum2, scriptnum2 + num1));
     }
 }
 
 static void CheckNegate(const int64_t &num) {
     const CScriptNum10 bignum(num);
     const CScriptNum scriptnum(num);
 
     // -INT64_MIN is undefined
     if (num != std::numeric_limits<int64_t>::min())
         BOOST_CHECK(verify(-bignum, -scriptnum));
 }
 
 static void CheckSubtract(const int64_t &num1, const int64_t &num2) {
     const CScriptNum10 bignum1(num1);
     const CScriptNum10 bignum2(num2);
     const CScriptNum scriptnum1(num1);
     const CScriptNum scriptnum2(num2);
     bool invalid = false;
 
     // int64_t overflow is undefined.
     invalid =
         ((num2 > 0 && num1 < std::numeric_limits<int64_t>::min() + num2) ||
          (num2 < 0 && num1 > std::numeric_limits<int64_t>::max() + num2));
     if (!invalid) {
         BOOST_CHECK(verify(bignum1 - bignum2, scriptnum1 - scriptnum2));
         BOOST_CHECK(verify(bignum1 - bignum2, scriptnum1 - num2));
     }
 
     invalid =
         ((num1 > 0 && num2 < std::numeric_limits<int64_t>::min() + num1) ||
          (num1 < 0 && num2 > std::numeric_limits<int64_t>::max() + num1));
     if (!invalid) {
         BOOST_CHECK(verify(bignum2 - bignum1, scriptnum2 - scriptnum1));
         BOOST_CHECK(verify(bignum2 - bignum1, scriptnum2 - num1));
     }
 }
 
 static void CheckCompare(const int64_t &num1, const int64_t &num2) {
     const CScriptNum10 bignum1(num1);
     const CScriptNum10 bignum2(num2);
     const CScriptNum scriptnum1(num1);
     const CScriptNum scriptnum2(num2);
 
     BOOST_CHECK((bignum1 == bignum1) == (scriptnum1 == scriptnum1));
     BOOST_CHECK((bignum1 != bignum1) == (scriptnum1 != scriptnum1));
     BOOST_CHECK((bignum1 < bignum1) == (scriptnum1 < scriptnum1));
     BOOST_CHECK((bignum1 > bignum1) == (scriptnum1 > scriptnum1));
     BOOST_CHECK((bignum1 >= bignum1) == (scriptnum1 >= scriptnum1));
     BOOST_CHECK((bignum1 <= bignum1) == (scriptnum1 <= scriptnum1));
 
     BOOST_CHECK((bignum1 == bignum1) == (scriptnum1 == num1));
     BOOST_CHECK((bignum1 != bignum1) == (scriptnum1 != num1));
     BOOST_CHECK((bignum1 < bignum1) == (scriptnum1 < num1));
     BOOST_CHECK((bignum1 > bignum1) == (scriptnum1 > num1));
     BOOST_CHECK((bignum1 >= bignum1) == (scriptnum1 >= num1));
     BOOST_CHECK((bignum1 <= bignum1) == (scriptnum1 <= num1));
 
     BOOST_CHECK((bignum1 == bignum2) == (scriptnum1 == scriptnum2));
     BOOST_CHECK((bignum1 != bignum2) == (scriptnum1 != scriptnum2));
     BOOST_CHECK((bignum1 < bignum2) == (scriptnum1 < scriptnum2));
     BOOST_CHECK((bignum1 > bignum2) == (scriptnum1 > scriptnum2));
     BOOST_CHECK((bignum1 >= bignum2) == (scriptnum1 >= scriptnum2));
     BOOST_CHECK((bignum1 <= bignum2) == (scriptnum1 <= scriptnum2));
 
     BOOST_CHECK((bignum1 == bignum2) == (scriptnum1 == num2));
     BOOST_CHECK((bignum1 != bignum2) == (scriptnum1 != num2));
     BOOST_CHECK((bignum1 < bignum2) == (scriptnum1 < num2));
     BOOST_CHECK((bignum1 > bignum2) == (scriptnum1 > num2));
     BOOST_CHECK((bignum1 >= bignum2) == (scriptnum1 >= num2));
     BOOST_CHECK((bignum1 <= bignum2) == (scriptnum1 <= num2));
 }
 
 static void RunCreate(const int64_t &num) {
     CheckCreateInt(num);
     CScriptNum scriptnum(num);
     if (scriptnum.getvch().size() <= CScriptNum::nDefaultMaxNumSize)
         CheckCreateVch(num);
     else {
         BOOST_CHECK_THROW(CheckCreateVch(num), scriptnum10_error);
     }
 }
 
 static void RunOperators(const int64_t &num1, const int64_t &num2) {
     CheckAdd(num1, num2);
     CheckSubtract(num1, num2);
     CheckNegate(num1);
     CheckCompare(num1, num2);
 }
 
 BOOST_AUTO_TEST_CASE(creation) {
     for (size_t i = 0; i < sizeof(values) / sizeof(values[0]); ++i) {
         for (size_t j = 0; j < sizeof(offsets) / sizeof(offsets[0]); ++j) {
             RunCreate(values[i]);
             RunCreate(values[i] + offsets[j]);
             RunCreate(values[i] - offsets[j]);
         }
     }
 }
 
 BOOST_AUTO_TEST_CASE(operators) {
     for (size_t i = 0; i < sizeof(values) / sizeof(values[0]); ++i) {
         for (size_t j = 0; j < sizeof(offsets) / sizeof(offsets[0]); ++j) {
             RunOperators(values[i], values[i]);
             RunOperators(values[i], -values[i]);
             RunOperators(values[i], values[j]);
             RunOperators(values[i], -values[j]);
             RunOperators(values[i] + values[j], values[j]);
             RunOperators(values[i] + values[j], -values[j]);
             RunOperators(values[i] - values[j], values[j]);
             RunOperators(values[i] - values[j], -values[j]);
             RunOperators(values[i] + values[j], values[i] + values[j]);
             RunOperators(values[i] + values[j], values[i] - values[j]);
             RunOperators(values[i] - values[j], values[i] + values[j]);
             RunOperators(values[i] - values[j], values[i] - values[j]);
         }
     }
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp
index ac03e9bf4..f2125d826 100644
--- a/src/test/sighash_tests.cpp
+++ b/src/test/sighash_tests.cpp
@@ -1,220 +1,220 @@
 // 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.
 
 #include "consensus/validation.h"
 #include "data/sighash.json.h"
 #include "hash.h"
 #include "script/interpreter.h"
 #include "script/script.h"
 #include "serialize.h"
 #include "streams.h"
 #include "test/test_bitcoin.h"
 #include "test/test_random.h"
 #include "util.h"
 #include "utilstrencodings.h"
 #include "validation.h" // For CheckRegularTransaction
 #include "version.h"
 
 #include <iostream>
 
 #include <boost/test/unit_test.hpp>
 
 #include <univalue.h>
 
 extern UniValue read_json(const std::string &jsondata);
 
 // Old script.cpp SignatureHash function
 static uint256 SignatureHashOld(CScript scriptCode, const CTransaction &txTo,
                                 unsigned int nIn, int nHashType) {
     static const uint256 one(uint256S(
         "0000000000000000000000000000000000000000000000000000000000000001"));
     if (nIn >= txTo.vin.size()) {
         printf("ERROR: SignatureHash(): nIn=%d out of range\n", nIn);
         return one;
     }
     CMutableTransaction txTmp(txTo);
 
     // In case concatenating two scripts ends up with two codeseparators, or an
     // extra one at the end, this prevents all those possible incompatibilities.
     scriptCode.FindAndDelete(CScript(OP_CODESEPARATOR));
 
     // Blank out other inputs' signatures
     for (unsigned int i = 0; i < txTmp.vin.size(); i++)
         txTmp.vin[i].scriptSig = CScript();
     txTmp.vin[nIn].scriptSig = scriptCode;
 
     // Blank out some of the outputs
     if ((nHashType & 0x1f) == SIGHASH_NONE) {
         // Wildcard payee
         txTmp.vout.clear();
 
         // Let the others update at will
         for (unsigned int i = 0; i < txTmp.vin.size(); i++)
             if (i != nIn) txTmp.vin[i].nSequence = 0;
     } else if ((nHashType & 0x1f) == SIGHASH_SINGLE) {
         // Only lock-in the txout payee at same index as txin
         unsigned int nOut = nIn;
         if (nOut >= txTmp.vout.size()) {
             printf("ERROR: SignatureHash(): nOut=%d out of range\n", nOut);
             return one;
         }
         txTmp.vout.resize(nOut + 1);
         for (unsigned int i = 0; i < nOut; i++)
             txTmp.vout[i].SetNull();
 
         // Let the others update at will
         for (unsigned int i = 0; i < txTmp.vin.size(); i++)
             if (i != nIn) txTmp.vin[i].nSequence = 0;
     }
 
     // Blank out other inputs completely, not recommended for open transactions
     if (nHashType & SIGHASH_ANYONECANPAY) {
         txTmp.vin[0] = txTmp.vin[nIn];
         txTmp.vin.resize(1);
     }
 
     // Serialize and hash
     CHashWriter ss(SER_GETHASH, 0);
     ss << txTmp << nHashType;
     return ss.GetHash();
 }
 
 static void RandomScript(CScript &script) {
     static const opcodetype oplist[] = {
         OP_FALSE, OP_1,        OP_2,
         OP_3,     OP_CHECKSIG, OP_IF,
         OP_VERIF, OP_RETURN,   OP_CODESEPARATOR};
     script = CScript();
     int ops = (insecure_rand() % 10);
     for (int i = 0; i < ops; i++)
         script
             << oplist[insecure_rand() % (sizeof(oplist) / sizeof(oplist[0]))];
 }
 
 static void RandomTransaction(CMutableTransaction &tx, bool fSingle) {
     tx.nVersion = insecure_rand();
     tx.vin.clear();
     tx.vout.clear();
     tx.nLockTime = (insecure_rand() % 2) ? insecure_rand() : 0;
     int ins = (insecure_rand() % 4) + 1;
     int outs = fSingle ? ins : (insecure_rand() % 4) + 1;
     for (int in = 0; in < ins; in++) {
         tx.vin.push_back(CTxIn());
         CTxIn &txin = tx.vin.back();
         txin.prevout.hash = GetRandHash();
         txin.prevout.n = insecure_rand() % 4;
         RandomScript(txin.scriptSig);
         txin.nSequence =
             (insecure_rand() % 2) ? insecure_rand() : (unsigned int)-1;
     }
     for (int out = 0; out < outs; out++) {
         tx.vout.push_back(CTxOut());
         CTxOut &txout = tx.vout.back();
         txout.nValue = insecure_rand() % 100000000;
         RandomScript(txout.scriptPubKey);
     }
 }
 
 BOOST_FIXTURE_TEST_SUITE(sighash_tests, BasicTestingSetup)
 
 BOOST_AUTO_TEST_CASE(sighash_test) {
     seed_insecure_rand(false);
 
 #if defined(PRINT_SIGHASH_JSON)
     std::cout << "[\n";
     std::cout << "\t[\"raw_transaction, script, input_index, hashType, "
                  "signature_hash (result)\"],\n";
 #endif
     int nRandomTests = 50000;
 
 #if defined(PRINT_SIGHASH_JSON)
     nRandomTests = 500;
 #endif
     for (int i = 0; i < nRandomTests; i++) {
         int nHashType = insecure_rand();
 
         // Clear forkid
         nHashType &= ~SIGHASH_FORKID;
 
         CMutableTransaction txTo;
         RandomTransaction(txTo, (nHashType & 0x1f) == SIGHASH_SINGLE);
         CScript scriptCode;
         RandomScript(scriptCode);
         int nIn = insecure_rand() % txTo.vin.size();
 
         uint256 sh, sho;
         sho = SignatureHashOld(scriptCode, txTo, nIn, nHashType);
         sh = SignatureHash(scriptCode, txTo, nIn, nHashType, 0);
 #if defined(PRINT_SIGHASH_JSON)
         CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
         ss << txTo;
 
         std::cout << "\t[\"";
         std::cout << HexStr(ss.begin(), ss.end()) << "\", \"";
         std::cout << HexStr(scriptCode) << "\", ";
         std::cout << nIn << ", ";
         std::cout << nHashType << ", \"";
         std::cout << sh.GetHex() << "\"]";
         if (i + 1 != nRandomTests) {
             std::cout << ",";
         }
         std::cout << "\n";
 #endif
         BOOST_CHECK(sh == sho);
     }
 #if defined(PRINT_SIGHASH_JSON)
     std::cout << "]\n";
 #endif
 }
 
 // Goal: check that SignatureHash generates correct hash
 BOOST_AUTO_TEST_CASE(sighash_from_data) {
     UniValue tests = read_json(
         std::string(json_tests::sighash,
                     json_tests::sighash + sizeof(json_tests::sighash)));
 
     for (unsigned int idx = 0; idx < tests.size(); idx++) {
         UniValue test = tests[idx];
         std::string strTest = test.write();
         // Allow for extra stuff (useful for comments)
         if (test.size() < 1) {
             BOOST_ERROR("Bad test: " << strTest);
             continue;
         }
         if (test.size() == 1) continue; // comment
 
         std::string raw_tx, raw_script, sigHashHex;
         int nIn, nHashType;
         uint256 sh;
         CTransactionRef tx;
         CScript scriptCode = CScript();
 
         try {
             // deserialize test data
             raw_tx = test[0].get_str();
             raw_script = test[1].get_str();
             nIn = test[2].get_int();
             nHashType = test[3].get_int();
             sigHashHex = test[4].get_str();
 
             CDataStream stream(ParseHex(raw_tx), SER_NETWORK, PROTOCOL_VERSION);
             stream >> tx;
 
             CValidationState state;
             BOOST_CHECK_MESSAGE(CheckRegularTransaction(*tx, state), strTest);
             BOOST_CHECK(state.IsValid());
 
-            std::vector<unsigned char> raw = ParseHex(raw_script);
+            std::vector<uint8_t> raw = ParseHex(raw_script);
             scriptCode.insert(scriptCode.end(), raw.begin(), raw.end());
         } catch (...) {
             BOOST_ERROR("Bad test, couldn't deserialize data: " << strTest);
             continue;
         }
 
         sh = SignatureHash(scriptCode, *tx, nIn, nHashType, 0);
         BOOST_CHECK_MESSAGE(sh.GetHex() == sigHashHex, strTest);
     }
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp
index 02172ab75..7e35f944b 100644
--- a/src/test/sigopcount_tests.cpp
+++ b/src/test/sigopcount_tests.cpp
@@ -1,224 +1,224 @@
 // Copyright (c) 2012-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.
 
 #include "consensus/consensus.h"
 #include "consensus/validation.h"
 #include "key.h"
 #include "pubkey.h"
 #include "script/script.h"
 #include "script/standard.h"
 #include "test/test_bitcoin.h"
 #include "uint256.h"
 #include "validation.h"
 
 #include <limits>
 #include <vector>
 
 #include <boost/test/unit_test.hpp>
 
 // Helpers:
-static std::vector<unsigned char> Serialize(const CScript &s) {
-    std::vector<unsigned char> sSerialized(s.begin(), s.end());
+static std::vector<uint8_t> Serialize(const CScript &s) {
+    std::vector<uint8_t> sSerialized(s.begin(), s.end());
     return sSerialized;
 }
 
 BOOST_FIXTURE_TEST_SUITE(sigopcount_tests, BasicTestingSetup)
 
 BOOST_AUTO_TEST_CASE(GetSigOpCount) {
     // Test CScript::GetSigOpCount()
     CScript s1;
     BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 0U);
     BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 0U);
 
     uint160 dummy;
     s1 << OP_1 << ToByteVector(dummy) << ToByteVector(dummy) << OP_2
        << OP_CHECKMULTISIG;
     BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 2U);
     s1 << OP_IF << OP_CHECKSIG << OP_ENDIF;
     BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 3U);
     BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 21U);
 
     CScript p2sh = GetScriptForDestination(CScriptID(s1));
     CScript scriptSig;
     scriptSig << OP_0 << Serialize(s1);
     BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(scriptSig), 3U);
 
     std::vector<CPubKey> keys;
     for (int i = 0; i < 3; i++) {
         CKey k;
         k.MakeNewKey(true);
         keys.push_back(k.GetPubKey());
     }
     CScript s2 = GetScriptForMultisig(1, keys);
     BOOST_CHECK_EQUAL(s2.GetSigOpCount(true), 3U);
     BOOST_CHECK_EQUAL(s2.GetSigOpCount(false), 20U);
 
     p2sh = GetScriptForDestination(CScriptID(s2));
     BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(true), 0U);
     BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(false), 0U);
     CScript scriptSig2;
     scriptSig2 << OP_1 << ToByteVector(dummy) << ToByteVector(dummy)
                << Serialize(s2);
     BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(scriptSig2), 3U);
 }
 
 /**
  * Verifies script execution of the zeroth scriptPubKey of tx output and zeroth
  * scriptSig and witness of tx input.
  */
 ScriptError VerifyWithFlag(const CTransaction &output,
                            const CMutableTransaction &input, int flags) {
     ScriptError error;
     CTransaction inputi(input);
     bool ret = VerifyScript(
         inputi.vin[0].scriptSig, output.vout[0].scriptPubKey, flags,
         TransactionSignatureChecker(&inputi, 0, output.vout[0].nValue), &error);
     BOOST_CHECK((ret == true) == (error == SCRIPT_ERR_OK));
 
     return error;
 }
 
 /**
  * Builds a creationTx from scriptPubKey and a spendingTx from scriptSig and
  * witness such that spendingTx spends output zero of creationTx. Also inserts
  * creationTx's output into the coins view.
  */
 void BuildTxs(CMutableTransaction &spendingTx, CCoinsViewCache &coins,
               CMutableTransaction &creationTx, const CScript &scriptPubKey,
               const CScript &scriptSig) {
     creationTx.nVersion = 1;
     creationTx.vin.resize(1);
     creationTx.vin[0].prevout.SetNull();
     creationTx.vin[0].scriptSig = CScript();
     creationTx.vout.resize(1);
     creationTx.vout[0].nValue = 1;
     creationTx.vout[0].scriptPubKey = scriptPubKey;
 
     spendingTx.nVersion = 1;
     spendingTx.vin.resize(1);
     spendingTx.vin[0].prevout.hash = creationTx.GetId();
     spendingTx.vin[0].prevout.n = 0;
     spendingTx.vin[0].scriptSig = scriptSig;
     spendingTx.vout.resize(1);
     spendingTx.vout[0].nValue = 1;
     spendingTx.vout[0].scriptPubKey = CScript();
 
     coins.ModifyCoins(creationTx.GetId())->FromTx(creationTx, 0);
 }
 
 BOOST_AUTO_TEST_CASE(GetTxSigOpCost) {
     // Transaction creates outputs
     CMutableTransaction creationTx;
     // Transaction that spends outputs and whose sig op cost is going to be
     // tested
     CMutableTransaction spendingTx;
 
     // Create utxo set
     CCoinsView coinsDummy;
     CCoinsViewCache coins(&coinsDummy);
     // Create key
     CKey key;
     key.MakeNewKey(true);
     CPubKey pubkey = key.GetPubKey();
     // Default flags
     int flags = SCRIPT_VERIFY_P2SH;
 
     // Multisig script (legacy counting)
     {
         CScript scriptPubKey = CScript() << 1 << ToByteVector(pubkey)
                                          << ToByteVector(pubkey) << 2
                                          << OP_CHECKMULTISIGVERIFY;
         // Do not use a valid signature to avoid using wallet operations.
         CScript scriptSig = CScript() << OP_0 << OP_0;
 
         BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig);
         // Legacy counting only includes signature operations in scriptSigs and
         // scriptPubKeys of a transaction and does not take the actual executed
         // sig operations into account. spendingTx in itself does not contain a
         // signature operation.
         assert(GetTransactionSigOpCount(CTransaction(spendingTx), coins,
                                         flags) == 0);
         // creationTx contains two signature operations in its scriptPubKey, but
         // legacy counting is not accurate.
         assert(GetTransactionSigOpCount(CTransaction(creationTx), coins,
                                         flags) == MAX_PUBKEYS_PER_MULTISIG);
         // Sanity check: script verification fails because of an invalid
         // signature.
         assert(VerifyWithFlag(creationTx, spendingTx, flags) ==
                SCRIPT_ERR_CHECKMULTISIGVERIFY);
     }
 
     // Multisig nested in P2SH
     {
         CScript redeemScript = CScript() << 1 << ToByteVector(pubkey)
                                          << ToByteVector(pubkey) << 2
                                          << OP_CHECKMULTISIGVERIFY;
         CScript scriptPubKey = GetScriptForDestination(CScriptID(redeemScript));
         CScript scriptSig = CScript() << OP_0 << OP_0
                                       << ToByteVector(redeemScript);
 
         BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig);
         assert(GetTransactionSigOpCount(CTransaction(spendingTx), coins,
                                         flags) == 2);
         assert(VerifyWithFlag(creationTx, spendingTx, flags) ==
                SCRIPT_ERR_CHECKMULTISIGVERIFY);
     }
 }
 
 BOOST_AUTO_TEST_CASE(test_consensus_sigops_limit) {
     BOOST_CHECK_EQUAL(GetMaxBlockSigOpsCount(1), MAX_BLOCK_SIGOPS_PER_MB);
     BOOST_CHECK_EQUAL(GetMaxBlockSigOpsCount(123456), MAX_BLOCK_SIGOPS_PER_MB);
     BOOST_CHECK_EQUAL(GetMaxBlockSigOpsCount(1000000), MAX_BLOCK_SIGOPS_PER_MB);
     BOOST_CHECK_EQUAL(GetMaxBlockSigOpsCount(1000001),
                       2 * MAX_BLOCK_SIGOPS_PER_MB);
     BOOST_CHECK_EQUAL(GetMaxBlockSigOpsCount(1348592),
                       2 * MAX_BLOCK_SIGOPS_PER_MB);
     BOOST_CHECK_EQUAL(GetMaxBlockSigOpsCount(2000000),
                       2 * MAX_BLOCK_SIGOPS_PER_MB);
     BOOST_CHECK_EQUAL(GetMaxBlockSigOpsCount(2000001),
                       3 * MAX_BLOCK_SIGOPS_PER_MB);
     BOOST_CHECK_EQUAL(GetMaxBlockSigOpsCount(2654321),
                       3 * MAX_BLOCK_SIGOPS_PER_MB);
     BOOST_CHECK_EQUAL(
         GetMaxBlockSigOpsCount(std::numeric_limits<uint32_t>::max()),
         4295 * MAX_BLOCK_SIGOPS_PER_MB);
 }
 
 BOOST_AUTO_TEST_CASE(test_max_sigops_per_tx) {
     CMutableTransaction tx;
     tx.nVersion = 1;
     tx.vin.resize(1);
     tx.vin[0].prevout.hash = GetRandHash();
     tx.vin[0].prevout.n = 0;
     tx.vin[0].scriptSig = CScript();
     tx.vout.resize(1);
     tx.vout[0].nValue = 1;
     tx.vout[0].scriptPubKey = CScript();
 
     {
         CValidationState state;
         BOOST_CHECK(CheckRegularTransaction(tx, state, false));
     }
 
     // Get just before the limit.
     for (size_t i = 0; i < MAX_TX_SIGOPS_COUNT; i++) {
         tx.vout[0].scriptPubKey << OP_CHECKSIG;
     }
 
     {
         CValidationState state;
         BOOST_CHECK(CheckRegularTransaction(tx, state, false));
     }
 
     // And go over.
     tx.vout[0].scriptPubKey << OP_CHECKSIG;
 
     {
         CValidationState state;
         BOOST_CHECK(!CheckRegularTransaction(tx, state, false));
         BOOST_CHECK_EQUAL(state.GetRejectReason(), "bad-txn-sigops");
     }
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp
index 7e589b0dd..956430e4a 100644
--- a/src/test/streams_tests.cpp
+++ b/src/test/streams_tests.cpp
@@ -1,139 +1,139 @@
 // Copyright (c) 2012-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.
 
 #include "streams.h"
 #include "support/allocators/zeroafterfree.h"
 #include "test/test_bitcoin.h"
 
 #include <boost/assert.hpp>
 #include <boost/assign/std/vector.hpp> // for 'operator+=()'
 #include <boost/test/unit_test.hpp>
 
 using namespace boost::assign; // bring 'operator+=()' into scope
 
 BOOST_FIXTURE_TEST_SUITE(streams_tests, BasicTestingSetup)
 
 BOOST_AUTO_TEST_CASE(streams_vector_writer) {
-    unsigned char a(1);
-    unsigned char b(2);
-    unsigned char bytes[] = {3, 4, 5, 6};
-    std::vector<unsigned char> vch;
+    uint8_t a(1);
+    uint8_t b(2);
+    uint8_t bytes[] = {3, 4, 5, 6};
+    std::vector<uint8_t> vch;
 
     // Each test runs twice. Serializing a second time at the same starting
     // point should yield the same results, even if the first test grew the
     // vector.
 
     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, a, b);
-    BOOST_CHECK((vch == std::vector<unsigned char>{{1, 2}}));
+    BOOST_CHECK((vch == std::vector<uint8_t>{{1, 2}}));
     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, a, b);
-    BOOST_CHECK((vch == std::vector<unsigned char>{{1, 2}}));
+    BOOST_CHECK((vch == std::vector<uint8_t>{{1, 2}}));
     vch.clear();
 
     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, b);
-    BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 1, 2}}));
+    BOOST_CHECK((vch == std::vector<uint8_t>{{0, 0, 1, 2}}));
     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, b);
-    BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 1, 2}}));
+    BOOST_CHECK((vch == std::vector<uint8_t>{{0, 0, 1, 2}}));
     vch.clear();
 
     vch.resize(5, 0);
     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, b);
-    BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 1, 2, 0}}));
+    BOOST_CHECK((vch == std::vector<uint8_t>{{0, 0, 1, 2, 0}}));
     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, b);
-    BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 1, 2, 0}}));
+    BOOST_CHECK((vch == std::vector<uint8_t>{{0, 0, 1, 2, 0}}));
     vch.clear();
 
     vch.resize(4, 0);
     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 3, a, b);
-    BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 0, 1, 2}}));
+    BOOST_CHECK((vch == std::vector<uint8_t>{{0, 0, 0, 1, 2}}));
     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 3, a, b);
-    BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 0, 1, 2}}));
+    BOOST_CHECK((vch == std::vector<uint8_t>{{0, 0, 0, 1, 2}}));
     vch.clear();
 
     vch.resize(4, 0);
     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 4, a, b);
-    BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 0, 0, 1, 2}}));
+    BOOST_CHECK((vch == std::vector<uint8_t>{{0, 0, 0, 0, 1, 2}}));
     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 4, a, b);
-    BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 0, 0, 1, 2}}));
+    BOOST_CHECK((vch == std::vector<uint8_t>{{0, 0, 0, 0, 1, 2}}));
     vch.clear();
 
     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, FLATDATA(bytes));
-    BOOST_CHECK((vch == std::vector<unsigned char>{{3, 4, 5, 6}}));
+    BOOST_CHECK((vch == std::vector<uint8_t>{{3, 4, 5, 6}}));
     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, FLATDATA(bytes));
-    BOOST_CHECK((vch == std::vector<unsigned char>{{3, 4, 5, 6}}));
+    BOOST_CHECK((vch == std::vector<uint8_t>{{3, 4, 5, 6}}));
     vch.clear();
 
     vch.resize(4, 8);
     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, FLATDATA(bytes),
                   b);
-    BOOST_CHECK((vch == std::vector<unsigned char>{{8, 8, 1, 3, 4, 5, 6, 2}}));
+    BOOST_CHECK((vch == std::vector<uint8_t>{{8, 8, 1, 3, 4, 5, 6, 2}}));
     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, FLATDATA(bytes),
                   b);
-    BOOST_CHECK((vch == std::vector<unsigned char>{{8, 8, 1, 3, 4, 5, 6, 2}}));
+    BOOST_CHECK((vch == std::vector<uint8_t>{{8, 8, 1, 3, 4, 5, 6, 2}}));
     vch.clear();
 }
 
 BOOST_AUTO_TEST_CASE(streams_serializedata_xor) {
     std::vector<char> in;
     std::vector<char> expected_xor;
-    std::vector<unsigned char> key;
+    std::vector<uint8_t> key;
     CDataStream ds(in, 0, 0);
 
     // Degenerate case
 
     key += '\x00', '\x00';
     ds.Xor(key);
     BOOST_CHECK_EQUAL(std::string(expected_xor.begin(), expected_xor.end()),
                       std::string(ds.begin(), ds.end()));
 
     in += '\x0f', '\xf0';
     expected_xor += '\xf0', '\x0f';
 
     // Single character key
 
     ds.clear();
     ds.insert(ds.begin(), in.begin(), in.end());
     key.clear();
 
     key += '\xff';
     ds.Xor(key);
     BOOST_CHECK_EQUAL(std::string(expected_xor.begin(), expected_xor.end()),
                       std::string(ds.begin(), ds.end()));
 
     // Multi character key
 
     in.clear();
     expected_xor.clear();
     in += '\xf0', '\x0f';
     expected_xor += '\x0f', '\x00';
 
     ds.clear();
     ds.insert(ds.begin(), in.begin(), in.end());
 
     key.clear();
     key += '\xff', '\x0f';
 
     ds.Xor(key);
     BOOST_CHECK_EQUAL(std::string(expected_xor.begin(), expected_xor.end()),
                       std::string(ds.begin(), ds.end()));
 }
 
 BOOST_AUTO_TEST_CASE(streams_empty_vector) {
     std::vector<char> in;
     CDataStream ds(in, 0, 0);
 
     // read 0 bytes used to cause a segfault on some older systems.
     ds.read(nullptr, 0);
 
     // Same goes for writing 0 bytes from a vector ...
     const std::vector<char> vdata{'f', 'o', 'o', 'b', 'a', 'r'};
     ds.insert(ds.begin(), vdata.begin(), vdata.begin());
     ds.insert(ds.begin(), vdata.begin(), vdata.end());
 
     // ... or an array.
     const char adata[6] = {'f', 'o', 'o', 'b', 'a', 'r'};
     ds.insert(ds.begin(), &adata[0], &adata[0]);
     ds.insert(ds.begin(), &adata[0], &adata[6]);
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index 0a64469e1..140d22832 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -1,640 +1,640 @@
 // Copyright (c) 2011-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.
 
 #include "data/tx_invalid.json.h"
 #include "data/tx_valid.json.h"
 #include "test/test_bitcoin.h"
 
 #include "clientversion.h"
 #include "consensus/validation.h"
 #include "core_io.h"
 #include "key.h"
 #include "keystore.h"
 #include "policy/policy.h"
 #include "script/script.h"
 #include "script/script_error.h"
 #include "script/sign.h"
 #include "script/standard.h"
 #include "test/scriptflags.h"
 #include "utilstrencodings.h"
 #include "validation.h" // For CheckRegularTransaction
 
 #include <map>
 #include <string>
 
 #include <boost/range/adaptor/reversed.hpp>
 #include <boost/test/unit_test.hpp>
 
 #include <univalue.h>
 
-typedef std::vector<unsigned char> valtype;
+typedef std::vector<uint8_t> valtype;
 
 // In script_tests.cpp
 extern UniValue read_json(const std::string &jsondata);
 
 BOOST_FIXTURE_TEST_SUITE(transaction_tests, BasicTestingSetup)
 
 BOOST_AUTO_TEST_CASE(tx_valid) {
     // Read tests from test/data/tx_valid.json
     // Format is an array of arrays
     // Inner arrays are either [ "comment" ]
     // or [[[prevout hash, prevout index, prevout scriptPubKey], [input 2],
     // ...],"], serializedTransaction, verifyFlags
     // ... where all scripts are stringified scripts.
     //
     // verifyFlags is a comma separated list of script verification flags to
     // apply, or "NONE"
     UniValue tests = read_json(
         std::string(json_tests::tx_valid,
                     json_tests::tx_valid + sizeof(json_tests::tx_valid)));
 
     ScriptError err;
     for (size_t idx = 0; idx < tests.size(); idx++) {
         UniValue test = tests[idx];
         std::string strTest = test.write();
         if (test[0].isArray()) {
             if (test.size() != 3 || !test[1].isStr() || !test[2].isStr()) {
                 BOOST_ERROR("Bad test: " << strTest);
                 continue;
             }
 
             std::map<COutPoint, CScript> mapprevOutScriptPubKeys;
             std::map<COutPoint, int64_t> mapprevOutValues;
             UniValue inputs = test[0].get_array();
             bool fValid = true;
             for (size_t inpIdx = 0; inpIdx < inputs.size(); inpIdx++) {
                 const UniValue &input = inputs[inpIdx];
                 if (!input.isArray()) {
                     fValid = false;
                     break;
                 }
                 UniValue vinput = input.get_array();
                 if (vinput.size() < 3 || vinput.size() > 4) {
                     fValid = false;
                     break;
                 }
                 COutPoint outpoint(uint256S(vinput[0].get_str()),
                                    vinput[1].get_int());
                 mapprevOutScriptPubKeys[outpoint] =
                     ParseScript(vinput[2].get_str());
                 if (vinput.size() >= 4) {
                     mapprevOutValues[outpoint] = vinput[3].get_int64();
                 }
             }
             if (!fValid) {
                 BOOST_ERROR("Bad test: " << strTest);
                 continue;
             }
 
             std::string transaction = test[1].get_str();
             CDataStream stream(ParseHex(transaction), SER_NETWORK,
                                PROTOCOL_VERSION);
             CTransaction tx(deserialize, stream);
 
             CValidationState state;
             BOOST_CHECK_MESSAGE(tx.IsCoinBase()
                                     ? CheckCoinbase(tx, state)
                                     : CheckRegularTransaction(tx, state),
                                 strTest);
             BOOST_CHECK(state.IsValid());
 
             PrecomputedTransactionData txdata(tx);
             for (size_t i = 0; i < tx.vin.size(); i++) {
                 if (!mapprevOutScriptPubKeys.count(tx.vin[i].prevout)) {
                     BOOST_ERROR("Bad test: " << strTest);
                     break;
                 }
 
                 CAmount amount = 0;
                 if (mapprevOutValues.count(tx.vin[i].prevout)) {
                     amount = mapprevOutValues[tx.vin[i].prevout];
                 }
 
                 uint32_t verify_flags = ParseScriptFlags(test[2].get_str());
                 BOOST_CHECK_MESSAGE(
                     VerifyScript(tx.vin[i].scriptSig,
                                  mapprevOutScriptPubKeys[tx.vin[i].prevout],
                                  verify_flags, TransactionSignatureChecker(
                                                    &tx, i, amount, txdata),
                                  &err),
                     strTest);
                 BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK,
                                     ScriptErrorString(err));
             }
         }
     }
 }
 
 BOOST_AUTO_TEST_CASE(tx_invalid) {
     // Read tests from test/data/tx_invalid.json
     // Format is an array of arrays
     // Inner arrays are either [ "comment" ]
     // or [[[prevout hash, prevout index, prevout scriptPubKey], [input 2],
     // ...],"], serializedTransaction, verifyFlags
     // ... where all scripts are stringified scripts.
     //
     // verifyFlags is a comma separated list of script verification flags to
     // apply, or "NONE"
     UniValue tests = read_json(
         std::string(json_tests::tx_invalid,
                     json_tests::tx_invalid + sizeof(json_tests::tx_invalid)));
 
     ScriptError err;
     for (size_t idx = 0; idx < tests.size(); idx++) {
         UniValue test = tests[idx];
         std::string strTest = test.write();
         if (test[0].isArray()) {
             if (test.size() != 3 || !test[1].isStr() || !test[2].isStr()) {
                 BOOST_ERROR("Bad test: " << strTest);
                 continue;
             }
 
             std::map<COutPoint, CScript> mapprevOutScriptPubKeys;
             std::map<COutPoint, int64_t> mapprevOutValues;
             UniValue inputs = test[0].get_array();
             bool fValid = true;
             for (size_t inpIdx = 0; inpIdx < inputs.size(); inpIdx++) {
                 const UniValue &input = inputs[inpIdx];
                 if (!input.isArray()) {
                     fValid = false;
                     break;
                 }
                 UniValue vinput = input.get_array();
                 if (vinput.size() < 3 || vinput.size() > 4) {
                     fValid = false;
                     break;
                 }
                 COutPoint outpoint(uint256S(vinput[0].get_str()),
                                    vinput[1].get_int());
                 mapprevOutScriptPubKeys[outpoint] =
                     ParseScript(vinput[2].get_str());
                 if (vinput.size() >= 4) {
                     mapprevOutValues[outpoint] = vinput[3].get_int64();
                 }
             }
             if (!fValid) {
                 BOOST_ERROR("Bad test: " << strTest);
                 continue;
             }
 
             std::string transaction = test[1].get_str();
             CDataStream stream(ParseHex(transaction), SER_NETWORK,
                                PROTOCOL_VERSION);
             CTransaction tx(deserialize, stream);
 
             CValidationState state;
             fValid = CheckRegularTransaction(tx, state) && state.IsValid();
 
             PrecomputedTransactionData txdata(tx);
             for (size_t i = 0; i < tx.vin.size() && fValid; i++) {
                 if (!mapprevOutScriptPubKeys.count(tx.vin[i].prevout)) {
                     BOOST_ERROR("Bad test: " << strTest);
                     break;
                 }
 
                 CAmount amount = 0;
                 if (mapprevOutValues.count(tx.vin[i].prevout)) {
                     amount = mapprevOutValues[tx.vin[i].prevout];
                 }
 
                 uint32_t verify_flags = ParseScriptFlags(test[2].get_str());
                 fValid = VerifyScript(
                     tx.vin[i].scriptSig,
                     mapprevOutScriptPubKeys[tx.vin[i].prevout], verify_flags,
                     TransactionSignatureChecker(&tx, i, amount, txdata), &err);
             }
             BOOST_CHECK_MESSAGE(!fValid, strTest);
             BOOST_CHECK_MESSAGE(err != SCRIPT_ERR_OK, ScriptErrorString(err));
         }
     }
 }
 
 BOOST_AUTO_TEST_CASE(basic_transaction_tests) {
     // Random real transaction
     // (e2769b09e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436)
-    unsigned char ch[] = {
+    uint8_t ch[] = {
         0x01, 0x00, 0x00, 0x00, 0x01, 0x6b, 0xff, 0x7f, 0xcd, 0x4f, 0x85, 0x65,
         0xef, 0x40, 0x6d, 0xd5, 0xd6, 0x3d, 0x4f, 0xf9, 0x4f, 0x31, 0x8f, 0xe8,
         0x20, 0x27, 0xfd, 0x4d, 0xc4, 0x51, 0xb0, 0x44, 0x74, 0x01, 0x9f, 0x74,
         0xb4, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x49, 0x30, 0x46, 0x02, 0x21, 0x00,
         0xda, 0x0d, 0xc6, 0xae, 0xce, 0xfe, 0x1e, 0x06, 0xef, 0xdf, 0x05, 0x77,
         0x37, 0x57, 0xde, 0xb1, 0x68, 0x82, 0x09, 0x30, 0xe3, 0xb0, 0xd0, 0x3f,
         0x46, 0xf5, 0xfc, 0xf1, 0x50, 0xbf, 0x99, 0x0c, 0x02, 0x21, 0x00, 0xd2,
         0x5b, 0x5c, 0x87, 0x04, 0x00, 0x76, 0xe4, 0xf2, 0x53, 0xf8, 0x26, 0x2e,
         0x76, 0x3e, 0x2d, 0xd5, 0x1e, 0x7f, 0xf0, 0xbe, 0x15, 0x77, 0x27, 0xc4,
         0xbc, 0x42, 0x80, 0x7f, 0x17, 0xbd, 0x39, 0x01, 0x41, 0x04, 0xe6, 0xc2,
         0x6e, 0xf6, 0x7d, 0xc6, 0x10, 0xd2, 0xcd, 0x19, 0x24, 0x84, 0x78, 0x9a,
         0x6c, 0xf9, 0xae, 0xa9, 0x93, 0x0b, 0x94, 0x4b, 0x7e, 0x2d, 0xb5, 0x34,
         0x2b, 0x9d, 0x9e, 0x5b, 0x9f, 0xf7, 0x9a, 0xff, 0x9a, 0x2e, 0xe1, 0x97,
         0x8d, 0xd7, 0xfd, 0x01, 0xdf, 0xc5, 0x22, 0xee, 0x02, 0x28, 0x3d, 0x3b,
         0x06, 0xa9, 0xd0, 0x3a, 0xcf, 0x80, 0x96, 0x96, 0x8d, 0x7d, 0xbb, 0x0f,
         0x91, 0x78, 0xff, 0xff, 0xff, 0xff, 0x02, 0x8b, 0xa7, 0x94, 0x0e, 0x00,
         0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14, 0xba, 0xde, 0xec, 0xfd, 0xef,
         0x05, 0x07, 0x24, 0x7f, 0xc8, 0xf7, 0x42, 0x41, 0xd7, 0x3b, 0xc0, 0x39,
         0x97, 0x2d, 0x7b, 0x88, 0xac, 0x40, 0x94, 0xa8, 0x02, 0x00, 0x00, 0x00,
         0x00, 0x19, 0x76, 0xa9, 0x14, 0xc1, 0x09, 0x32, 0x48, 0x3f, 0xec, 0x93,
         0xed, 0x51, 0xf5, 0xfe, 0x95, 0xe7, 0x25, 0x59, 0xf2, 0xcc, 0x70, 0x43,
         0xf9, 0x88, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00};
-    std::vector<unsigned char> vch(ch, ch + sizeof(ch) - 1);
+    std::vector<uint8_t> vch(ch, ch + sizeof(ch) - 1);
     CDataStream stream(vch, SER_DISK, CLIENT_VERSION);
     CMutableTransaction tx;
     stream >> tx;
     CValidationState state;
     BOOST_CHECK_MESSAGE(CheckRegularTransaction(tx, state) && state.IsValid(),
                         "Simple deserialized transaction should be valid.");
 
     // Check that duplicate txins fail
     tx.vin.push_back(tx.vin[0]);
     BOOST_CHECK_MESSAGE(!CheckRegularTransaction(tx, state) || !state.IsValid(),
                         "Transaction with duplicate txins should be invalid.");
 }
 
 //
 // Helper: create two dummy transactions, each with
 // two outputs.  The first has 11 and 50 CENT outputs
 // paid to a TX_PUBKEY, the second 21 and 22 CENT outputs
 // paid to a TX_PUBKEYHASH.
 //
 static std::vector<CMutableTransaction>
 SetupDummyInputs(CBasicKeyStore &keystoreRet, CCoinsViewCache &coinsRet) {
     std::vector<CMutableTransaction> dummyTransactions;
     dummyTransactions.resize(2);
 
     // Add some keys to the keystore:
     CKey key[4];
     for (int i = 0; i < 4; i++) {
         key[i].MakeNewKey(i % 2);
         keystoreRet.AddKey(key[i]);
     }
 
     // Create some dummy input transactions
     dummyTransactions[0].vout.resize(2);
     dummyTransactions[0].vout[0].nValue = 11 * CENT;
     dummyTransactions[0].vout[0].scriptPubKey
         << ToByteVector(key[0].GetPubKey()) << OP_CHECKSIG;
     dummyTransactions[0].vout[1].nValue = 50 * CENT;
     dummyTransactions[0].vout[1].scriptPubKey
         << ToByteVector(key[1].GetPubKey()) << OP_CHECKSIG;
     coinsRet.ModifyCoins(dummyTransactions[0].GetId())
         ->FromTx(dummyTransactions[0], 0);
 
     dummyTransactions[1].vout.resize(2);
     dummyTransactions[1].vout[0].nValue = 21 * CENT;
     dummyTransactions[1].vout[0].scriptPubKey =
         GetScriptForDestination(key[2].GetPubKey().GetID());
     dummyTransactions[1].vout[1].nValue = 22 * CENT;
     dummyTransactions[1].vout[1].scriptPubKey =
         GetScriptForDestination(key[3].GetPubKey().GetID());
     coinsRet.ModifyCoins(dummyTransactions[1].GetId())
         ->FromTx(dummyTransactions[1], 0);
 
     return dummyTransactions;
 }
 
 BOOST_AUTO_TEST_CASE(test_Get) {
     CBasicKeyStore keystore;
     CCoinsView coinsDummy;
     CCoinsViewCache coins(&coinsDummy);
     std::vector<CMutableTransaction> dummyTransactions =
         SetupDummyInputs(keystore, coins);
 
     CMutableTransaction t1;
     t1.vin.resize(3);
     t1.vin[0].prevout.hash = dummyTransactions[0].GetId();
     t1.vin[0].prevout.n = 1;
-    t1.vin[0].scriptSig << std::vector<unsigned char>(65, 0);
+    t1.vin[0].scriptSig << std::vector<uint8_t>(65, 0);
     t1.vin[1].prevout.hash = dummyTransactions[1].GetId();
     t1.vin[1].prevout.n = 0;
-    t1.vin[1].scriptSig << std::vector<unsigned char>(65, 0)
-                        << std::vector<unsigned char>(33, 4);
+    t1.vin[1].scriptSig << std::vector<uint8_t>(65, 0)
+                        << std::vector<uint8_t>(33, 4);
     t1.vin[2].prevout.hash = dummyTransactions[1].GetId();
     t1.vin[2].prevout.n = 1;
-    t1.vin[2].scriptSig << std::vector<unsigned char>(65, 0)
-                        << std::vector<unsigned char>(33, 4);
+    t1.vin[2].scriptSig << std::vector<uint8_t>(65, 0)
+                        << std::vector<uint8_t>(33, 4);
     t1.vout.resize(2);
     t1.vout[0].nValue = 90 * CENT;
     t1.vout[0].scriptPubKey << OP_1;
 
     BOOST_CHECK(AreInputsStandard(t1, coins));
     BOOST_CHECK_EQUAL(coins.GetValueIn(t1), (50 + 21 + 22) * CENT);
 }
 
 void CreateCreditAndSpend(const CKeyStore &keystore, const CScript &outscript,
                           CTransactionRef &output, CMutableTransaction &input,
                           bool success = true) {
     CMutableTransaction outputm;
     outputm.nVersion = 1;
     outputm.vin.resize(1);
     outputm.vin[0].prevout.SetNull();
     outputm.vin[0].scriptSig = CScript();
     outputm.vout.resize(1);
     outputm.vout[0].nValue = 1;
     outputm.vout[0].scriptPubKey = outscript;
     CDataStream ssout(SER_NETWORK, PROTOCOL_VERSION);
     ssout << outputm;
     ssout >> output;
     BOOST_CHECK_EQUAL(output->vin.size(), 1);
     BOOST_CHECK(output->vin[0] == outputm.vin[0]);
     BOOST_CHECK_EQUAL(output->vout.size(), 1);
     BOOST_CHECK(output->vout[0] == outputm.vout[0]);
 
     CMutableTransaction inputm;
     inputm.nVersion = 1;
     inputm.vin.resize(1);
     inputm.vin[0].prevout.hash = output->GetId();
     inputm.vin[0].prevout.n = 0;
     inputm.vout.resize(1);
     inputm.vout[0].nValue = 1;
     inputm.vout[0].scriptPubKey = CScript();
     bool ret = SignSignature(keystore, *output, inputm, 0,
                              SIGHASH_ALL | SIGHASH_FORKID);
     BOOST_CHECK_EQUAL(ret, success);
     CDataStream ssin(SER_NETWORK, PROTOCOL_VERSION);
     ssin << inputm;
     ssin >> input;
     BOOST_CHECK_EQUAL(input.vin.size(), 1);
     BOOST_CHECK(input.vin[0] == inputm.vin[0]);
     BOOST_CHECK_EQUAL(input.vout.size(), 1);
     BOOST_CHECK(input.vout[0] == inputm.vout[0]);
 }
 
 void CheckWithFlag(const CTransactionRef &output,
                    const CMutableTransaction &input, int flags, bool success) {
     ScriptError error;
     CTransaction inputi(input);
     bool ret = VerifyScript(
         inputi.vin[0].scriptSig, output->vout[0].scriptPubKey,
         flags | SCRIPT_ENABLE_SIGHASH_FORKID,
         TransactionSignatureChecker(&inputi, 0, output->vout[0].nValue),
         &error);
     BOOST_CHECK_EQUAL(ret, success);
 }
 
 static CScript PushAll(const std::vector<valtype> &values) {
     CScript result;
     for (const valtype &v : values) {
         if (v.size() == 0) {
             result << OP_0;
         } else if (v.size() == 1 && v[0] >= 1 && v[0] <= 16) {
             result << CScript::EncodeOP_N(v[0]);
         } else {
             result << v;
         }
     }
     return result;
 }
 
 void ReplaceRedeemScript(CScript &script, const CScript &redeemScript) {
     std::vector<valtype> stack;
     EvalScript(stack, script, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker());
     BOOST_CHECK(stack.size() > 0);
     stack.back() =
-        std::vector<unsigned char>(redeemScript.begin(), redeemScript.end());
+        std::vector<uint8_t>(redeemScript.begin(), redeemScript.end());
     script = PushAll(stack);
 }
 
 BOOST_AUTO_TEST_CASE(test_witness) {
     CBasicKeyStore keystore, keystore2;
     CKey key1, key2, key3, key1L, key2L;
     CPubKey pubkey1, pubkey2, pubkey3, pubkey1L, pubkey2L;
     key1.MakeNewKey(true);
     key2.MakeNewKey(true);
     key3.MakeNewKey(true);
     key1L.MakeNewKey(false);
     key2L.MakeNewKey(false);
     pubkey1 = key1.GetPubKey();
     pubkey2 = key2.GetPubKey();
     pubkey3 = key3.GetPubKey();
     pubkey1L = key1L.GetPubKey();
     pubkey2L = key2L.GetPubKey();
     keystore.AddKeyPubKey(key1, pubkey1);
     keystore.AddKeyPubKey(key2, pubkey2);
     keystore.AddKeyPubKey(key1L, pubkey1L);
     keystore.AddKeyPubKey(key2L, pubkey2L);
     CScript scriptPubkey1, scriptPubkey2, scriptPubkey1L, scriptPubkey2L,
         scriptMulti;
     scriptPubkey1 << ToByteVector(pubkey1) << OP_CHECKSIG;
     scriptPubkey2 << ToByteVector(pubkey2) << OP_CHECKSIG;
     scriptPubkey1L << ToByteVector(pubkey1L) << OP_CHECKSIG;
     scriptPubkey2L << ToByteVector(pubkey2L) << OP_CHECKSIG;
     std::vector<CPubKey> oneandthree;
     oneandthree.push_back(pubkey1);
     oneandthree.push_back(pubkey3);
     scriptMulti = GetScriptForMultisig(2, oneandthree);
     keystore.AddCScript(scriptPubkey1);
     keystore.AddCScript(scriptPubkey2);
     keystore.AddCScript(scriptPubkey1L);
     keystore.AddCScript(scriptPubkey2L);
     keystore.AddCScript(scriptMulti);
     keystore2.AddCScript(scriptMulti);
     keystore2.AddKeyPubKey(key3, pubkey3);
 
     CTransactionRef output1, output2;
     CMutableTransaction input1, input2;
     SignatureData sigdata;
 
     // Normal pay-to-compressed-pubkey.
     CreateCreditAndSpend(keystore, scriptPubkey1, output1, input1);
     CreateCreditAndSpend(keystore, scriptPubkey2, output2, input2);
     CheckWithFlag(output1, input1, 0, true);
     CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
     CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
     CheckWithFlag(output1, input2, 0, false);
     CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, false);
     CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);
 
     // P2SH pay-to-compressed-pubkey.
     CreateCreditAndSpend(keystore,
                          GetScriptForDestination(CScriptID(scriptPubkey1)),
                          output1, input1);
     CreateCreditAndSpend(keystore,
                          GetScriptForDestination(CScriptID(scriptPubkey2)),
                          output2, input2);
     ReplaceRedeemScript(input2.vin[0].scriptSig, scriptPubkey1);
     CheckWithFlag(output1, input1, 0, true);
     CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
     CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
     CheckWithFlag(output1, input2, 0, true);
     CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, false);
     CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);
 
     // Normal pay-to-uncompressed-pubkey.
     CreateCreditAndSpend(keystore, scriptPubkey1L, output1, input1);
     CreateCreditAndSpend(keystore, scriptPubkey2L, output2, input2);
     CheckWithFlag(output1, input1, 0, true);
     CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
     CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
     CheckWithFlag(output1, input2, 0, false);
     CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, false);
     CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);
 
     // P2SH pay-to-uncompressed-pubkey.
     CreateCreditAndSpend(keystore,
                          GetScriptForDestination(CScriptID(scriptPubkey1L)),
                          output1, input1);
     CreateCreditAndSpend(keystore,
                          GetScriptForDestination(CScriptID(scriptPubkey2L)),
                          output2, input2);
     ReplaceRedeemScript(input2.vin[0].scriptSig, scriptPubkey1L);
     CheckWithFlag(output1, input1, 0, true);
     CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
     CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
     CheckWithFlag(output1, input2, 0, true);
     CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, false);
     CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);
 
     // Normal 2-of-2 multisig
     CreateCreditAndSpend(keystore, scriptMulti, output1, input1, false);
     CheckWithFlag(output1, input1, 0, false);
     CreateCreditAndSpend(keystore2, scriptMulti, output2, input2, false);
     CheckWithFlag(output2, input2, 0, false);
     BOOST_CHECK(*output1 == *output2);
     UpdateTransaction(
         input1, 0, CombineSignatures(output1->vout[0].scriptPubKey,
                                      MutableTransactionSignatureChecker(
                                          &input1, 0, output1->vout[0].nValue),
                                      DataFromTransaction(input1, 0),
                                      DataFromTransaction(input2, 0)));
     CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
 
     // P2SH 2-of-2 multisig
     CreateCreditAndSpend(keystore,
                          GetScriptForDestination(CScriptID(scriptMulti)),
                          output1, input1, false);
     CheckWithFlag(output1, input1, 0, true);
     CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, false);
     CreateCreditAndSpend(keystore2,
                          GetScriptForDestination(CScriptID(scriptMulti)),
                          output2, input2, false);
     CheckWithFlag(output2, input2, 0, true);
     CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH, false);
     BOOST_CHECK(*output1 == *output2);
     UpdateTransaction(
         input1, 0, CombineSignatures(output1->vout[0].scriptPubKey,
                                      MutableTransactionSignatureChecker(
                                          &input1, 0, output1->vout[0].nValue),
                                      DataFromTransaction(input1, 0),
                                      DataFromTransaction(input2, 0)));
     CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
     CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
 }
 
 BOOST_AUTO_TEST_CASE(test_IsStandard) {
     LOCK(cs_main);
     CBasicKeyStore keystore;
     CCoinsView coinsDummy;
     CCoinsViewCache coins(&coinsDummy);
     std::vector<CMutableTransaction> dummyTransactions =
         SetupDummyInputs(keystore, coins);
 
     CMutableTransaction t;
     t.vin.resize(1);
     t.vin[0].prevout.hash = dummyTransactions[0].GetId();
     t.vin[0].prevout.n = 1;
-    t.vin[0].scriptSig << std::vector<unsigned char>(65, 0);
+    t.vin[0].scriptSig << std::vector<uint8_t>(65, 0);
     t.vout.resize(1);
     t.vout[0].nValue = 90 * CENT;
     CKey key;
     key.MakeNewKey(true);
     t.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID());
 
     std::string reason;
     BOOST_CHECK(IsStandardTx(t, reason));
 
     // Check dust with default relay fee:
     CAmount nDustThreshold = 182 * dustRelayFee.GetFeePerK() / 1000 * 3;
     BOOST_CHECK_EQUAL(nDustThreshold, 546);
     // dust:
     t.vout[0].nValue = nDustThreshold - 1;
     BOOST_CHECK(!IsStandardTx(t, reason));
     // not dust:
     t.vout[0].nValue = nDustThreshold;
     BOOST_CHECK(IsStandardTx(t, reason));
 
     // Check dust with odd relay fee to verify rounding:
     // nDustThreshold = 182 * 1234 / 1000 * 3
     dustRelayFee = CFeeRate(1234);
     // dust:
     t.vout[0].nValue = 672 - 1;
     BOOST_CHECK(!IsStandardTx(t, reason));
     // not dust:
     t.vout[0].nValue = 672;
     BOOST_CHECK(IsStandardTx(t, reason));
     dustRelayFee = CFeeRate(DUST_RELAY_TX_FEE);
 
     t.vout[0].scriptPubKey = CScript() << OP_1;
     BOOST_CHECK(!IsStandardTx(t, reason));
 
     // MAX_OP_RETURN_RELAY-byte TX_NULL_DATA (standard)
     t.vout[0].scriptPubKey =
         CScript() << OP_RETURN
                   << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909"
                               "a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548"
                               "271967f1a67130b7105cd6a828e03909a67962e0ea1f61de"
                               "b649f6bc3f4cef38");
     BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY, t.vout[0].scriptPubKey.size());
     BOOST_CHECK(IsStandardTx(t, reason));
 
     // MAX_OP_RETURN_RELAY+1-byte TX_NULL_DATA (non-standard)
     t.vout[0].scriptPubKey =
         CScript() << OP_RETURN
                   << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909"
                               "a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548"
                               "271967f1a67130b7105cd6a828e03909a67962e0ea1f61de"
                               "b649f6bc3f4cef3800");
     BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY + 1, t.vout[0].scriptPubKey.size());
     BOOST_CHECK(!IsStandardTx(t, reason));
 
     // Data payload can be encoded in any way...
     t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("");
     BOOST_CHECK(IsStandardTx(t, reason));
     t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("00")
                                        << ParseHex("01");
     BOOST_CHECK(IsStandardTx(t, reason));
     // OP_RESERVED *is* considered to be a PUSHDATA type opcode by IsPushOnly()!
     t.vout[0].scriptPubKey = CScript() << OP_RETURN << OP_RESERVED << -1 << 0
                                        << ParseHex("01") << 2 << 3 << 4 << 5
                                        << 6 << 7 << 8 << 9 << 10 << 11 << 12
                                        << 13 << 14 << 15 << 16;
     BOOST_CHECK(IsStandardTx(t, reason));
     t.vout[0].scriptPubKey = CScript()
                              << OP_RETURN << 0 << ParseHex("01") << 2
                              << ParseHex("fffffffffffffffffffffffffffffffffffff"
                                          "fffffffffffffffffffffffffffffffffff");
     BOOST_CHECK(IsStandardTx(t, reason));
 
     // ...so long as it only contains PUSHDATA's
     t.vout[0].scriptPubKey = CScript() << OP_RETURN << OP_RETURN;
     BOOST_CHECK(!IsStandardTx(t, reason));
 
     // TX_NULL_DATA w/o PUSHDATA
     t.vout.resize(1);
     t.vout[0].scriptPubKey = CScript() << OP_RETURN;
     BOOST_CHECK(IsStandardTx(t, reason));
 
     // Only one TX_NULL_DATA permitted in all cases
     t.vout.resize(2);
     t.vout[0].scriptPubKey =
         CScript() << OP_RETURN
                   << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909"
                               "a67962e0ea1f61deb649f6bc3f4cef38");
     t.vout[1].scriptPubKey =
         CScript() << OP_RETURN
                   << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909"
                               "a67962e0ea1f61deb649f6bc3f4cef38");
     BOOST_CHECK(!IsStandardTx(t, reason));
 
     t.vout[0].scriptPubKey =
         CScript() << OP_RETURN
                   << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909"
                               "a67962e0ea1f61deb649f6bc3f4cef38");
     t.vout[1].scriptPubKey = CScript() << OP_RETURN;
     BOOST_CHECK(!IsStandardTx(t, reason));
 
     t.vout[0].scriptPubKey = CScript() << OP_RETURN;
     t.vout[1].scriptPubKey = CScript() << OP_RETURN;
     BOOST_CHECK(!IsStandardTx(t, reason));
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/uint256_tests.cpp b/src/test/uint256_tests.cpp
index 50be5ac51..eafbfde51 100644
--- a/src/test/uint256_tests.cpp
+++ b/src/test/uint256_tests.cpp
@@ -1,277 +1,271 @@
 // Copyright (c) 2011-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.
 #include "uint256.h"
 #include "arith_uint256.h"
 #include "test/test_bitcoin.h"
 #include "version.h"
 
 #include <boost/test/unit_test.hpp>
 #include <cmath>
 #include <cstdint>
 #include <cstdio>
 #include <iomanip>
 #include <limits>
 #include <sstream>
 #include <string>
 
 BOOST_FIXTURE_TEST_SUITE(uint256_tests, BasicTestingSetup)
 
-const unsigned char R1Array[] =
+const uint8_t R1Array[] =
     "\x9c\x52\x4a\xdb\xcf\x56\x11\x12\x2b\x29\x12\x5e\x5d\x35\xd2\xd2"
     "\x22\x81\xaa\xb5\x33\xf0\x08\x32\xd5\x56\xb1\xf9\xea\xe5\x1d\x7d";
 const char R1ArrayHex[] =
     "7D1DE5EAF9B156D53208F033B5AA8122D2d2355d5e12292b121156cfdb4a529c";
-const uint256 R1L = uint256(std::vector<unsigned char>(R1Array, R1Array + 32));
-const uint160 R1S = uint160(std::vector<unsigned char>(R1Array, R1Array + 20));
+const uint256 R1L = uint256(std::vector<uint8_t>(R1Array, R1Array + 32));
+const uint160 R1S = uint160(std::vector<uint8_t>(R1Array, R1Array + 20));
 
-const unsigned char R2Array[] =
+const uint8_t R2Array[] =
     "\x70\x32\x1d\x7c\x47\xa5\x6b\x40\x26\x7e\x0a\xc3\xa6\x9c\xb6\xbf"
     "\x13\x30\x47\xa3\x19\x2d\xda\x71\x49\x13\x72\xf0\xb4\xca\x81\xd7";
-const uint256 R2L = uint256(std::vector<unsigned char>(R2Array, R2Array + 32));
-const uint160 R2S = uint160(std::vector<unsigned char>(R2Array, R2Array + 20));
+const uint256 R2L = uint256(std::vector<uint8_t>(R2Array, R2Array + 32));
+const uint160 R2S = uint160(std::vector<uint8_t>(R2Array, R2Array + 20));
 
-const unsigned char ZeroArray[] =
+const uint8_t ZeroArray[] =
     "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
     "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
-const uint256 ZeroL =
-    uint256(std::vector<unsigned char>(ZeroArray, ZeroArray + 32));
-const uint160 ZeroS =
-    uint160(std::vector<unsigned char>(ZeroArray, ZeroArray + 20));
+const uint256 ZeroL = uint256(std::vector<uint8_t>(ZeroArray, ZeroArray + 32));
+const uint160 ZeroS = uint160(std::vector<uint8_t>(ZeroArray, ZeroArray + 20));
 
-const unsigned char OneArray[] =
+const uint8_t OneArray[] =
     "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
     "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
-const uint256 OneL =
-    uint256(std::vector<unsigned char>(OneArray, OneArray + 32));
-const uint160 OneS =
-    uint160(std::vector<unsigned char>(OneArray, OneArray + 20));
+const uint256 OneL = uint256(std::vector<uint8_t>(OneArray, OneArray + 32));
+const uint160 OneS = uint160(std::vector<uint8_t>(OneArray, OneArray + 20));
 
-const unsigned char MaxArray[] =
+const uint8_t MaxArray[] =
     "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
     "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
-const uint256 MaxL =
-    uint256(std::vector<unsigned char>(MaxArray, MaxArray + 32));
-const uint160 MaxS =
-    uint160(std::vector<unsigned char>(MaxArray, MaxArray + 20));
+const uint256 MaxL = uint256(std::vector<uint8_t>(MaxArray, MaxArray + 32));
+const uint160 MaxS = uint160(std::vector<uint8_t>(MaxArray, MaxArray + 20));
 
-std::string ArrayToString(const unsigned char A[], unsigned int width) {
+std::string ArrayToString(const uint8_t A[], unsigned int width) {
     std::stringstream Stream;
     Stream << std::hex;
     for (unsigned int i = 0; i < width; ++i) {
         Stream << std::setw(2) << std::setfill('0')
                << (unsigned int)A[width - i - 1];
     }
     return Stream.str();
 }
 
 inline uint160 uint160S(const char *str) {
     uint160 rv;
     rv.SetHex(str);
     return rv;
 }
 inline uint160 uint160S(const std::string &str) {
     uint160 rv;
     rv.SetHex(str);
     return rv;
 }
 
 // constructors, equality, inequality
 BOOST_AUTO_TEST_CASE(basics) {
     BOOST_CHECK(1 == 0 + 1);
     // constructor uint256(vector<char>):
     BOOST_CHECK(R1L.ToString() == ArrayToString(R1Array, 32));
     BOOST_CHECK(R1S.ToString() == ArrayToString(R1Array, 20));
     BOOST_CHECK(R2L.ToString() == ArrayToString(R2Array, 32));
     BOOST_CHECK(R2S.ToString() == ArrayToString(R2Array, 20));
     BOOST_CHECK(ZeroL.ToString() == ArrayToString(ZeroArray, 32));
     BOOST_CHECK(ZeroS.ToString() == ArrayToString(ZeroArray, 20));
     BOOST_CHECK(OneL.ToString() == ArrayToString(OneArray, 32));
     BOOST_CHECK(OneS.ToString() == ArrayToString(OneArray, 20));
     BOOST_CHECK(MaxL.ToString() == ArrayToString(MaxArray, 32));
     BOOST_CHECK(MaxS.ToString() == ArrayToString(MaxArray, 20));
     BOOST_CHECK(OneL.ToString() != ArrayToString(ZeroArray, 32));
     BOOST_CHECK(OneS.ToString() != ArrayToString(ZeroArray, 20));
 
     // == and !=
     BOOST_CHECK(R1L != R2L && R1S != R2S);
     BOOST_CHECK(ZeroL != OneL && ZeroS != OneS);
     BOOST_CHECK(OneL != ZeroL && OneS != ZeroS);
     BOOST_CHECK(MaxL != ZeroL && MaxS != ZeroS);
 
     // String Constructor and Copy Constructor
     BOOST_CHECK(uint256S("0x" + R1L.ToString()) == R1L);
     BOOST_CHECK(uint256S("0x" + R2L.ToString()) == R2L);
     BOOST_CHECK(uint256S("0x" + ZeroL.ToString()) == ZeroL);
     BOOST_CHECK(uint256S("0x" + OneL.ToString()) == OneL);
     BOOST_CHECK(uint256S("0x" + MaxL.ToString()) == MaxL);
     BOOST_CHECK(uint256S(R1L.ToString()) == R1L);
     BOOST_CHECK(uint256S("   0x" + R1L.ToString() + "   ") == R1L);
     BOOST_CHECK(uint256S("") == ZeroL);
     BOOST_CHECK(R1L == uint256S(R1ArrayHex));
     BOOST_CHECK(uint256(R1L) == R1L);
     BOOST_CHECK(uint256(ZeroL) == ZeroL);
     BOOST_CHECK(uint256(OneL) == OneL);
 
     BOOST_CHECK(uint160S("0x" + R1S.ToString()) == R1S);
     BOOST_CHECK(uint160S("0x" + R2S.ToString()) == R2S);
     BOOST_CHECK(uint160S("0x" + ZeroS.ToString()) == ZeroS);
     BOOST_CHECK(uint160S("0x" + OneS.ToString()) == OneS);
     BOOST_CHECK(uint160S("0x" + MaxS.ToString()) == MaxS);
     BOOST_CHECK(uint160S(R1S.ToString()) == R1S);
     BOOST_CHECK(uint160S("   0x" + R1S.ToString() + "   ") == R1S);
     BOOST_CHECK(uint160S("") == ZeroS);
     BOOST_CHECK(R1S == uint160S(R1ArrayHex));
 
     BOOST_CHECK(uint160(R1S) == R1S);
     BOOST_CHECK(uint160(ZeroS) == ZeroS);
     BOOST_CHECK(uint160(OneS) == OneS);
 }
 
 // <= >= < >
 BOOST_AUTO_TEST_CASE(comparison) {
     uint256 LastL;
     for (int i = 255; i >= 0; --i) {
         uint256 TmpL;
         *(TmpL.begin() + (i >> 3)) |= 1 << (7 - (i & 7));
         BOOST_CHECK(LastL < TmpL);
         LastL = TmpL;
     }
 
     BOOST_CHECK(ZeroL < R1L);
     BOOST_CHECK(R2L < R1L);
     BOOST_CHECK(ZeroL < OneL);
     BOOST_CHECK(OneL < MaxL);
     BOOST_CHECK(R1L < MaxL);
     BOOST_CHECK(R2L < MaxL);
 
     uint160 LastS;
     for (int i = 159; i >= 0; --i) {
         uint160 TmpS;
         *(TmpS.begin() + (i >> 3)) |= 1 << (7 - (i & 7));
         BOOST_CHECK(LastS < TmpS);
         LastS = TmpS;
     }
     BOOST_CHECK(ZeroS < R1S);
     BOOST_CHECK(R2S < R1S);
     BOOST_CHECK(ZeroS < OneS);
     BOOST_CHECK(OneS < MaxS);
     BOOST_CHECK(R1S < MaxS);
     BOOST_CHECK(R2S < MaxS);
 }
 
 // GetHex SetHex begin() end() size() GetLow64 GetSerializeSize, Serialize,
 // Unserialize
 BOOST_AUTO_TEST_CASE(methods) {
     BOOST_CHECK(R1L.GetHex() == R1L.ToString());
     BOOST_CHECK(R2L.GetHex() == R2L.ToString());
     BOOST_CHECK(OneL.GetHex() == OneL.ToString());
     BOOST_CHECK(MaxL.GetHex() == MaxL.ToString());
     uint256 TmpL(R1L);
     BOOST_CHECK(TmpL == R1L);
     TmpL.SetHex(R2L.ToString());
     BOOST_CHECK(TmpL == R2L);
     TmpL.SetHex(ZeroL.ToString());
     BOOST_CHECK(TmpL == uint256());
 
     TmpL.SetHex(R1L.ToString());
     BOOST_CHECK(memcmp(R1L.begin(), R1Array, 32) == 0);
     BOOST_CHECK(memcmp(TmpL.begin(), R1Array, 32) == 0);
     BOOST_CHECK(memcmp(R2L.begin(), R2Array, 32) == 0);
     BOOST_CHECK(memcmp(ZeroL.begin(), ZeroArray, 32) == 0);
     BOOST_CHECK(memcmp(OneL.begin(), OneArray, 32) == 0);
     BOOST_CHECK(R1L.size() == sizeof(R1L));
     BOOST_CHECK(sizeof(R1L) == 32);
     BOOST_CHECK(R1L.size() == 32);
     BOOST_CHECK(R2L.size() == 32);
     BOOST_CHECK(ZeroL.size() == 32);
     BOOST_CHECK(MaxL.size() == 32);
     BOOST_CHECK(R1L.begin() + 32 == R1L.end());
     BOOST_CHECK(R2L.begin() + 32 == R2L.end());
     BOOST_CHECK(OneL.begin() + 32 == OneL.end());
     BOOST_CHECK(MaxL.begin() + 32 == MaxL.end());
     BOOST_CHECK(TmpL.begin() + 32 == TmpL.end());
     BOOST_CHECK(GetSerializeSize(R1L, 0, PROTOCOL_VERSION) == 32);
     BOOST_CHECK(GetSerializeSize(ZeroL, 0, PROTOCOL_VERSION) == 32);
 
     CDataStream ss(0, PROTOCOL_VERSION);
     ss << R1L;
     BOOST_CHECK(ss.str() == std::string(R1Array, R1Array + 32));
     ss >> TmpL;
     BOOST_CHECK(R1L == TmpL);
     ss.clear();
     ss << ZeroL;
     BOOST_CHECK(ss.str() == std::string(ZeroArray, ZeroArray + 32));
     ss >> TmpL;
     BOOST_CHECK(ZeroL == TmpL);
     ss.clear();
     ss << MaxL;
     BOOST_CHECK(ss.str() == std::string(MaxArray, MaxArray + 32));
     ss >> TmpL;
     BOOST_CHECK(MaxL == TmpL);
     ss.clear();
 
     BOOST_CHECK(R1S.GetHex() == R1S.ToString());
     BOOST_CHECK(R2S.GetHex() == R2S.ToString());
     BOOST_CHECK(OneS.GetHex() == OneS.ToString());
     BOOST_CHECK(MaxS.GetHex() == MaxS.ToString());
     uint160 TmpS(R1S);
     BOOST_CHECK(TmpS == R1S);
     TmpS.SetHex(R2S.ToString());
     BOOST_CHECK(TmpS == R2S);
     TmpS.SetHex(ZeroS.ToString());
     BOOST_CHECK(TmpS == uint160());
 
     TmpS.SetHex(R1S.ToString());
     BOOST_CHECK(memcmp(R1S.begin(), R1Array, 20) == 0);
     BOOST_CHECK(memcmp(TmpS.begin(), R1Array, 20) == 0);
     BOOST_CHECK(memcmp(R2S.begin(), R2Array, 20) == 0);
     BOOST_CHECK(memcmp(ZeroS.begin(), ZeroArray, 20) == 0);
     BOOST_CHECK(memcmp(OneS.begin(), OneArray, 20) == 0);
     BOOST_CHECK(R1S.size() == sizeof(R1S));
     BOOST_CHECK(sizeof(R1S) == 20);
     BOOST_CHECK(R1S.size() == 20);
     BOOST_CHECK(R2S.size() == 20);
     BOOST_CHECK(ZeroS.size() == 20);
     BOOST_CHECK(MaxS.size() == 20);
     BOOST_CHECK(R1S.begin() + 20 == R1S.end());
     BOOST_CHECK(R2S.begin() + 20 == R2S.end());
     BOOST_CHECK(OneS.begin() + 20 == OneS.end());
     BOOST_CHECK(MaxS.begin() + 20 == MaxS.end());
     BOOST_CHECK(TmpS.begin() + 20 == TmpS.end());
     BOOST_CHECK(GetSerializeSize(R1S, 0, PROTOCOL_VERSION) == 20);
     BOOST_CHECK(GetSerializeSize(ZeroS, 0, PROTOCOL_VERSION) == 20);
 
     ss << R1S;
     BOOST_CHECK(ss.str() == std::string(R1Array, R1Array + 20));
     ss >> TmpS;
     BOOST_CHECK(R1S == TmpS);
     ss.clear();
     ss << ZeroS;
     BOOST_CHECK(ss.str() == std::string(ZeroArray, ZeroArray + 20));
     ss >> TmpS;
     BOOST_CHECK(ZeroS == TmpS);
     ss.clear();
     ss << MaxS;
     BOOST_CHECK(ss.str() == std::string(MaxArray, MaxArray + 20));
     ss >> TmpS;
     BOOST_CHECK(MaxS == TmpS);
     ss.clear();
 }
 
 BOOST_AUTO_TEST_CASE(conversion) {
     BOOST_CHECK(ArithToUint256(UintToArith256(ZeroL)) == ZeroL);
     BOOST_CHECK(ArithToUint256(UintToArith256(OneL)) == OneL);
     BOOST_CHECK(ArithToUint256(UintToArith256(R1L)) == R1L);
     BOOST_CHECK(ArithToUint256(UintToArith256(R2L)) == R2L);
     BOOST_CHECK(UintToArith256(ZeroL) == 0);
     BOOST_CHECK(UintToArith256(OneL) == 1);
     BOOST_CHECK(ArithToUint256(0) == ZeroL);
     BOOST_CHECK(ArithToUint256(1) == OneL);
     BOOST_CHECK(arith_uint256(R1L.GetHex()) == UintToArith256(R1L));
     BOOST_CHECK(arith_uint256(R2L.GetHex()) == UintToArith256(R2L));
     BOOST_CHECK(R1L.GetHex() == UintToArith256(R1L).GetHex());
     BOOST_CHECK(R2L.GetHex() == UintToArith256(R2L).GetHex());
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index 1e0c25efe..c9d879bb4 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -1,623 +1,622 @@
 // Copyright (c) 2011-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.
 
 #include "util.h"
 
 #include "clientversion.h"
 #include "primitives/transaction.h"
 #include "sync.h"
 #include "test/test_bitcoin.h"
 #include "test/test_random.h"
 #include "utilmoneystr.h"
 #include "utilstrencodings.h"
 
 #include <cstdint>
 #include <vector>
 
 #include <boost/test/unit_test.hpp>
 
 extern std::map<std::string, std::string> mapArgs;
 
 BOOST_FIXTURE_TEST_SUITE(util_tests, BasicTestingSetup)
 
 BOOST_AUTO_TEST_CASE(util_criticalsection) {
     CCriticalSection cs;
 
     do {
         LOCK(cs);
         break;
 
         BOOST_ERROR("break was swallowed!");
     } while (0);
 
     do {
         TRY_LOCK(cs, lockTest);
         if (lockTest) break;
 
         BOOST_ERROR("break was swallowed!");
     } while (0);
 }
 
-static const unsigned char ParseHex_expected[65] = {
+static const uint8_t ParseHex_expected[65] = {
     0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, 0x19, 0x67,
     0xf1, 0xa6, 0x71, 0x30, 0xb7, 0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0,
     0x39, 0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde, 0xb6,
     0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, 0xf3, 0x55, 0x04,
     0xe5, 0x1e, 0xc1, 0x12, 0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b,
     0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d, 0x5f};
 BOOST_AUTO_TEST_CASE(util_ParseHex) {
-    std::vector<unsigned char> result;
-    std::vector<unsigned char> expected(
+    std::vector<uint8_t> result;
+    std::vector<uint8_t> expected(
         ParseHex_expected, ParseHex_expected + sizeof(ParseHex_expected));
     // Basic test vector
     result = ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0"
                       "ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d"
                       "578a4c702b6bf11d5f");
     BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(),
                                   expected.begin(), expected.end());
 
     // Spaces between bytes must be supported
     result = ParseHex("12 34 56 78");
     BOOST_CHECK(result.size() == 4 && result[0] == 0x12 && result[1] == 0x34 &&
                 result[2] == 0x56 && result[3] == 0x78);
 
     // Leading space must be supported (used in CDBEnv::Salvage)
     result = ParseHex(" 89 34 56 78");
     BOOST_CHECK(result.size() == 4 && result[0] == 0x89 && result[1] == 0x34 &&
                 result[2] == 0x56 && result[3] == 0x78);
 
     // Stop parsing at invalid value
     result = ParseHex("1234 invalid 1234");
     BOOST_CHECK(result.size() == 2 && result[0] == 0x12 && result[1] == 0x34);
 }
 
 BOOST_AUTO_TEST_CASE(util_HexStr) {
     BOOST_CHECK_EQUAL(HexStr(ParseHex_expected,
                              ParseHex_expected + sizeof(ParseHex_expected)),
                       "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0"
                       "ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d"
                       "578a4c702b6bf11d5f");
 
     BOOST_CHECK_EQUAL(HexStr(ParseHex_expected, ParseHex_expected + 5, true),
                       "04 67 8a fd b0");
 
     BOOST_CHECK_EQUAL(HexStr(ParseHex_expected, ParseHex_expected, true), "");
 
-    std::vector<unsigned char> ParseHex_vec(ParseHex_expected,
-                                            ParseHex_expected + 5);
+    std::vector<uint8_t> ParseHex_vec(ParseHex_expected, ParseHex_expected + 5);
 
     BOOST_CHECK_EQUAL(HexStr(ParseHex_vec, true), "04 67 8a fd b0");
 }
 
 BOOST_AUTO_TEST_CASE(util_DateTimeStrFormat) {
     BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 0),
                       "1970-01-01 00:00:00");
     BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 0x7FFFFFFF),
                       "2038-01-19 03:14:07");
     BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 1317425777),
                       "2011-09-30 23:36:17");
     BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M", 1317425777),
                       "2011-09-30 23:36");
     BOOST_CHECK_EQUAL(
         DateTimeStrFormat("%a, %d %b %Y %H:%M:%S +0000", 1317425777),
         "Fri, 30 Sep 2011 23:36:17 +0000");
 }
 
 BOOST_AUTO_TEST_CASE(util_ParseParameters) {
     const char *argv_test[] = {"-ignored",      "-a", "-b",  "-ccc=argument",
                                "-ccc=multiple", "f",  "-d=e"};
 
     ParseParameters(0, (char **)argv_test);
     BOOST_CHECK(mapArgs.empty() && mapMultiArgs.empty());
 
     ParseParameters(1, (char **)argv_test);
     BOOST_CHECK(mapArgs.empty() && mapMultiArgs.empty());
 
     ParseParameters(5, (char **)argv_test);
     // expectation: -ignored is ignored (program name argument),
     // -a, -b and -ccc end up in map, -d ignored because it is after
     // a non-option argument (non-GNU option parsing)
     BOOST_CHECK(mapArgs.size() == 3 && mapMultiArgs.size() == 3);
     BOOST_CHECK(IsArgSet("-a") && IsArgSet("-b") && IsArgSet("-ccc") &&
                 !IsArgSet("f") && !IsArgSet("-d"));
     BOOST_CHECK(mapMultiArgs.count("-a") && mapMultiArgs.count("-b") &&
                 mapMultiArgs.count("-ccc") && !mapMultiArgs.count("f") &&
                 !mapMultiArgs.count("-d"));
 
     BOOST_CHECK(mapArgs["-a"] == "" && mapArgs["-ccc"] == "multiple");
     BOOST_CHECK(mapMultiArgs.at("-ccc").size() == 2);
 }
 
 BOOST_AUTO_TEST_CASE(util_GetArg) {
     mapArgs.clear();
     mapArgs["strtest1"] = "string...";
     // strtest2 undefined on purpose
     mapArgs["inttest1"] = "12345";
     mapArgs["inttest2"] = "81985529216486895";
     // inttest3 undefined on purpose
     mapArgs["booltest1"] = "";
     // booltest2 undefined on purpose
     mapArgs["booltest3"] = "0";
     mapArgs["booltest4"] = "1";
 
     BOOST_CHECK_EQUAL(GetArg("strtest1", "default"), "string...");
     BOOST_CHECK_EQUAL(GetArg("strtest2", "default"), "default");
     BOOST_CHECK_EQUAL(GetArg("inttest1", -1), 12345);
     BOOST_CHECK_EQUAL(GetArg("inttest2", -1), 81985529216486895LL);
     BOOST_CHECK_EQUAL(GetArg("inttest3", -1), -1);
     BOOST_CHECK_EQUAL(GetBoolArg("booltest1", false), true);
     BOOST_CHECK_EQUAL(GetBoolArg("booltest2", false), false);
     BOOST_CHECK_EQUAL(GetBoolArg("booltest3", false), false);
     BOOST_CHECK_EQUAL(GetBoolArg("booltest4", false), true);
 }
 
 BOOST_AUTO_TEST_CASE(util_FormatMoney) {
     BOOST_CHECK_EQUAL(FormatMoney(0), "0.00");
     BOOST_CHECK_EQUAL(FormatMoney((COIN / 10000) * 123456789), "12345.6789");
     BOOST_CHECK_EQUAL(FormatMoney(-COIN), "-1.00");
 
     BOOST_CHECK_EQUAL(FormatMoney(COIN * 100000000), "100000000.00");
     BOOST_CHECK_EQUAL(FormatMoney(COIN * 10000000), "10000000.00");
     BOOST_CHECK_EQUAL(FormatMoney(COIN * 1000000), "1000000.00");
     BOOST_CHECK_EQUAL(FormatMoney(COIN * 100000), "100000.00");
     BOOST_CHECK_EQUAL(FormatMoney(COIN * 10000), "10000.00");
     BOOST_CHECK_EQUAL(FormatMoney(COIN * 1000), "1000.00");
     BOOST_CHECK_EQUAL(FormatMoney(COIN * 100), "100.00");
     BOOST_CHECK_EQUAL(FormatMoney(COIN * 10), "10.00");
     BOOST_CHECK_EQUAL(FormatMoney(COIN), "1.00");
     BOOST_CHECK_EQUAL(FormatMoney(COIN / 10), "0.10");
     BOOST_CHECK_EQUAL(FormatMoney(COIN / 100), "0.01");
     BOOST_CHECK_EQUAL(FormatMoney(COIN / 1000), "0.001");
     BOOST_CHECK_EQUAL(FormatMoney(COIN / 10000), "0.0001");
     BOOST_CHECK_EQUAL(FormatMoney(COIN / 100000), "0.00001");
     BOOST_CHECK_EQUAL(FormatMoney(COIN / 1000000), "0.000001");
     BOOST_CHECK_EQUAL(FormatMoney(COIN / 10000000), "0.0000001");
     BOOST_CHECK_EQUAL(FormatMoney(COIN / 100000000), "0.00000001");
 }
 
 BOOST_AUTO_TEST_CASE(util_ParseMoney) {
     CAmount ret = 0;
     BOOST_CHECK(ParseMoney("0.0", ret));
     BOOST_CHECK_EQUAL(ret, 0);
 
     BOOST_CHECK(ParseMoney("12345.6789", ret));
     BOOST_CHECK_EQUAL(ret, (COIN / 10000) * 123456789);
 
     BOOST_CHECK(ParseMoney("100000000.00", ret));
     BOOST_CHECK_EQUAL(ret, COIN * 100000000);
     BOOST_CHECK(ParseMoney("10000000.00", ret));
     BOOST_CHECK_EQUAL(ret, COIN * 10000000);
     BOOST_CHECK(ParseMoney("1000000.00", ret));
     BOOST_CHECK_EQUAL(ret, COIN * 1000000);
     BOOST_CHECK(ParseMoney("100000.00", ret));
     BOOST_CHECK_EQUAL(ret, COIN * 100000);
     BOOST_CHECK(ParseMoney("10000.00", ret));
     BOOST_CHECK_EQUAL(ret, COIN * 10000);
     BOOST_CHECK(ParseMoney("1000.00", ret));
     BOOST_CHECK_EQUAL(ret, COIN * 1000);
     BOOST_CHECK(ParseMoney("100.00", ret));
     BOOST_CHECK_EQUAL(ret, COIN * 100);
     BOOST_CHECK(ParseMoney("10.00", ret));
     BOOST_CHECK_EQUAL(ret, COIN * 10);
     BOOST_CHECK(ParseMoney("1.00", ret));
     BOOST_CHECK_EQUAL(ret, COIN);
     BOOST_CHECK(ParseMoney("1", ret));
     BOOST_CHECK_EQUAL(ret, COIN);
     BOOST_CHECK(ParseMoney("0.1", ret));
     BOOST_CHECK_EQUAL(ret, COIN / 10);
     BOOST_CHECK(ParseMoney("0.01", ret));
     BOOST_CHECK_EQUAL(ret, COIN / 100);
     BOOST_CHECK(ParseMoney("0.001", ret));
     BOOST_CHECK_EQUAL(ret, COIN / 1000);
     BOOST_CHECK(ParseMoney("0.0001", ret));
     BOOST_CHECK_EQUAL(ret, COIN / 10000);
     BOOST_CHECK(ParseMoney("0.00001", ret));
     BOOST_CHECK_EQUAL(ret, COIN / 100000);
     BOOST_CHECK(ParseMoney("0.000001", ret));
     BOOST_CHECK_EQUAL(ret, COIN / 1000000);
     BOOST_CHECK(ParseMoney("0.0000001", ret));
     BOOST_CHECK_EQUAL(ret, COIN / 10000000);
     BOOST_CHECK(ParseMoney("0.00000001", ret));
     BOOST_CHECK_EQUAL(ret, COIN / 100000000);
 
     // Attempted 63 bit overflow should fail
     BOOST_CHECK(!ParseMoney("92233720368.54775808", ret));
 
     // Parsing negative amounts must fail
     BOOST_CHECK(!ParseMoney("-1", ret));
 }
 
 BOOST_AUTO_TEST_CASE(util_IsHex) {
     BOOST_CHECK(IsHex("00"));
     BOOST_CHECK(IsHex("00112233445566778899aabbccddeeffAABBCCDDEEFF"));
     BOOST_CHECK(IsHex("ff"));
     BOOST_CHECK(IsHex("FF"));
 
     BOOST_CHECK(!IsHex(""));
     BOOST_CHECK(!IsHex("0"));
     BOOST_CHECK(!IsHex("a"));
     BOOST_CHECK(!IsHex("eleven"));
     BOOST_CHECK(!IsHex("00xx00"));
     BOOST_CHECK(!IsHex("0x0000"));
 }
 
 BOOST_AUTO_TEST_CASE(util_seed_insecure_rand) {
     seed_insecure_rand(true);
     for (int mod = 2; mod < 11; mod++) {
         int mask = 1;
         // Really rough binomal confidence approximation.
         int err =
             30 * 10000. / mod * sqrt((1. / mod * (1 - 1. / mod)) / 10000.);
         // mask is 2^ceil(log2(mod))-1
         while (mask < mod - 1)
             mask = (mask << 1) + 1;
 
         int count = 0;
         // How often does it get a zero from the uniform range [0,mod)?
         for (int i = 0; i < 10000; i++) {
             uint32_t rval;
             do {
                 rval = insecure_rand() & mask;
             } while (rval >= (uint32_t)mod);
             count += rval == 0;
         }
         BOOST_CHECK(count <= 10000 / mod + err);
         BOOST_CHECK(count >= 10000 / mod - err);
     }
 }
 
 BOOST_AUTO_TEST_CASE(util_TimingResistantEqual) {
     BOOST_CHECK(TimingResistantEqual(std::string(""), std::string("")));
     BOOST_CHECK(!TimingResistantEqual(std::string("abc"), std::string("")));
     BOOST_CHECK(!TimingResistantEqual(std::string(""), std::string("abc")));
     BOOST_CHECK(!TimingResistantEqual(std::string("a"), std::string("aa")));
     BOOST_CHECK(!TimingResistantEqual(std::string("aa"), std::string("a")));
     BOOST_CHECK(TimingResistantEqual(std::string("abc"), std::string("abc")));
     BOOST_CHECK(!TimingResistantEqual(std::string("abc"), std::string("aba")));
 }
 
 /* Test strprintf formatting directives.
  * Put a string before and after to ensure sanity of element sizes on stack. */
 #define B "check_prefix"
 #define E "check_postfix"
 BOOST_AUTO_TEST_CASE(strprintf_numbers) {
     int64_t s64t = -9223372036854775807LL;   /* signed 64 bit test value */
     uint64_t u64t = 18446744073709551615ULL; /* unsigned 64 bit test value */
     BOOST_CHECK(strprintf("%s %d %s", B, s64t, E) == B
                 " -9223372036854775807 " E);
     BOOST_CHECK(strprintf("%s %u %s", B, u64t, E) == B
                 " 18446744073709551615 " E);
     BOOST_CHECK(strprintf("%s %x %s", B, u64t, E) == B " ffffffffffffffff " E);
 
     size_t st = 12345678;    /* unsigned size_t test value */
     ssize_t sst = -12345678; /* signed size_t test value */
     BOOST_CHECK(strprintf("%s %d %s", B, sst, E) == B " -12345678 " E);
     BOOST_CHECK(strprintf("%s %u %s", B, st, E) == B " 12345678 " E);
     BOOST_CHECK(strprintf("%s %x %s", B, st, E) == B " bc614e " E);
 
     ptrdiff_t pt = 87654321;   /* positive ptrdiff_t test value */
     ptrdiff_t spt = -87654321; /* negative ptrdiff_t test value */
     BOOST_CHECK(strprintf("%s %d %s", B, spt, E) == B " -87654321 " E);
     BOOST_CHECK(strprintf("%s %u %s", B, pt, E) == B " 87654321 " E);
     BOOST_CHECK(strprintf("%s %x %s", B, pt, E) == B " 5397fb1 " E);
 }
 #undef B
 #undef E
 
 /* Check for mingw/wine issue #3494
  * Remove this test before time.ctime(0xffffffff) == 'Sun Feb  7 07:28:15 2106'
  */
 BOOST_AUTO_TEST_CASE(gettime) {
     BOOST_CHECK((GetTime() & ~0xFFFFFFFFLL) == 0);
 }
 
 BOOST_AUTO_TEST_CASE(test_ParseInt32) {
     int32_t n;
     // Valid values
     BOOST_CHECK(ParseInt32("1234", nullptr));
     BOOST_CHECK(ParseInt32("0", &n) && n == 0);
     BOOST_CHECK(ParseInt32("1234", &n) && n == 1234);
     BOOST_CHECK(ParseInt32("01234", &n) && n == 1234); // no octal
     BOOST_CHECK(ParseInt32("2147483647", &n) && n == 2147483647);
     BOOST_CHECK(ParseInt32("-2147483648", &n) && n == -2147483648);
     BOOST_CHECK(ParseInt32("-1234", &n) && n == -1234);
     // Invalid values
     BOOST_CHECK(!ParseInt32("", &n));
     BOOST_CHECK(!ParseInt32(" 1", &n)); // no padding inside
     BOOST_CHECK(!ParseInt32("1 ", &n));
     BOOST_CHECK(!ParseInt32("1a", &n));
     BOOST_CHECK(!ParseInt32("aap", &n));
     BOOST_CHECK(!ParseInt32("0x1", &n)); // no hex
     BOOST_CHECK(!ParseInt32("0x1", &n)); // no hex
     const char test_bytes[] = {'1', 0, '1'};
     std::string teststr(test_bytes, sizeof(test_bytes));
     BOOST_CHECK(!ParseInt32(teststr, &n)); // no embedded NULs
     // Overflow and underflow
     BOOST_CHECK(!ParseInt32("-2147483649", nullptr));
     BOOST_CHECK(!ParseInt32("2147483648", nullptr));
     BOOST_CHECK(!ParseInt32("-32482348723847471234", nullptr));
     BOOST_CHECK(!ParseInt32("32482348723847471234", nullptr));
 }
 
 BOOST_AUTO_TEST_CASE(test_ParseInt64) {
     int64_t n;
     // Valid values
     BOOST_CHECK(ParseInt64("1234", nullptr));
     BOOST_CHECK(ParseInt64("0", &n) && n == 0LL);
     BOOST_CHECK(ParseInt64("1234", &n) && n == 1234LL);
     BOOST_CHECK(ParseInt64("01234", &n) && n == 1234LL); // no octal
     BOOST_CHECK(ParseInt64("2147483647", &n) && n == 2147483647LL);
     BOOST_CHECK(ParseInt64("-2147483648", &n) && n == -2147483648LL);
     BOOST_CHECK(ParseInt64("9223372036854775807", &n) &&
                 n == (int64_t)9223372036854775807);
     BOOST_CHECK(ParseInt64("-9223372036854775808", &n) &&
                 n == (int64_t)-9223372036854775807 - 1);
     BOOST_CHECK(ParseInt64("-1234", &n) && n == -1234LL);
     // Invalid values
     BOOST_CHECK(!ParseInt64("", &n));
     BOOST_CHECK(!ParseInt64(" 1", &n)); // no padding inside
     BOOST_CHECK(!ParseInt64("1 ", &n));
     BOOST_CHECK(!ParseInt64("1a", &n));
     BOOST_CHECK(!ParseInt64("aap", &n));
     BOOST_CHECK(!ParseInt64("0x1", &n)); // no hex
     const char test_bytes[] = {'1', 0, '1'};
     std::string teststr(test_bytes, sizeof(test_bytes));
     BOOST_CHECK(!ParseInt64(teststr, &n)); // no embedded NULs
     // Overflow and underflow
     BOOST_CHECK(!ParseInt64("-9223372036854775809", nullptr));
     BOOST_CHECK(!ParseInt64("9223372036854775808", nullptr));
     BOOST_CHECK(!ParseInt64("-32482348723847471234", nullptr));
     BOOST_CHECK(!ParseInt64("32482348723847471234", nullptr));
 }
 
 BOOST_AUTO_TEST_CASE(test_ParseUInt32) {
     uint32_t n;
     // Valid values
     BOOST_CHECK(ParseUInt32("1234", nullptr));
     BOOST_CHECK(ParseUInt32("0", &n) && n == 0);
     BOOST_CHECK(ParseUInt32("1234", &n) && n == 1234);
     BOOST_CHECK(ParseUInt32("01234", &n) && n == 1234); // no octal
     BOOST_CHECK(ParseUInt32("2147483647", &n) && n == 2147483647);
     BOOST_CHECK(ParseUInt32("2147483648", &n) && n == (uint32_t)2147483648);
     BOOST_CHECK(ParseUInt32("4294967295", &n) && n == (uint32_t)4294967295);
     // Invalid values
     BOOST_CHECK(!ParseUInt32("", &n));
     BOOST_CHECK(!ParseUInt32(" 1", &n)); // no padding inside
     BOOST_CHECK(!ParseUInt32(" -1", &n));
     BOOST_CHECK(!ParseUInt32("1 ", &n));
     BOOST_CHECK(!ParseUInt32("1a", &n));
     BOOST_CHECK(!ParseUInt32("aap", &n));
     BOOST_CHECK(!ParseUInt32("0x1", &n)); // no hex
     BOOST_CHECK(!ParseUInt32("0x1", &n)); // no hex
     const char test_bytes[] = {'1', 0, '1'};
     std::string teststr(test_bytes, sizeof(test_bytes));
     BOOST_CHECK(!ParseUInt32(teststr, &n)); // no embedded NULs
     // Overflow and underflow
     BOOST_CHECK(!ParseUInt32("-2147483648", &n));
     BOOST_CHECK(!ParseUInt32("4294967296", &n));
     BOOST_CHECK(!ParseUInt32("-1234", &n));
     BOOST_CHECK(!ParseUInt32("-32482348723847471234", nullptr));
     BOOST_CHECK(!ParseUInt32("32482348723847471234", nullptr));
 }
 
 BOOST_AUTO_TEST_CASE(test_ParseUInt64) {
     uint64_t n;
     // Valid values
     BOOST_CHECK(ParseUInt64("1234", nullptr));
     BOOST_CHECK(ParseUInt64("0", &n) && n == 0LL);
     BOOST_CHECK(ParseUInt64("1234", &n) && n == 1234LL);
     BOOST_CHECK(ParseUInt64("01234", &n) && n == 1234LL); // no octal
     BOOST_CHECK(ParseUInt64("2147483647", &n) && n == 2147483647LL);
     BOOST_CHECK(ParseUInt64("9223372036854775807", &n) &&
                 n == 9223372036854775807ULL);
     BOOST_CHECK(ParseUInt64("9223372036854775808", &n) &&
                 n == 9223372036854775808ULL);
     BOOST_CHECK(ParseUInt64("18446744073709551615", &n) &&
                 n == 18446744073709551615ULL);
     // Invalid values
     BOOST_CHECK(!ParseUInt64("", &n));
     BOOST_CHECK(!ParseUInt64(" 1", &n)); // no padding inside
     BOOST_CHECK(!ParseUInt64(" -1", &n));
     BOOST_CHECK(!ParseUInt64("1 ", &n));
     BOOST_CHECK(!ParseUInt64("1a", &n));
     BOOST_CHECK(!ParseUInt64("aap", &n));
     BOOST_CHECK(!ParseUInt64("0x1", &n)); // no hex
     const char test_bytes[] = {'1', 0, '1'};
     std::string teststr(test_bytes, sizeof(test_bytes));
     BOOST_CHECK(!ParseUInt64(teststr, &n)); // no embedded NULs
     // Overflow and underflow
     BOOST_CHECK(!ParseUInt64("-9223372036854775809", nullptr));
     BOOST_CHECK(!ParseUInt64("18446744073709551616", nullptr));
     BOOST_CHECK(!ParseUInt64("-32482348723847471234", nullptr));
     BOOST_CHECK(!ParseUInt64("-2147483648", &n));
     BOOST_CHECK(!ParseUInt64("-9223372036854775808", &n));
     BOOST_CHECK(!ParseUInt64("-1234", &n));
 }
 
 BOOST_AUTO_TEST_CASE(test_ParseDouble) {
     double n;
     // Valid values
     BOOST_CHECK(ParseDouble("1234", nullptr));
     BOOST_CHECK(ParseDouble("0", &n) && n == 0.0);
     BOOST_CHECK(ParseDouble("1234", &n) && n == 1234.0);
     BOOST_CHECK(ParseDouble("01234", &n) && n == 1234.0); // no octal
     BOOST_CHECK(ParseDouble("2147483647", &n) && n == 2147483647.0);
     BOOST_CHECK(ParseDouble("-2147483648", &n) && n == -2147483648.0);
     BOOST_CHECK(ParseDouble("-1234", &n) && n == -1234.0);
     BOOST_CHECK(ParseDouble("1e6", &n) && n == 1e6);
     BOOST_CHECK(ParseDouble("-1e6", &n) && n == -1e6);
     // Invalid values
     BOOST_CHECK(!ParseDouble("", &n));
     BOOST_CHECK(!ParseDouble(" 1", &n)); // no padding inside
     BOOST_CHECK(!ParseDouble("1 ", &n));
     BOOST_CHECK(!ParseDouble("1a", &n));
     BOOST_CHECK(!ParseDouble("aap", &n));
     BOOST_CHECK(!ParseDouble("0x1", &n)); // no hex
     const char test_bytes[] = {'1', 0, '1'};
     std::string teststr(test_bytes, sizeof(test_bytes));
     BOOST_CHECK(!ParseDouble(teststr, &n)); // no embedded NULs
     // Overflow and underflow
     BOOST_CHECK(!ParseDouble("-1e10000", nullptr));
     BOOST_CHECK(!ParseDouble("1e10000", nullptr));
 }
 
 BOOST_AUTO_TEST_CASE(test_FormatParagraph) {
     BOOST_CHECK_EQUAL(FormatParagraph("", 79, 0), "");
     BOOST_CHECK_EQUAL(FormatParagraph("test", 79, 0), "test");
     BOOST_CHECK_EQUAL(FormatParagraph(" test", 79, 0), " test");
     BOOST_CHECK_EQUAL(FormatParagraph("test test", 79, 0), "test test");
     BOOST_CHECK_EQUAL(FormatParagraph("test test", 4, 0), "test\ntest");
     BOOST_CHECK_EQUAL(FormatParagraph("testerde test", 4, 0), "testerde\ntest");
     BOOST_CHECK_EQUAL(FormatParagraph("test test", 4, 4), "test\n    test");
 
     // Make sure we don't indent a fully-new line following a too-long line
     // ending
     BOOST_CHECK_EQUAL(FormatParagraph("test test\nabc", 4, 4),
                       "test\n    test\nabc");
 
     BOOST_CHECK_EQUAL(
         FormatParagraph("This_is_a_very_long_test_string_without_any_spaces_so_"
                         "it_should_just_get_returned_as_is_despite_the_length "
                         "until it gets here",
                         79),
         "This_is_a_very_long_test_string_without_any_spaces_so_it_should_just_"
         "get_returned_as_is_despite_the_length\nuntil it gets here");
 
     // Test wrap length is exact
     BOOST_CHECK_EQUAL(
         FormatParagraph("a b c d e f g h i j k l m n o p q r s t u v w x y z 1 "
                         "2 3 4 5 6 7 8 9 a b c de f g h i j k l m n o p",
                         79),
         "a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 "
         "a b c de\nf g h i j k l m n o p");
     BOOST_CHECK_EQUAL(
         FormatParagraph("x\na b c d e f g h i j k l m n o p q r s t u v w x y "
                         "z 1 2 3 4 5 6 7 8 9 a b c de f g h i j k l m n o p",
                         79),
         "x\na b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 "
         "8 9 a b c de\nf g h i j k l m n o p");
     // Indent should be included in length of lines
     BOOST_CHECK_EQUAL(
         FormatParagraph("x\na b c d e f g h i j k l m n o p q r s t u v w x y "
                         "z 1 2 3 4 5 6 7 8 9 a b c de f g h i j k l m n o p q "
                         "r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e fg h "
                         "i j k",
                         79, 4),
         "x\na b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 "
         "8 9 a b c de\n    f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 "
         "5 6 7 8 9 a b c d e fg\n    h i j k");
 
     BOOST_CHECK_EQUAL(
         FormatParagraph("This is a very long test string. This is a second "
                         "sentence in the very long test string.",
                         79),
         "This is a very long test string. This is a second sentence in the "
         "very long\ntest string.");
     BOOST_CHECK_EQUAL(
         FormatParagraph("This is a very long test string.\nThis is a second "
                         "sentence in the very long test string. This is a "
                         "third sentence in the very long test string.",
                         79),
         "This is a very long test string.\nThis is a second sentence in the "
         "very long test string. This is a third\nsentence in the very long "
         "test string.");
     BOOST_CHECK_EQUAL(
         FormatParagraph("This is a very long test string.\n\nThis is a second "
                         "sentence in the very long test string. This is a "
                         "third sentence in the very long test string.",
                         79),
         "This is a very long test string.\n\nThis is a second sentence in the "
         "very long test string. This is a third\nsentence in the very long "
         "test string.");
     BOOST_CHECK_EQUAL(
         FormatParagraph(
             "Testing that normal newlines do not get indented.\nLike here.",
             79),
         "Testing that normal newlines do not get indented.\nLike here.");
 }
 
 BOOST_AUTO_TEST_CASE(test_FormatSubVersion) {
     std::vector<std::string> comments;
     comments.push_back(std::string("comment1"));
     std::vector<std::string> comments2;
     comments2.push_back(std::string("comment1"));
     comments2.push_back(SanitizeString(
         std::string("Comment2; .,_?@-; !\"#$%&'()*+/<=>[]\\^`{|}~"),
         SAFE_CHARS_UA_COMMENT)); // Semicolon is discouraged but not forbidden
                                  // by BIP-0014
     BOOST_CHECK_EQUAL(
         FormatSubVersion("Test", 99900, std::vector<std::string>()),
         std::string("/Test:0.9.99/"));
     BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments),
                       std::string("/Test:0.9.99(comment1)/"));
     BOOST_CHECK_EQUAL(
         FormatSubVersion("Test", 99900, comments2),
         std::string("/Test:0.9.99(comment1; Comment2; .,_?@-; )/"));
 }
 
 BOOST_AUTO_TEST_CASE(test_ParseFixedPoint) {
     int64_t amount = 0;
     BOOST_CHECK(ParseFixedPoint("0", 8, &amount));
     BOOST_CHECK_EQUAL(amount, 0LL);
     BOOST_CHECK(ParseFixedPoint("1", 8, &amount));
     BOOST_CHECK_EQUAL(amount, 100000000LL);
     BOOST_CHECK(ParseFixedPoint("0.0", 8, &amount));
     BOOST_CHECK_EQUAL(amount, 0LL);
     BOOST_CHECK(ParseFixedPoint("-0.1", 8, &amount));
     BOOST_CHECK_EQUAL(amount, -10000000LL);
     BOOST_CHECK(ParseFixedPoint("1.1", 8, &amount));
     BOOST_CHECK_EQUAL(amount, 110000000LL);
     BOOST_CHECK(ParseFixedPoint("1.10000000000000000", 8, &amount));
     BOOST_CHECK_EQUAL(amount, 110000000LL);
     BOOST_CHECK(ParseFixedPoint("1.1e1", 8, &amount));
     BOOST_CHECK_EQUAL(amount, 1100000000LL);
     BOOST_CHECK(ParseFixedPoint("1.1e-1", 8, &amount));
     BOOST_CHECK_EQUAL(amount, 11000000LL);
     BOOST_CHECK(ParseFixedPoint("1000", 8, &amount));
     BOOST_CHECK_EQUAL(amount, 100000000000LL);
     BOOST_CHECK(ParseFixedPoint("-1000", 8, &amount));
     BOOST_CHECK_EQUAL(amount, -100000000000LL);
     BOOST_CHECK(ParseFixedPoint("0.00000001", 8, &amount));
     BOOST_CHECK_EQUAL(amount, 1LL);
     BOOST_CHECK(ParseFixedPoint("0.0000000100000000", 8, &amount));
     BOOST_CHECK_EQUAL(amount, 1LL);
     BOOST_CHECK(ParseFixedPoint("-0.00000001", 8, &amount));
     BOOST_CHECK_EQUAL(amount, -1LL);
     BOOST_CHECK(ParseFixedPoint("1000000000.00000001", 8, &amount));
     BOOST_CHECK_EQUAL(amount, 100000000000000001LL);
     BOOST_CHECK(ParseFixedPoint("9999999999.99999999", 8, &amount));
     BOOST_CHECK_EQUAL(amount, 999999999999999999LL);
     BOOST_CHECK(ParseFixedPoint("-9999999999.99999999", 8, &amount));
     BOOST_CHECK_EQUAL(amount, -999999999999999999LL);
 
     BOOST_CHECK(!ParseFixedPoint("", 8, &amount));
     BOOST_CHECK(!ParseFixedPoint("-", 8, &amount));
     BOOST_CHECK(!ParseFixedPoint("a-1000", 8, &amount));
     BOOST_CHECK(!ParseFixedPoint("-a1000", 8, &amount));
     BOOST_CHECK(!ParseFixedPoint("-1000a", 8, &amount));
     BOOST_CHECK(!ParseFixedPoint("-01000", 8, &amount));
     BOOST_CHECK(!ParseFixedPoint("00.1", 8, &amount));
     BOOST_CHECK(!ParseFixedPoint(".1", 8, &amount));
     BOOST_CHECK(!ParseFixedPoint("--0.1", 8, &amount));
     BOOST_CHECK(!ParseFixedPoint("0.000000001", 8, &amount));
     BOOST_CHECK(!ParseFixedPoint("-0.000000001", 8, &amount));
     BOOST_CHECK(!ParseFixedPoint("0.00000001000000001", 8, &amount));
     BOOST_CHECK(!ParseFixedPoint("-10000000000.00000000", 8, &amount));
     BOOST_CHECK(!ParseFixedPoint("10000000000.00000000", 8, &amount));
     BOOST_CHECK(!ParseFixedPoint("-10000000000.00000001", 8, &amount));
     BOOST_CHECK(!ParseFixedPoint("10000000000.00000001", 8, &amount));
     BOOST_CHECK(!ParseFixedPoint("-10000000000.00000009", 8, &amount));
     BOOST_CHECK(!ParseFixedPoint("10000000000.00000009", 8, &amount));
     BOOST_CHECK(!ParseFixedPoint("-99999999999.99999999", 8, &amount));
     BOOST_CHECK(!ParseFixedPoint("99999909999.09999999", 8, &amount));
     BOOST_CHECK(!ParseFixedPoint("92233720368.54775807", 8, &amount));
     BOOST_CHECK(!ParseFixedPoint("92233720368.54775808", 8, &amount));
     BOOST_CHECK(!ParseFixedPoint("-92233720368.54775808", 8, &amount));
     BOOST_CHECK(!ParseFixedPoint("-92233720368.54775809", 8, &amount));
     BOOST_CHECK(!ParseFixedPoint("1.1e", 8, &amount));
     BOOST_CHECK(!ParseFixedPoint("1.1e-", 8, &amount));
     BOOST_CHECK(!ParseFixedPoint("1.", 8, &amount));
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/tinyformat.h b/src/tinyformat.h
index 919538448..451993542 100644
--- a/src/tinyformat.h
+++ b/src/tinyformat.h
@@ -1,1076 +1,1076 @@
 // tinyformat.h
 // Copyright (C) 2011, Chris Foster [chris42f (at) gmail (d0t) com]
 //
 // Boost Software License - Version 1.0
 //
 // Permission is hereby granted, free of charge, to any person or organization
 // obtaining a copy of the software and accompanying documentation covered by
 // this license (the "Software") to use, reproduce, display, distribute,
 // execute, and transmit the Software, and to prepare derivative works of the
 // Software, and to permit third-parties to whom the Software is furnished to
 // do so, all subject to the following:
 //
 // The copyright notices in the Software and this entire statement, including
 // the above license grant, this restriction and the following disclaimer,
 // must be included in all copies of the Software, in whole or in part, and
 // all derivative works of the Software, unless such copies or derivative
 // works are solely in the form of machine-executable object code generated by
 // a source language processor.
 //
 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
 // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
 // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
 //------------------------------------------------------------------------------
 // Tinyformat: A minimal type safe printf replacement
 //
 // tinyformat.h is a type safe printf replacement library in a single C++
 // header file.  Design goals include:
 //
 // * Type safety and extensibility for user defined types.
 // * C99 printf() compatibility, to the extent possible using std::ostream
 // * Simplicity and minimalism.  A single header file to include and distribute
 //   with your projects.
 // * Augment rather than replace the standard stream formatting mechanism
 // * C++98 support, with optional C++11 niceties
 //
 //
 // Main interface example usage
 // ----------------------------
 //
 // To print a date to std::cout:
 //
 //   std::string weekday = "Wednesday";
 //   const char* month = "July";
 //   size_t day = 27;
 //   long hour = 14;
 //   int min = 44;
 //
 //   tfm::printf("%s, %s %d, %.2d:%.2d\n", weekday, month, day, hour, min);
 //
 // The strange types here emphasize the type safety of the interface; it is
 // possible to print a std::string using the "%s" conversion, and a
 // size_t using the "%d" conversion.  A similar result could be achieved
 // using either of the tfm::format() functions.  One prints on a user provided
 // stream:
 //
 //   tfm::format(std::cerr, "%s, %s %d, %.2d:%.2d\n",
 //               weekday, month, day, hour, min);
 //
 // The other returns a std::string:
 //
 //   std::string date = tfm::format("%s, %s %d, %.2d:%.2d\n",
 //                                  weekday, month, day, hour, min);
 //   std::cout << date;
 //
 // These are the three primary interface functions.  There is also a
 // convenience function printfln() which appends a newline to the usual result
 // of printf() for super simple logging.
 //
 //
 // User defined format functions
 // -----------------------------
 //
 // Simulating variadic templates in C++98 is pretty painful since it requires
 // writing out the same function for each desired number of arguments.  To make
 // this bearable tinyformat comes with a set of macros which are used
 // internally to generate the API, but which may also be used in user code.
 //
 // The three macros TINYFORMAT_ARGTYPES(n), TINYFORMAT_VARARGS(n) and
 // TINYFORMAT_PASSARGS(n) will generate a list of n argument types,
 // type/name pairs and argument names respectively when called with an integer
 // n between 1 and 16.  We can use these to define a macro which generates the
 // desired user defined function with n arguments.  To generate all 16 user
 // defined function bodies, use the macro TINYFORMAT_FOREACH_ARGNUM.  For an
 // example, see the implementation of printf() at the end of the source file.
 //
 // Sometimes it's useful to be able to pass a list of format arguments through
 // to a non-template function.  The FormatList class is provided as a way to do
 // this by storing the argument list in a type-opaque way.  Continuing the
 // example from above, we construct a FormatList using makeFormatList():
 //
 //   FormatListRef formatList = tfm::makeFormatList(weekday, month, day, hour,
 //   min);
 //
 // The format list can now be passed into any non-template function and used
 // via a call to the vformat() function:
 //
 //   tfm::vformat(std::cout, "%s, %s %d, %.2d:%.2d\n", formatList);
 //
 //
 // Additional API information
 // --------------------------
 //
 // Error handling: Define TINYFORMAT_ERROR to customize the error handling for
 // format strings which are unsupported or have the wrong number of format
 // specifiers (calls assert() by default).
 //
 // User defined types: Uses operator<< for user defined types by default.
 // Overload formatValue() for more control.
 
 #ifndef TINYFORMAT_H_INCLUDED
 #define TINYFORMAT_H_INCLUDED
 
 namespace tinyformat {}
 //------------------------------------------------------------------------------
 // Config section.  Customize to your liking!
 
 // Namespace alias to encourage brevity
 namespace tfm = tinyformat;
 
 // Error handling; calls assert() by default.
 #define TINYFORMAT_ERROR(reasonString) throw std::runtime_error(reasonString)
 
 // Define for C++11 variadic templates which make the code shorter & more
 // general.  If you don't define this, C++11 support is autodetected below.
 #define TINYFORMAT_USE_VARIADIC_TEMPLATES
 
 //------------------------------------------------------------------------------
 // Implementation details.
 #include <algorithm>
 #include <cassert>
 #include <iostream>
 #include <sstream>
 #include <stdexcept>
 
 #ifndef TINYFORMAT_ERROR
 #define TINYFORMAT_ERROR(reason) assert(0 && reason)
 #endif
 
 #if !defined(TINYFORMAT_USE_VARIADIC_TEMPLATES) &&                             \
     !defined(TINYFORMAT_NO_VARIADIC_TEMPLATES)
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
 #define TINYFORMAT_USE_VARIADIC_TEMPLATES
 #endif
 #endif
 
 #if defined(__GLIBCXX__) && __GLIBCXX__ < 20080201
 //  std::showpos is broken on old libstdc++ as provided with OSX.  See
 //  http://gcc.gnu.org/ml/libstdc++/2007-11/msg00075.html
 #define TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND
 #endif
 
 #ifdef __APPLE__
 // Workaround OSX linker warning: xcode uses different default symbol
 // visibilities for static libs vs executables (see issue #25)
 #define TINYFORMAT_HIDDEN __attribute__((visibility("hidden")))
 #else
 #define TINYFORMAT_HIDDEN
 #endif
 
 namespace tinyformat {
 
 //------------------------------------------------------------------------------
 namespace detail {
 
     // Test whether type T1 is convertible to type T2
     template <typename T1, typename T2> struct is_convertible {
     private:
         // two types of different size
         struct fail {
             char dummy[2];
         };
         struct succeed {
             char dummy;
         };
         // Try to convert a T1 to a T2 by plugging into tryConvert
         static fail tryConvert(...);
         static succeed tryConvert(const T2 &);
         static const T1 &makeT1();
 
     public:
 #ifdef _MSC_VER
 // Disable spurious loss of precision warnings in tryConvert(makeT1())
 #pragma warning(push)
 #pragma warning(disable : 4244)
 #pragma warning(disable : 4267)
 #endif
         // Standard trick: the (...) version of tryConvert will be chosen from
         // the overload set only if the version taking a T2 doesn't match. Then
         // we compare the sizes of the return types to check which function
         // matched.  Very neat, in a disgusting kind of way :)
         static const bool value =
             sizeof(tryConvert(makeT1())) == sizeof(succeed);
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
     };
 
     // Detect when a type is not a wchar_t string
     template <typename T> struct is_wchar {
         typedef int tinyformat_wchar_is_not_supported;
     };
     template <> struct is_wchar<wchar_t *> {};
     template <> struct is_wchar<const wchar_t *> {};
     template <int n> struct is_wchar<const wchar_t[n]> {};
     template <int n> struct is_wchar<wchar_t[n]> {};
 
     // Format the value by casting to type fmtT. This default implementation
     // should never be called.
     template <typename T, typename fmtT,
               bool convertible = is_convertible<T, fmtT>::value>
     struct formatValueAsType {
         static void invoke(std::ostream & /*out*/, const T & /*value*/) {
             assert(0);
         }
     };
 
     // Specialized version for types that can actually be converted to fmtT, as
     // indicated by the "convertible" template parameter.
     template <typename T, typename fmtT>
     struct formatValueAsType<T, fmtT, true> {
         static void invoke(std::ostream &out, const T &value) {
             out << static_cast<fmtT>(value);
         }
     };
 
 #ifdef TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND
     template <typename T, bool convertible = is_convertible<T, int>::value>
     struct formatZeroIntegerWorkaround {
         static bool invoke(std::ostream & /**/, const T & /**/) {
             return false;
         }
     };
     template <typename T> struct formatZeroIntegerWorkaround<T, true> {
         static bool invoke(std::ostream &out, const T &value) {
             if (static_cast<int>(value) == 0 &&
                 out.flags() & std::ios::showpos) {
                 out << "+0";
                 return true;
             }
             return false;
         }
     };
 #endif // TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND
 
     // Convert an arbitrary type to integer.  The version with convertible=false
     // throws an error.
     template <typename T, bool convertible = is_convertible<T, int>::value>
     struct convertToInt {
         static int invoke(const T & /*value*/) {
             TINYFORMAT_ERROR("tinyformat: Cannot convert from argument type to "
                              "integer for use as variable width or precision");
             return 0;
         }
     };
     // Specialization for convertToInt when conversion is possible
     template <typename T> struct convertToInt<T, true> {
         static int invoke(const T &value) { return static_cast<int>(value); }
     };
 
     // Format at most ntrunc characters to the given stream.
     template <typename T>
     inline void formatTruncated(std::ostream &out, const T &value, int ntrunc) {
         std::ostringstream tmp;
         tmp << value;
         std::string result = tmp.str();
         out.write(result.c_str(),
                   (std::min)(ntrunc, static_cast<int>(result.size())));
     }
 #define TINYFORMAT_DEFINE_FORMAT_TRUNCATED_CSTR(type)                          \
     inline void formatTruncated(std::ostream &out, type *value, int ntrunc) {  \
         std::streamsize len = 0;                                               \
         while (len < ntrunc && value[len] != 0)                                \
             ++len;                                                             \
         out.write(value, len);                                                 \
     }
-    // Overload for const char* and char*.  Could overload for signed & unsigned
+    // Overload for const char* and char*. Could overload for signed & unsigned
     // char too, but these are technically unneeded for printf compatibility.
     TINYFORMAT_DEFINE_FORMAT_TRUNCATED_CSTR(const char)
     TINYFORMAT_DEFINE_FORMAT_TRUNCATED_CSTR(char)
 #undef TINYFORMAT_DEFINE_FORMAT_TRUNCATED_CSTR
 
 } // namespace detail
 
 //------------------------------------------------------------------------------
 // Variable formatting functions.  May be overridden for user-defined types if
 // desired.
 
 /// Format a value into a stream, delegating to operator<< by default.
 ///
 /// Users may override this for their own types.  When this function is called,
 /// the stream flags will have been modified according to the format string.
 /// The format specification is provided in the range [fmtBegin, fmtEnd).  For
 /// truncating conversions, ntrunc is set to the desired maximum number of
 /// characters, for example "%.7s" calls formatValue with ntrunc = 7.
 ///
 /// By default, formatValue() uses the usual stream insertion operator
 /// operator<< to format the type T, with special cases for the %c and %p
 /// conversions.
 template <typename T>
 inline void formatValue(std::ostream &out, const char * /*fmtBegin*/,
                         const char *fmtEnd, int ntrunc, const T &value) {
 #ifndef TINYFORMAT_ALLOW_WCHAR_STRINGS
     // Since we don't support printing of wchar_t using "%ls", make it fail at
     // compile time in preference to printing as a void* at runtime.
     typedef typename detail::is_wchar<T>::tinyformat_wchar_is_not_supported
         DummyType;
     (void)DummyType(); // avoid unused type warning with gcc-4.8
 #endif
     // The mess here is to support the %c and %p conversions: if these
     // conversions are active we try to convert the type to a char or const
     // void* respectively and format that instead of the value itself. For the
     // %p conversion it's important to avoid dereferencing the pointer, which
     // could otherwise lead to a crash when printing a dangling (const char*).
     const bool canConvertToChar = detail::is_convertible<T, char>::value;
     const bool canConvertToVoidPtr =
         detail::is_convertible<T, const void *>::value;
     if (canConvertToChar && *(fmtEnd - 1) == 'c')
         detail::formatValueAsType<T, char>::invoke(out, value);
     else if (canConvertToVoidPtr && *(fmtEnd - 1) == 'p')
         detail::formatValueAsType<T, const void *>::invoke(out, value);
 #ifdef TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND
     else if (detail::formatZeroIntegerWorkaround<T>::invoke(out, value)) /**/
         ;
 #endif
     else if (ntrunc >= 0) {
         // Take care not to overread C strings in truncating conversions like
         // "%.4s" where at most 4 characters may be read.
         detail::formatTruncated(out, value, ntrunc);
     } else
         out << value;
 }
 
 // Overloaded version for char types to support printing as an integer
 #define TINYFORMAT_DEFINE_FORMATVALUE_CHAR(charType)                           \
     inline void formatValue(std::ostream &out, const char * /*fmtBegin*/,      \
                             const char *fmtEnd, int /**/, charType value) {    \
         switch (*(fmtEnd - 1)) {                                               \
             case 'u':                                                          \
             case 'd':                                                          \
             case 'i':                                                          \
             case 'o':                                                          \
             case 'X':                                                          \
             case 'x':                                                          \
                 out << static_cast<int>(value);                                \
                 break;                                                         \
             default:                                                           \
                 out << value;                                                  \
                 break;                                                         \
         }                                                                      \
     }
-// per 3.9.1: char, signed char and unsigned char are all distinct types
+// per 3.9.1: char, signed char and uint8_t are all distinct types
 TINYFORMAT_DEFINE_FORMATVALUE_CHAR(char)
 TINYFORMAT_DEFINE_FORMATVALUE_CHAR(signed char)
-TINYFORMAT_DEFINE_FORMATVALUE_CHAR(unsigned char)
+TINYFORMAT_DEFINE_FORMATVALUE_CHAR(uint8_t)
 #undef TINYFORMAT_DEFINE_FORMATVALUE_CHAR
 
 //------------------------------------------------------------------------------
 // Tools for emulating variadic templates in C++98.  The basic idea here is
 // stolen from the boost preprocessor metaprogramming library and cut down to
 // be just general enough for what we need.
 
 #define TINYFORMAT_ARGTYPES(n) TINYFORMAT_ARGTYPES_##n
 #define TINYFORMAT_VARARGS(n) TINYFORMAT_VARARGS_##n
 #define TINYFORMAT_PASSARGS(n) TINYFORMAT_PASSARGS_##n
 #define TINYFORMAT_PASSARGS_TAIL(n) TINYFORMAT_PASSARGS_TAIL_##n
 
 // To keep it as transparent as possible, the macros below have been generated
 // using python via the excellent cog.py code generation script.  This avoids
 // the need for a bunch of complex (but more general) preprocessor tricks as
 // used in boost.preprocessor.
 //
 // To rerun the code generation in place, use `cog.py -r tinyformat.h`
 // (see http://nedbatchelder.com/code/cog).  Alternatively you can just create
 // extra versions by hand.
 
 /*[[[cog
 maxParams = 16
 
 def makeCommaSepLists(lineTemplate, elemTemplate, startInd=1):
     for j in range(startInd,maxParams+1):
         list = ', '.join([elemTemplate % {'i':i} for i in range(startInd,j+1)])
         cog.outl(lineTemplate % {'j':j, 'list':list})
 
 makeCommaSepLists('#define TINYFORMAT_ARGTYPES_%(j)d %(list)s',
                   'class T%(i)d')
 
 cog.outl()
 makeCommaSepLists('#define TINYFORMAT_VARARGS_%(j)d %(list)s',
                   'const T%(i)d& v%(i)d')
 
 cog.outl()
 makeCommaSepLists('#define TINYFORMAT_PASSARGS_%(j)d %(list)s', 'v%(i)d')
 
 cog.outl()
 cog.outl('#define TINYFORMAT_PASSARGS_TAIL_1')
 makeCommaSepLists('#define TINYFORMAT_PASSARGS_TAIL_%(j)d , %(list)s',
                   'v%(i)d', startInd = 2)
 
 cog.outl()
 cog.outl('#define TINYFORMAT_FOREACH_ARGNUM(m) \\\n    ' +
          ' '.join(['m(%d)' % (j,) for j in range(1,maxParams+1)]))
 ]]]*/
 #define TINYFORMAT_ARGTYPES_1 class T1
 #define TINYFORMAT_ARGTYPES_2 class T1, class T2
 #define TINYFORMAT_ARGTYPES_3 class T1, class T2, class T3
 #define TINYFORMAT_ARGTYPES_4 class T1, class T2, class T3, class T4
 #define TINYFORMAT_ARGTYPES_5 class T1, class T2, class T3, class T4, class T5
 #define TINYFORMAT_ARGTYPES_6                                                  \
     class T1, class T2, class T3, class T4, class T5, class T6
 #define TINYFORMAT_ARGTYPES_7                                                  \
     class T1, class T2, class T3, class T4, class T5, class T6, class T7
 #define TINYFORMAT_ARGTYPES_8                                                  \
     class T1, class T2, class T3, class T4, class T5, class T6, class T7,      \
         class T8
 #define TINYFORMAT_ARGTYPES_9                                                  \
     class T1, class T2, class T3, class T4, class T5, class T6, class T7,      \
         class T8, class T9
 #define TINYFORMAT_ARGTYPES_10                                                 \
     class T1, class T2, class T3, class T4, class T5, class T6, class T7,      \
         class T8, class T9, class T10
 #define TINYFORMAT_ARGTYPES_11                                                 \
     class T1, class T2, class T3, class T4, class T5, class T6, class T7,      \
         class T8, class T9, class T10, class T11
 #define TINYFORMAT_ARGTYPES_12                                                 \
     class T1, class T2, class T3, class T4, class T5, class T6, class T7,      \
         class T8, class T9, class T10, class T11, class T12
 #define TINYFORMAT_ARGTYPES_13                                                 \
     class T1, class T2, class T3, class T4, class T5, class T6, class T7,      \
         class T8, class T9, class T10, class T11, class T12, class T13
 #define TINYFORMAT_ARGTYPES_14                                                 \
     class T1, class T2, class T3, class T4, class T5, class T6, class T7,      \
         class T8, class T9, class T10, class T11, class T12, class T13,        \
         class T14
 #define TINYFORMAT_ARGTYPES_15                                                 \
     class T1, class T2, class T3, class T4, class T5, class T6, class T7,      \
         class T8, class T9, class T10, class T11, class T12, class T13,        \
         class T14, class T15
 #define TINYFORMAT_ARGTYPES_16                                                 \
     class T1, class T2, class T3, class T4, class T5, class T6, class T7,      \
         class T8, class T9, class T10, class T11, class T12, class T13,        \
         class T14, class T15, class T16
 
 #define TINYFORMAT_VARARGS_1 const T1 &v1
 #define TINYFORMAT_VARARGS_2 const T1 &v1, const T2 &v2
 #define TINYFORMAT_VARARGS_3 const T1 &v1, const T2 &v2, const T3 &v3
 #define TINYFORMAT_VARARGS_4                                                   \
     const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4
 #define TINYFORMAT_VARARGS_5                                                   \
     const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5
 #define TINYFORMAT_VARARGS_6                                                   \
     const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5,      \
         const T6 &v6
 #define TINYFORMAT_VARARGS_7                                                   \
     const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5,      \
         const T6 &v6, const T7 &v7
 #define TINYFORMAT_VARARGS_8                                                   \
     const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5,      \
         const T6 &v6, const T7 &v7, const T8 &v8
 #define TINYFORMAT_VARARGS_9                                                   \
     const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5,      \
         const T6 &v6, const T7 &v7, const T8 &v8, const T9 &v9
 #define TINYFORMAT_VARARGS_10                                                  \
     const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5,      \
         const T6 &v6, const T7 &v7, const T8 &v8, const T9 &v9, const T10 &v10
 #define TINYFORMAT_VARARGS_11                                                  \
     const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5,      \
         const T6 &v6, const T7 &v7, const T8 &v8, const T9 &v9,                \
         const T10 &v10, const T11 &v11
 #define TINYFORMAT_VARARGS_12                                                  \
     const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5,      \
         const T6 &v6, const T7 &v7, const T8 &v8, const T9 &v9,                \
         const T10 &v10, const T11 &v11, const T12 &v12
 #define TINYFORMAT_VARARGS_13                                                  \
     const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5,      \
         const T6 &v6, const T7 &v7, const T8 &v8, const T9 &v9,                \
         const T10 &v10, const T11 &v11, const T12 &v12, const T13 &v13
 #define TINYFORMAT_VARARGS_14                                                  \
     const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5,      \
         const T6 &v6, const T7 &v7, const T8 &v8, const T9 &v9,                \
         const T10 &v10, const T11 &v11, const T12 &v12, const T13 &v13,        \
         const T14 &v14
 #define TINYFORMAT_VARARGS_15                                                  \
     const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5,      \
         const T6 &v6, const T7 &v7, const T8 &v8, const T9 &v9,                \
         const T10 &v10, const T11 &v11, const T12 &v12, const T13 &v13,        \
         const T14 &v14, const T15 &v15
 #define TINYFORMAT_VARARGS_16                                                  \
     const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5,      \
         const T6 &v6, const T7 &v7, const T8 &v8, const T9 &v9,                \
         const T10 &v10, const T11 &v11, const T12 &v12, const T13 &v13,        \
         const T14 &v14, const T15 &v15, const T16 &v16
 
 #define TINYFORMAT_PASSARGS_1 v1
 #define TINYFORMAT_PASSARGS_2 v1, v2
 #define TINYFORMAT_PASSARGS_3 v1, v2, v3
 #define TINYFORMAT_PASSARGS_4 v1, v2, v3, v4
 #define TINYFORMAT_PASSARGS_5 v1, v2, v3, v4, v5
 #define TINYFORMAT_PASSARGS_6 v1, v2, v3, v4, v5, v6
 #define TINYFORMAT_PASSARGS_7 v1, v2, v3, v4, v5, v6, v7
 #define TINYFORMAT_PASSARGS_8 v1, v2, v3, v4, v5, v6, v7, v8
 #define TINYFORMAT_PASSARGS_9 v1, v2, v3, v4, v5, v6, v7, v8, v9
 #define TINYFORMAT_PASSARGS_10 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10
 #define TINYFORMAT_PASSARGS_11 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11
 #define TINYFORMAT_PASSARGS_12 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12
 #define TINYFORMAT_PASSARGS_13                                                 \
     v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13
 #define TINYFORMAT_PASSARGS_14                                                 \
     v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14
 #define TINYFORMAT_PASSARGS_15                                                 \
     v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15
 #define TINYFORMAT_PASSARGS_16                                                 \
     v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16
 
 #define TINYFORMAT_PASSARGS_TAIL_1
 #define TINYFORMAT_PASSARGS_TAIL_2 , v2
 #define TINYFORMAT_PASSARGS_TAIL_3 , v2, v3
 #define TINYFORMAT_PASSARGS_TAIL_4 , v2, v3, v4
 #define TINYFORMAT_PASSARGS_TAIL_5 , v2, v3, v4, v5
 #define TINYFORMAT_PASSARGS_TAIL_6 , v2, v3, v4, v5, v6
 #define TINYFORMAT_PASSARGS_TAIL_7 , v2, v3, v4, v5, v6, v7
 #define TINYFORMAT_PASSARGS_TAIL_8 , v2, v3, v4, v5, v6, v7, v8
 #define TINYFORMAT_PASSARGS_TAIL_9 , v2, v3, v4, v5, v6, v7, v8, v9
 #define TINYFORMAT_PASSARGS_TAIL_10 , v2, v3, v4, v5, v6, v7, v8, v9, v10
 #define TINYFORMAT_PASSARGS_TAIL_11 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11
 #define TINYFORMAT_PASSARGS_TAIL_12                                            \
     , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12
 #define TINYFORMAT_PASSARGS_TAIL_13                                            \
     , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13
 #define TINYFORMAT_PASSARGS_TAIL_14                                            \
     , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14
 #define TINYFORMAT_PASSARGS_TAIL_15                                            \
     , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15
 #define TINYFORMAT_PASSARGS_TAIL_16                                            \
     , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16
 
 #define TINYFORMAT_FOREACH_ARGNUM(m)                                           \
     m(1) m(2) m(3) m(4) m(5) m(6) m(7) m(8) m(9) m(10) m(11) m(12) m(13) m(14) \
         m(15) m(16)
 //[[[end]]]
 
 namespace detail {
 
     // Type-opaque holder for an argument to format(), with associated actions
     // on the type held as explicit function pointers. This allows FormatArg's
     // for each argument to be allocated as a homogenous array inside FormatList
     // whereas a naive implementation based on inheritance does not.
     class FormatArg {
     public:
         FormatArg() {}
 
         template <typename T>
         FormatArg(const T &value)
             : m_value(static_cast<const void *>(&value)),
               m_formatImpl(&formatImpl<T>), m_toIntImpl(&toIntImpl<T>) {}
 
         void format(std::ostream &out, const char *fmtBegin, const char *fmtEnd,
                     int ntrunc) const {
             m_formatImpl(out, fmtBegin, fmtEnd, ntrunc, m_value);
         }
 
         int toInt() const { return m_toIntImpl(m_value); }
 
     private:
         template <typename T>
         TINYFORMAT_HIDDEN static void
         formatImpl(std::ostream &out, const char *fmtBegin, const char *fmtEnd,
                    int ntrunc, const void *value) {
             formatValue(out, fmtBegin, fmtEnd, ntrunc,
                         *static_cast<const T *>(value));
         }
 
         template <typename T>
         TINYFORMAT_HIDDEN static int toIntImpl(const void *value) {
             return convertToInt<T>::invoke(*static_cast<const T *>(value));
         }
 
         const void *m_value;
         void (*m_formatImpl)(std::ostream &out, const char *fmtBegin,
                              const char *fmtEnd, int ntrunc, const void *value);
         int (*m_toIntImpl)(const void *value);
     };
 
     // Parse and return an integer from the string c, as atoi()
     // On return, c is set to one past the end of the integer.
     inline int parseIntAndAdvance(const char *&c) {
         int i = 0;
         for (; *c >= '0' && *c <= '9'; ++c)
             i = 10 * i + (*c - '0');
         return i;
     }
 
     // Print literal part of format string and return next format spec position.
     //
     // Skips over any occurrences of '%%', printing a literal '%' to the output.
     // The position of the first % character of the next nontrivial format spec
     // is returned, or the end of string.
     inline const char *printFormatStringLiteral(std::ostream &out,
                                                 const char *fmt) {
         const char *c = fmt;
         for (;; ++c) {
             switch (*c) {
                 case '\0':
                     out.write(fmt, c - fmt);
                     return c;
                 case '%':
                     out.write(fmt, c - fmt);
                     if (*(c + 1) != '%') return c;
                     // for "%%", tack trailing % onto next literal section.
                     fmt = ++c;
                     break;
                 default:
                     break;
             }
         }
     }
 
     // Parse a format string and set the stream state accordingly.
     //
     // The format mini-language recognized here is meant to be the one from C99,
     // with the form "%[flags][width][.precision][length]type".
     //
     // Formatting options which can't be natively represented using the ostream
     // state are returned in spacePadPositive (for space padded positive
     // numbers) and ntrunc (for truncating conversions). argIndex is incremented
     // if necessary to pull out variable width and precision. The function
     // returns a pointer to the character after the end of the current format
     // spec.
     inline const char *
     streamStateFromFormat(std::ostream &out, bool &spacePadPositive,
                           int &ntrunc, const char *fmtStart,
                           const detail::FormatArg *formatters, int &argIndex,
                           int numFormatters) {
         if (*fmtStart != '%') {
             TINYFORMAT_ERROR("tinyformat: Not enough conversion specifiers in "
                              "format string");
             return fmtStart;
         }
         // Reset stream state to defaults.
         out.width(0);
         out.precision(6);
         out.fill(' ');
         // Reset most flags; ignore irrelevant unitbuf & skipws.
         out.unsetf(std::ios::adjustfield | std::ios::basefield |
                    std::ios::floatfield | std::ios::showbase |
                    std::ios::boolalpha | std::ios::showpoint |
                    std::ios::showpos | std::ios::uppercase);
         bool precisionSet = false;
         bool widthSet = false;
         int widthExtra = 0;
         const char *c = fmtStart + 1;
         // 1) Parse flags
         for (;; ++c) {
             switch (*c) {
                 case '#':
                     out.setf(std::ios::showpoint | std::ios::showbase);
                     continue;
                 case '0':
                     // overridden by left alignment ('-' flag)
                     if (!(out.flags() & std::ios::left)) {
                         // Use internal padding so that numeric values are
                         // formatted correctly, eg -00010 rather than 000-10
                         out.fill('0');
                         out.setf(std::ios::internal, std::ios::adjustfield);
                     }
                     continue;
                 case '-':
                     out.fill(' ');
                     out.setf(std::ios::left, std::ios::adjustfield);
                     continue;
                 case ' ':
                     // overridden by show positive sign, '+' flag.
                     if (!(out.flags() & std::ios::showpos))
                         spacePadPositive = true;
                     continue;
                 case '+':
                     out.setf(std::ios::showpos);
                     spacePadPositive = false;
                     widthExtra = 1;
                     continue;
                 default:
                     break;
             }
             break;
         }
         // 2) Parse width
         if (*c >= '0' && *c <= '9') {
             widthSet = true;
             out.width(parseIntAndAdvance(c));
         }
         if (*c == '*') {
             widthSet = true;
             int width = 0;
             if (argIndex < numFormatters)
                 width = formatters[argIndex++].toInt();
             else
                 TINYFORMAT_ERROR(
                     "tinyformat: Not enough arguments to read variable width");
             if (width < 0) {
                 // negative widths correspond to '-' flag set
                 out.fill(' ');
                 out.setf(std::ios::left, std::ios::adjustfield);
                 width = -width;
             }
             out.width(width);
             ++c;
         }
         // 3) Parse precision
         if (*c == '.') {
             ++c;
             int precision = 0;
             if (*c == '*') {
                 ++c;
                 if (argIndex < numFormatters)
                     precision = formatters[argIndex++].toInt();
                 else
                     TINYFORMAT_ERROR("tinyformat: Not enough arguments to read "
                                      "variable precision");
             } else {
                 if (*c >= '0' && *c <= '9') {
                     precision = parseIntAndAdvance(c);
                 } else if (*c == '-') {
                     // negative precisions ignored, treated as zero.
                     parseIntAndAdvance(++c);
                 }
             }
             out.precision(precision);
             precisionSet = true;
         }
         // 4) Ignore any C99 length modifier
         while (*c == 'l' || *c == 'h' || *c == 'L' || *c == 'j' || *c == 'z' ||
                *c == 't')
             ++c;
         // 5) We're up to the conversion specifier character.
         // Set stream flags based on conversion specifier (thanks to the
         // boost::format class for forging the way here).
         bool intConversion = false;
         switch (*c) {
             case 'u':
             case 'd':
             case 'i':
                 out.setf(std::ios::dec, std::ios::basefield);
                 intConversion = true;
                 break;
             case 'o':
                 out.setf(std::ios::oct, std::ios::basefield);
                 intConversion = true;
                 break;
             case 'X':
                 out.setf(std::ios::uppercase);
             // FALLTHROUGH
             case 'x':
             case 'p':
                 out.setf(std::ios::hex, std::ios::basefield);
                 intConversion = true;
                 break;
             case 'E':
                 out.setf(std::ios::uppercase);
             // FALLTHROUGH
             case 'e':
                 out.setf(std::ios::scientific, std::ios::floatfield);
                 out.setf(std::ios::dec, std::ios::basefield);
                 break;
             case 'F':
                 out.setf(std::ios::uppercase);
             // FALLTHROUGH
             case 'f':
                 out.setf(std::ios::fixed, std::ios::floatfield);
                 break;
             case 'G':
                 out.setf(std::ios::uppercase);
             // FALLTHROUGH
             case 'g':
                 out.setf(std::ios::dec, std::ios::basefield);
                 // As in boost::format, let stream decide float format.
                 out.flags(out.flags() & ~std::ios::floatfield);
                 break;
             case 'a':
             case 'A':
                 TINYFORMAT_ERROR("tinyformat: the %a and %A conversion specs "
                                  "are not supported");
                 break;
             case 'c':
                 // Handled as special case inside formatValue()
                 break;
             case 's':
                 if (precisionSet) ntrunc = static_cast<int>(out.precision());
                 // Make %s print booleans as "true" and "false"
                 out.setf(std::ios::boolalpha);
                 break;
             case 'n':
                 // Not supported - will cause problems!
                 TINYFORMAT_ERROR(
                     "tinyformat: %n conversion spec not supported");
                 break;
             case '\0':
                 TINYFORMAT_ERROR("tinyformat: Conversion spec incorrectly "
                                  "terminated by end of string");
                 return c;
             default:
                 break;
         }
         if (intConversion && precisionSet && !widthSet) {
             // "precision" for integers gives the minimum number of digits (to
             // be padded with zeros on the left). This isn't really supported by
             // the iostreams, but we can approximately simulate it with the
             // width if the width isn't otherwise used.
             out.width(out.precision() + widthExtra);
             out.setf(std::ios::internal, std::ios::adjustfield);
             out.fill('0');
         }
         return c + 1;
     }
 
     //------------------------------------------------------------------------------
     inline void formatImpl(std::ostream &out, const char *fmt,
                            const detail::FormatArg *formatters,
                            int numFormatters) {
         // Saved stream state
         std::streamsize origWidth = out.width();
         std::streamsize origPrecision = out.precision();
         std::ios::fmtflags origFlags = out.flags();
         char origFill = out.fill();
 
         for (int argIndex = 0; argIndex < numFormatters; ++argIndex) {
             // Parse the format string
             fmt = printFormatStringLiteral(out, fmt);
             bool spacePadPositive = false;
             int ntrunc = -1;
             const char *fmtEnd =
                 streamStateFromFormat(out, spacePadPositive, ntrunc, fmt,
                                       formatters, argIndex, numFormatters);
             if (argIndex >= numFormatters) {
                 // Check args remain after reading any variable width/precision
                 TINYFORMAT_ERROR("tinyformat: Not enough format arguments");
                 return;
             }
             const FormatArg &arg = formatters[argIndex];
             // Format the arg into the stream.
             if (!spacePadPositive)
                 arg.format(out, fmt, fmtEnd, ntrunc);
             else {
                 // The following is a special case with no direct correspondence
                 // between stream formatting and the printf() behaviour.
                 // Simulate it crudely by formatting into a temporary string
                 // stream and munging the resulting string.
                 std::ostringstream tmpStream;
                 tmpStream.copyfmt(out);
                 tmpStream.setf(std::ios::showpos);
                 arg.format(tmpStream, fmt, fmtEnd, ntrunc);
                 // allocates... yuck.
                 std::string result = tmpStream.str();
                 for (size_t i = 0, iend = result.size(); i < iend; ++i)
                     if (result[i] == '+') result[i] = ' ';
                 out << result;
             }
             fmt = fmtEnd;
         }
 
         // Print remaining part of format string.
         fmt = printFormatStringLiteral(out, fmt);
         if (*fmt != '\0')
             TINYFORMAT_ERROR(
                 "tinyformat: Too many conversion specifiers in format string");
 
         // Restore stream state
         out.width(origWidth);
         out.precision(origPrecision);
         out.flags(origFlags);
         out.fill(origFill);
     }
 
 } // namespace detail
 
 /// List of template arguments format(), held in a type-opaque way.
 ///
 /// A const reference to FormatList (typedef'd as FormatListRef) may be
 /// conveniently used to pass arguments to non-template functions: All type
 /// information has been stripped from the arguments, leaving just enough of a
 /// common interface to perform formatting as required.
 class FormatList {
 public:
     FormatList(detail::FormatArg *formatters, int N)
         : m_formatters(formatters), m_N(N) {}
 
     friend void vformat(std::ostream &out, const char *fmt,
                         const FormatList &list);
 
 private:
     const detail::FormatArg *m_formatters;
     int m_N;
 };
 
 /// Reference to type-opaque format list for passing to vformat()
 typedef const FormatList &FormatListRef;
 
 namespace detail {
 
     // Format list subclass with fixed storage to avoid dynamic allocation
     template <int N> class FormatListN : public FormatList {
     public:
 #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES
         template <typename... Args>
         FormatListN(const Args &... args)
             : FormatList(&m_formatterStore[0], N),
               m_formatterStore{FormatArg(args)...} {
             static_assert(sizeof...(args) == N, "Number of args must be N");
         }
 #else // C++98 version
         void init(int) {}
 #define TINYFORMAT_MAKE_FORMATLIST_CONSTRUCTOR(n)                              \
                                                                                \
     template <TINYFORMAT_ARGTYPES(n)>                                          \
     FormatListN(TINYFORMAT_VARARGS(n)) : FormatList(&m_formatterStore[0], n) { \
         assert(n == N);                                                        \
         init(0, TINYFORMAT_PASSARGS(n));                                       \
     }                                                                          \
                                                                                \
     template <TINYFORMAT_ARGTYPES(n)>                                          \
     void init(int i, TINYFORMAT_VARARGS(n)) {                                  \
         m_formatterStore[i] = FormatArg(v1);                                   \
         init(i + 1 TINYFORMAT_PASSARGS_TAIL(n));                               \
     }
 
         TINYFORMAT_FOREACH_ARGNUM(TINYFORMAT_MAKE_FORMATLIST_CONSTRUCTOR)
 #undef TINYFORMAT_MAKE_FORMATLIST_CONSTRUCTOR
 #endif
 
     private:
         FormatArg m_formatterStore[N];
     };
 
     // Special 0-arg version - MSVC says zero-sized C array in struct is
     // nonstandard.
     template <> class FormatListN<0> : public FormatList {
     public:
         FormatListN() : FormatList(0, 0) {}
     };
 
 } // namespace detail
 
 //------------------------------------------------------------------------------
 // Primary API functions
 
 #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES
 
 /// Make type-agnostic format list from list of template arguments.
 ///
 /// The exact return type of this function is an implementation detail and
 /// shouldn't be relied upon.  Instead it should be stored as a FormatListRef:
 ///
 ///   FormatListRef formatList = makeFormatList( /*...*/ );
 template <typename... Args>
 detail::FormatListN<sizeof...(Args)> makeFormatList(const Args &... args) {
     return detail::FormatListN<sizeof...(args)>(args...);
 }
 
 #else // C++98 version
 
 inline detail::FormatListN<0> makeFormatList() {
     return detail::FormatListN<0>();
 }
 #define TINYFORMAT_MAKE_MAKEFORMATLIST(n)                                      \
     template <TINYFORMAT_ARGTYPES(n)>                                          \
     detail::FormatListN<n> makeFormatList(TINYFORMAT_VARARGS(n)) {             \
         return detail::FormatListN<n>(TINYFORMAT_PASSARGS(n));                 \
     }
 TINYFORMAT_FOREACH_ARGNUM(TINYFORMAT_MAKE_MAKEFORMATLIST)
 #undef TINYFORMAT_MAKE_MAKEFORMATLIST
 
 #endif
 
 /// Format list of arguments to the stream according to the given format string.
 ///
 /// The name vformat() is chosen for the semantic similarity to vprintf(): the
 /// list of format arguments is held in a single function argument.
 inline void vformat(std::ostream &out, const char *fmt, FormatListRef list) {
     detail::formatImpl(out, fmt, list.m_formatters, list.m_N);
 }
 
 #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES
 
 /// Format list of arguments to the stream according to given format string.
 template <typename... Args>
 void format(std::ostream &out, const char *fmt, const Args &... args) {
     vformat(out, fmt, makeFormatList(args...));
 }
 
 /// Format list of arguments according to the given format string and return the
 /// result as a string.
 template <typename... Args>
 std::string format(const char *fmt, const Args &... args) {
     std::ostringstream oss;
     format(oss, fmt, args...);
     return oss.str();
 }
 
 /// Format list of arguments to std::cout, according to the given format string
 template <typename... Args> void printf(const char *fmt, const Args &... args) {
     format(std::cout, fmt, args...);
 }
 
 template <typename... Args>
 void printfln(const char *fmt, const Args &... args) {
     format(std::cout, fmt, args...);
     std::cout << '\n';
 }
 
 #else // C++98 version
 
 inline void format(std::ostream &out, const char *fmt) {
     vformat(out, fmt, makeFormatList());
 }
 
 inline std::string format(const char *fmt) {
     std::ostringstream oss;
     format(oss, fmt);
     return oss.str();
 }
 
 inline void printf(const char *fmt) {
     format(std::cout, fmt);
 }
 
 inline void printfln(const char *fmt) {
     format(std::cout, fmt);
     std::cout << '\n';
 }
 
 #define TINYFORMAT_MAKE_FORMAT_FUNCS(n)                                        \
                                                                                \
     template <TINYFORMAT_ARGTYPES(n)>                                          \
     void format(std::ostream &out, const char *fmt, TINYFORMAT_VARARGS(n)) {   \
         vformat(out, fmt, makeFormatList(TINYFORMAT_PASSARGS(n)));             \
     }                                                                          \
                                                                                \
     template <TINYFORMAT_ARGTYPES(n)>                                          \
     std::string format(const char *fmt, TINYFORMAT_VARARGS(n)) {               \
         std::ostringstream oss;                                                \
         format(oss, fmt, TINYFORMAT_PASSARGS(n));                              \
         return oss.str();                                                      \
     }                                                                          \
                                                                                \
     template <TINYFORMAT_ARGTYPES(n)>                                          \
     void printf(const char *fmt, TINYFORMAT_VARARGS(n)) {                      \
         format(std::cout, fmt, TINYFORMAT_PASSARGS(n));                        \
     }                                                                          \
                                                                                \
     template <TINYFORMAT_ARGTYPES(n)>                                          \
     void printfln(const char *fmt, TINYFORMAT_VARARGS(n)) {                    \
         format(std::cout, fmt, TINYFORMAT_PASSARGS(n));                        \
         std::cout << '\n';                                                     \
     }
 
 TINYFORMAT_FOREACH_ARGNUM(TINYFORMAT_MAKE_FORMAT_FUNCS)
 #undef TINYFORMAT_MAKE_FORMAT_FUNCS
 
 #endif
 
 // Added for Bitcoin Core
 template <typename... Args>
 std::string format(const std::string &fmt, const Args &... args) {
     std::ostringstream oss;
     format(oss, fmt.c_str(), args...);
     return oss.str();
 }
 
 } // namespace tinyformat
 
 #define strprintf tfm::format
 
 #endif // TINYFORMAT_H_INCLUDED
diff --git a/src/uint256.cpp b/src/uint256.cpp
index 6207aaa4d..3dd319a9c 100644
--- a/src/uint256.cpp
+++ b/src/uint256.cpp
@@ -1,73 +1,73 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #include "uint256.h"
 
 #include "utilstrencodings.h"
 
 #include <cstdio>
 #include <cstring>
 
 template <unsigned int BITS>
-base_blob<BITS>::base_blob(const std::vector<unsigned char> &vch) {
+base_blob<BITS>::base_blob(const std::vector<uint8_t> &vch) {
     assert(vch.size() == sizeof(data));
     memcpy(data, &vch[0], sizeof(data));
 }
 
 template <unsigned int BITS> std::string base_blob<BITS>::GetHex() const {
     char psz[sizeof(data) * 2 + 1];
     for (unsigned int i = 0; i < sizeof(data); i++)
         sprintf(psz + i * 2, "%02x", data[sizeof(data) - i - 1]);
     return std::string(psz, psz + sizeof(data) * 2);
 }
 
 template <unsigned int BITS> void base_blob<BITS>::SetHex(const char *psz) {
     memset(data, 0, sizeof(data));
 
     // skip leading spaces
     while (isspace(*psz))
         psz++;
 
     // skip 0x
     if (psz[0] == '0' && tolower(psz[1]) == 'x') psz += 2;
 
     // hex string to uint
     const char *pbegin = psz;
     while (::HexDigit(*psz) != -1)
         psz++;
     psz--;
-    unsigned char *p1 = (unsigned char *)data;
-    unsigned char *pend = p1 + WIDTH;
+    uint8_t *p1 = (uint8_t *)data;
+    uint8_t *pend = p1 + WIDTH;
     while (psz >= pbegin && p1 < pend) {
         *p1 = ::HexDigit(*psz--);
         if (psz >= pbegin) {
-            *p1 |= ((unsigned char)::HexDigit(*psz--) << 4);
+            *p1 |= uint8_t(::HexDigit(*psz--) << 4);
             p1++;
         }
     }
 }
 
 template <unsigned int BITS>
 void base_blob<BITS>::SetHex(const std::string &str) {
     SetHex(str.c_str());
 }
 
 template <unsigned int BITS> std::string base_blob<BITS>::ToString() const {
     return (GetHex());
 }
 
 // Explicit instantiations for base_blob<160>
-template base_blob<160>::base_blob(const std::vector<unsigned char> &);
+template base_blob<160>::base_blob(const std::vector<uint8_t> &);
 template std::string base_blob<160>::GetHex() const;
 template std::string base_blob<160>::ToString() const;
 template void base_blob<160>::SetHex(const char *);
 template void base_blob<160>::SetHex(const std::string &);
 
 // Explicit instantiations for base_blob<256>
-template base_blob<256>::base_blob(const std::vector<unsigned char> &);
+template base_blob<256>::base_blob(const std::vector<uint8_t> &);
 template std::string base_blob<256>::GetHex() const;
 template std::string base_blob<256>::ToString() const;
 template void base_blob<256>::SetHex(const char *);
 template void base_blob<256>::SetHex(const std::string &);
diff --git a/src/uint256.h b/src/uint256.h
index bd756cb62..aa42d538f 100644
--- a/src/uint256.h
+++ b/src/uint256.h
@@ -1,141 +1,139 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_UINT256_H
 #define BITCOIN_UINT256_H
 
 #include "crypto/common.h"
 
 #include <cassert>
 #include <cstdint>
 #include <cstring>
 #include <stdexcept>
 #include <string>
 #include <vector>
 
 /** Template base class for fixed-sized opaque blobs. */
 template <unsigned int BITS> class base_blob {
 protected:
     enum { WIDTH = BITS / 8 };
     uint8_t data[WIDTH];
 
 public:
     base_blob() { memset(data, 0, sizeof(data)); }
 
-    explicit base_blob(const std::vector<unsigned char> &vch);
+    explicit base_blob(const std::vector<uint8_t> &vch);
 
     bool IsNull() const {
         for (int i = 0; i < WIDTH; i++)
             if (data[i] != 0) return false;
         return true;
     }
 
     void SetNull() { memset(data, 0, sizeof(data)); }
 
     inline int Compare(const base_blob &other) const {
         return memcmp(data, other.data, sizeof(data));
     }
 
     friend inline bool operator==(const base_blob &a, const base_blob &b) {
         return a.Compare(b) == 0;
     }
     friend inline bool operator!=(const base_blob &a, const base_blob &b) {
         return a.Compare(b) != 0;
     }
     friend inline bool operator<(const base_blob &a, const base_blob &b) {
         return a.Compare(b) < 0;
     }
 
     std::string GetHex() const;
     void SetHex(const char *psz);
     void SetHex(const std::string &str);
     std::string ToString() const;
 
-    unsigned char *begin() { return &data[0]; }
+    uint8_t *begin() { return &data[0]; }
 
-    unsigned char *end() { return &data[WIDTH]; }
+    uint8_t *end() { return &data[WIDTH]; }
 
-    const unsigned char *begin() const { return &data[0]; }
+    const uint8_t *begin() const { return &data[0]; }
 
-    const unsigned char *end() const { return &data[WIDTH]; }
+    const uint8_t *end() const { return &data[WIDTH]; }
 
     unsigned int size() const { return sizeof(data); }
 
     uint64_t GetUint64(int pos) const {
         const uint8_t *ptr = data + pos * 8;
         return ((uint64_t)ptr[0]) | ((uint64_t)ptr[1]) << 8 |
                ((uint64_t)ptr[2]) << 16 | ((uint64_t)ptr[3]) << 24 |
                ((uint64_t)ptr[4]) << 32 | ((uint64_t)ptr[5]) << 40 |
                ((uint64_t)ptr[6]) << 48 | ((uint64_t)ptr[7]) << 56;
     }
 
     template <typename Stream> void Serialize(Stream &s) const {
         s.write((char *)data, sizeof(data));
     }
 
     template <typename Stream> void Unserialize(Stream &s) {
         s.read((char *)data, sizeof(data));
     }
 };
 
 /**
  * 160-bit opaque blob.
  * @note This type is called uint160 for historical reasons only. It is an
  * opaque blob of 160 bits and has no integer operations.
  */
 class uint160 : public base_blob<160> {
 public:
     uint160() {}
     uint160(const base_blob<160> &b) : base_blob<160>(b) {}
-    explicit uint160(const std::vector<unsigned char> &vch)
-        : base_blob<160>(vch) {}
+    explicit uint160(const std::vector<uint8_t> &vch) : base_blob<160>(vch) {}
 };
 
 /**
  * 256-bit opaque blob.
  * @note This type is called uint256 for historical reasons only. It is an
  * opaque blob of 256 bits and has no integer operations. Use arith_uint256 if
  * those are required.
  */
 class uint256 : public base_blob<256> {
 public:
     uint256() {}
     uint256(const base_blob<256> &b) : base_blob<256>(b) {}
-    explicit uint256(const std::vector<unsigned char> &vch)
-        : base_blob<256>(vch) {}
+    explicit uint256(const std::vector<uint8_t> &vch) : base_blob<256>(vch) {}
 
     /**
      * A cheap hash function that just returns 64 bits from the result, it can
      * be used when the contents are considered uniformly random. It is not
      * appropriate when the value can easily be influenced from outside as e.g.
      * a network adversary could provide values to trigger worst-case behavior.
      */
     uint64_t GetCheapHash() const { return ReadLE64(data); }
 };
 
 /**
  * uint256 from const char *.
  * This is a separate function because the constructor uint256(const char*) can
  * result in dangerously catching uint256(0).
  */
 inline uint256 uint256S(const char *str) {
     uint256 rv;
     rv.SetHex(str);
     return rv;
 }
 
 /**
  * uint256 from std::string.
  * This is a separate function because the constructor uint256(const std::string
  * &str) can result in dangerously catching uint256(0) via std::string(const
  * char*).
  */
 inline uint256 uint256S(const std::string &str) {
     uint256 rv;
     rv.SetHex(str);
     return rv;
 }
 
 #endif // BITCOIN_UINT256_H
diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp
index 4189bed88..180297f74 100644
--- a/src/utilstrencodings.cpp
+++ b/src/utilstrencodings.cpp
@@ -1,697 +1,695 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #include "utilstrencodings.h"
 
 #include "tinyformat.h"
 
 #include <cerrno>
 #include <cstdlib>
 #include <cstring>
 #include <limits>
 
 static const std::string CHARS_ALPHA_NUM =
     "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
 
 static const std::string SAFE_CHARS[] = {
     // SAFE_CHARS_DEFAULT
     CHARS_ALPHA_NUM + " .,;-_/:?@()",
     // SAFE_CHARS_UA_COMMENT
     CHARS_ALPHA_NUM + " .,;-_?@",
 };
 
 std::string SanitizeString(const std::string &str, int rule) {
     std::string strResult;
     for (std::string::size_type i = 0; i < str.size(); i++) {
         if (SAFE_CHARS[rule].find(str[i]) != std::string::npos)
             strResult.push_back(str[i]);
     }
     return strResult;
 }
 
 const signed char p_util_hexdigit[256] = {
     -1, -1,  -1,  -1,  -1,  -1,  -1,  -1, -1, -1, -1, -1, -1, -1, -1, -1,
     -1, -1,  -1,  -1,  -1,  -1,  -1,  -1, -1, -1, -1, -1, -1, -1, -1, -1,
     -1, -1,  -1,  -1,  -1,  -1,  -1,  -1, -1, -1, -1, -1, -1, -1, -1, -1,
     0,  1,   2,   3,   4,   5,   6,   7,  8,  9,  -1, -1, -1, -1, -1, -1,
     -1, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     -1, -1,  -1,  -1,  -1,  -1,  -1,  -1, -1, -1, -1, -1, -1, -1, -1, -1,
     -1, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     -1, -1,  -1,  -1,  -1,  -1,  -1,  -1, -1, -1, -1, -1, -1, -1, -1, -1,
     -1, -1,  -1,  -1,  -1,  -1,  -1,  -1, -1, -1, -1, -1, -1, -1, -1, -1,
     -1, -1,  -1,  -1,  -1,  -1,  -1,  -1, -1, -1, -1, -1, -1, -1, -1, -1,
     -1, -1,  -1,  -1,  -1,  -1,  -1,  -1, -1, -1, -1, -1, -1, -1, -1, -1,
     -1, -1,  -1,  -1,  -1,  -1,  -1,  -1, -1, -1, -1, -1, -1, -1, -1, -1,
     -1, -1,  -1,  -1,  -1,  -1,  -1,  -1, -1, -1, -1, -1, -1, -1, -1, -1,
     -1, -1,  -1,  -1,  -1,  -1,  -1,  -1, -1, -1, -1, -1, -1, -1, -1, -1,
     -1, -1,  -1,  -1,  -1,  -1,  -1,  -1, -1, -1, -1, -1, -1, -1, -1, -1,
     -1, -1,  -1,  -1,  -1,  -1,  -1,  -1, -1, -1, -1, -1, -1, -1, -1, -1,
 };
 
 signed char HexDigit(char c) {
-    return p_util_hexdigit[(unsigned char)c];
+    return p_util_hexdigit[(uint8_t)c];
 }
 
 bool IsHex(const std::string &str) {
     for (std::string::const_iterator it(str.begin()); it != str.end(); ++it) {
         if (HexDigit(*it) < 0) return false;
     }
     return (str.size() > 0) && (str.size() % 2 == 0);
 }
 
-std::vector<unsigned char> ParseHex(const char *psz) {
+std::vector<uint8_t> ParseHex(const char *psz) {
     // convert hex dump to vector
-    std::vector<unsigned char> vch;
+    std::vector<uint8_t> vch;
     while (true) {
         while (isspace(*psz))
             psz++;
         signed char c = HexDigit(*psz++);
         if (c == (signed char)-1) break;
-        unsigned char n = (c << 4);
+        uint8_t n = (c << 4);
         c = HexDigit(*psz++);
         if (c == (signed char)-1) break;
         n |= c;
         vch.push_back(n);
     }
     return vch;
 }
 
-std::vector<unsigned char> ParseHex(const std::string &str) {
+std::vector<uint8_t> ParseHex(const std::string &str) {
     return ParseHex(str.c_str());
 }
 
-std::string EncodeBase64(const unsigned char *pch, size_t len) {
+std::string EncodeBase64(const uint8_t *pch, size_t len) {
     static const char *pbase64 =
         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
     std::string strRet = "";
     strRet.reserve((len + 2) / 3 * 4);
 
     int mode = 0, left = 0;
-    const unsigned char *pchEnd = pch + len;
+    const uint8_t *pchEnd = pch + len;
 
     while (pch < pchEnd) {
         int enc = *(pch++);
         switch (mode) {
             case 0: // we have no bits
                 strRet += pbase64[enc >> 2];
                 left = (enc & 3) << 4;
                 mode = 1;
                 break;
 
             case 1: // we have two bits
                 strRet += pbase64[left | (enc >> 4)];
                 left = (enc & 15) << 2;
                 mode = 2;
                 break;
 
             case 2: // we have four bits
                 strRet += pbase64[left | (enc >> 6)];
                 strRet += pbase64[enc & 63];
                 mode = 0;
                 break;
         }
     }
 
     if (mode) {
         strRet += pbase64[left];
         strRet += '=';
         if (mode == 1) strRet += '=';
     }
 
     return strRet;
 }
 
 std::string EncodeBase64(const std::string &str) {
-    return EncodeBase64((const unsigned char *)str.c_str(), str.size());
+    return EncodeBase64((const uint8_t *)str.c_str(), str.size());
 }
 
-std::vector<unsigned char> DecodeBase64(const char *p, bool *pfInvalid) {
+std::vector<uint8_t> DecodeBase64(const char *p, bool *pfInvalid) {
     static const int decode64_table[256] = {
         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
         -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57,
         58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0,  1,  2,  3,  4,  5,  6,
         7,  8,  9,  10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
         25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
         37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1,
         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
         -1, -1, -1, -1};
 
     if (pfInvalid) *pfInvalid = false;
 
-    std::vector<unsigned char> vchRet;
+    std::vector<uint8_t> vchRet;
     vchRet.reserve(strlen(p) * 3 / 4);
 
     int mode = 0;
     int left = 0;
 
     while (1) {
-        int dec = decode64_table[(unsigned char)*p];
+        int dec = decode64_table[(uint8_t)*p];
         if (dec == -1) break;
         p++;
         switch (mode) {
             case 0: // we have no bits and get 6
                 left = dec;
                 mode = 1;
                 break;
 
             case 1: // we have 6 bits and keep 4
                 vchRet.push_back((left << 2) | (dec >> 4));
                 left = dec & 15;
                 mode = 2;
                 break;
 
             case 2: // we have 4 bits and get 6, we keep 2
                 vchRet.push_back((left << 4) | (dec >> 2));
                 left = dec & 3;
                 mode = 3;
                 break;
 
             case 3: // we have 2 bits and get 6
                 vchRet.push_back((left << 6) | dec);
                 mode = 0;
                 break;
         }
     }
 
     if (pfInvalid) switch (mode) {
             case 0: // 4n base64 characters processed: ok
                 break;
 
             case 1: // 4n+1 base64 character processed: impossible
                 *pfInvalid = true;
                 break;
 
             case 2: // 4n+2 base64 characters processed: require '=='
                 if (left || p[0] != '=' || p[1] != '=' ||
-                    decode64_table[(unsigned char)p[2]] != -1)
+                    decode64_table[(uint8_t)p[2]] != -1)
                     *pfInvalid = true;
                 break;
 
             case 3: // 4n+3 base64 characters processed: require '='
-                if (left || p[0] != '=' ||
-                    decode64_table[(unsigned char)p[1]] != -1)
+                if (left || p[0] != '=' || decode64_table[(uint8_t)p[1]] != -1)
                     *pfInvalid = true;
                 break;
         }
 
     return vchRet;
 }
 
 std::string DecodeBase64(const std::string &str) {
-    std::vector<unsigned char> vchRet = DecodeBase64(str.c_str());
+    std::vector<uint8_t> vchRet = DecodeBase64(str.c_str());
     return (vchRet.size() == 0)
                ? std::string()
                : std::string((const char *)&vchRet[0], vchRet.size());
 }
 
-std::string EncodeBase32(const unsigned char *pch, size_t len) {
+std::string EncodeBase32(const uint8_t *pch, size_t len) {
     static const char *pbase32 = "abcdefghijklmnopqrstuvwxyz234567";
 
     std::string strRet = "";
     strRet.reserve((len + 4) / 5 * 8);
 
     int mode = 0, left = 0;
-    const unsigned char *pchEnd = pch + len;
+    const uint8_t *pchEnd = pch + len;
 
     while (pch < pchEnd) {
         int enc = *(pch++);
         switch (mode) {
             case 0: // we have no bits
                 strRet += pbase32[enc >> 3];
                 left = (enc & 7) << 2;
                 mode = 1;
                 break;
 
             case 1: // we have three bits
                 strRet += pbase32[left | (enc >> 6)];
                 strRet += pbase32[(enc >> 1) & 31];
                 left = (enc & 1) << 4;
                 mode = 2;
                 break;
 
             case 2: // we have one bit
                 strRet += pbase32[left | (enc >> 4)];
                 left = (enc & 15) << 1;
                 mode = 3;
                 break;
 
             case 3: // we have four bits
                 strRet += pbase32[left | (enc >> 7)];
                 strRet += pbase32[(enc >> 2) & 31];
                 left = (enc & 3) << 3;
                 mode = 4;
                 break;
 
             case 4: // we have two bits
                 strRet += pbase32[left | (enc >> 5)];
                 strRet += pbase32[enc & 31];
                 mode = 0;
         }
     }
 
     static const int nPadding[5] = {0, 6, 4, 3, 1};
     if (mode) {
         strRet += pbase32[left];
         for (int n = 0; n < nPadding[mode]; n++)
             strRet += '=';
     }
 
     return strRet;
 }
 
 std::string EncodeBase32(const std::string &str) {
-    return EncodeBase32((const unsigned char *)str.c_str(), str.size());
+    return EncodeBase32((const uint8_t *)str.c_str(), str.size());
 }
 
-std::vector<unsigned char> DecodeBase32(const char *p, bool *pfInvalid) {
+std::vector<uint8_t> DecodeBase32(const char *p, bool *pfInvalid) {
     static const int decode32_table[256] = {
         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29,
         30, 31, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0,  1,  2,  3,  4,  5,  6,
         7,  8,  9,  10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
         25, -1, -1, -1, -1, -1, -1, 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10,
         11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1,
         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
         -1, -1, -1, -1};
 
     if (pfInvalid) *pfInvalid = false;
 
-    std::vector<unsigned char> vchRet;
+    std::vector<uint8_t> vchRet;
     vchRet.reserve((strlen(p)) * 5 / 8);
 
     int mode = 0;
     int left = 0;
 
     while (1) {
-        int dec = decode32_table[(unsigned char)*p];
+        int dec = decode32_table[(uint8_t)*p];
         if (dec == -1) break;
         p++;
         switch (mode) {
             case 0: // we have no bits and get 5
                 left = dec;
                 mode = 1;
                 break;
 
             case 1: // we have 5 bits and keep 2
                 vchRet.push_back((left << 3) | (dec >> 2));
                 left = dec & 3;
                 mode = 2;
                 break;
 
             case 2: // we have 2 bits and keep 7
                 left = left << 5 | dec;
                 mode = 3;
                 break;
 
             case 3: // we have 7 bits and keep 4
                 vchRet.push_back((left << 1) | (dec >> 4));
                 left = dec & 15;
                 mode = 4;
                 break;
 
             case 4: // we have 4 bits, and keep 1
                 vchRet.push_back((left << 4) | (dec >> 1));
                 left = dec & 1;
                 mode = 5;
                 break;
 
             case 5: // we have 1 bit, and keep 6
                 left = left << 5 | dec;
                 mode = 6;
                 break;
 
             case 6: // we have 6 bits, and keep 3
                 vchRet.push_back((left << 2) | (dec >> 3));
                 left = dec & 7;
                 mode = 7;
                 break;
 
             case 7: // we have 3 bits, and keep 0
                 vchRet.push_back((left << 5) | dec);
                 mode = 0;
                 break;
         }
     }
 
     if (pfInvalid) switch (mode) {
             case 0: // 8n base32 characters processed: ok
                 break;
 
             case 1: // 8n+1 base32 characters processed: impossible
             case 3: //   +3
             case 6: //   +6
                 *pfInvalid = true;
                 break;
 
             case 2: // 8n+2 base32 characters processed: require '======'
                 if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' ||
                     p[3] != '=' || p[4] != '=' || p[5] != '=' ||
-                    decode32_table[(unsigned char)p[6]] != -1)
+                    decode32_table[(uint8_t)p[6]] != -1)
                     *pfInvalid = true;
                 break;
 
             case 4: // 8n+4 base32 characters processed: require '===='
                 if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' ||
-                    p[3] != '=' || decode32_table[(unsigned char)p[4]] != -1)
+                    p[3] != '=' || decode32_table[(uint8_t)p[4]] != -1)
                     *pfInvalid = true;
                 break;
 
             case 5: // 8n+5 base32 characters processed: require '==='
                 if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' ||
-                    decode32_table[(unsigned char)p[3]] != -1)
+                    decode32_table[(uint8_t)p[3]] != -1)
                     *pfInvalid = true;
                 break;
 
             case 7: // 8n+7 base32 characters processed: require '='
-                if (left || p[0] != '=' ||
-                    decode32_table[(unsigned char)p[1]] != -1)
+                if (left || p[0] != '=' || decode32_table[(uint8_t)p[1]] != -1)
                     *pfInvalid = true;
                 break;
         }
 
     return vchRet;
 }
 
 std::string DecodeBase32(const std::string &str) {
-    std::vector<unsigned char> vchRet = DecodeBase32(str.c_str());
+    std::vector<uint8_t> vchRet = DecodeBase32(str.c_str());
     return (vchRet.size() == 0)
                ? std::string()
                : std::string((const char *)&vchRet[0], vchRet.size());
 }
 
 static bool ParsePrechecks(const std::string &str) {
     // No empty string allowed
     if (str.empty()) return false;
     // No padding allowed
     if (str.size() >= 1 && (isspace(str[0]) || isspace(str[str.size() - 1])))
         return false;
     // No embedded NUL characters allowed
     if (str.size() != strlen(str.c_str())) return false;
     return true;
 }
 
 bool ParseInt32(const std::string &str, int32_t *out) {
     if (!ParsePrechecks(str)) return false;
     char *endp = nullptr;
     // strtol will not set errno if valid
     errno = 0;
     long int n = strtol(str.c_str(), &endp, 10);
     if (out) *out = (int32_t)n;
     // Note that strtol returns a *long int*, so even if strtol doesn't report a
     // over/underflow we still have to check that the returned value is within
     // the range of an *int32_t*. On 64-bit platforms the size of these types
     // may be different.
     return endp && *endp == 0 && !errno &&
            n >= std::numeric_limits<int32_t>::min() &&
            n <= std::numeric_limits<int32_t>::max();
 }
 
 bool ParseInt64(const std::string &str, int64_t *out) {
     if (!ParsePrechecks(str)) return false;
     char *endp = nullptr;
     // strtoll will not set errno if valid
     errno = 0;
     long long int n = strtoll(str.c_str(), &endp, 10);
     if (out) *out = (int64_t)n;
     // Note that strtoll returns a *long long int*, so even if strtol doesn't
     // report a over/underflow we still have to check that the returned value is
     // within the range of an *int64_t*.
     return endp && *endp == 0 && !errno &&
            n >= std::numeric_limits<int64_t>::min() &&
            n <= std::numeric_limits<int64_t>::max();
 }
 
 bool ParseUInt32(const std::string &str, uint32_t *out) {
     if (!ParsePrechecks(str)) return false;
     // Reject negative values, unfortunately strtoul accepts these by default if
     // they fit in the range
     if (str.size() >= 1 && str[0] == '-') return false;
     char *endp = nullptr;
     // strtoul will not set errno if valid
     errno = 0;
     unsigned long int n = strtoul(str.c_str(), &endp, 10);
     if (out) *out = (uint32_t)n;
     // Note that strtoul returns a *unsigned long int*, so even if it doesn't
     // report a over/underflow we still have to check that the returned value is
     // within the range of an *uint32_t*. On 64-bit platforms the size of these
     // types may be different.
     return endp && *endp == 0 && !errno &&
            n <= std::numeric_limits<uint32_t>::max();
 }
 
 bool ParseUInt64(const std::string &str, uint64_t *out) {
     if (!ParsePrechecks(str)) return false;
     // Reject negative values, unfortunately strtoull accepts these by default
     // if they fit in the range
     if (str.size() >= 1 && str[0] == '-') return false;
     char *endp = nullptr;
     // strtoull will not set errno if valid
     errno = 0;
     unsigned long long int n = strtoull(str.c_str(), &endp, 10);
     if (out) *out = (uint64_t)n;
     // Note that strtoull returns a *unsigned long long int*, so even if it
     // doesn't report a over/underflow we still have to check that the returned
     // value is within the range of an *uint64_t*.
     return endp && *endp == 0 && !errno &&
            n <= std::numeric_limits<uint64_t>::max();
 }
 
 bool ParseDouble(const std::string &str, double *out) {
     if (!ParsePrechecks(str)) return false;
     // No hexadecimal floats allowed
     if (str.size() >= 2 && str[0] == '0' && str[1] == 'x') return false;
     std::istringstream text(str);
     text.imbue(std::locale::classic());
     double result;
     text >> result;
     if (out) *out = result;
     return text.eof() && !text.fail();
 }
 
 std::string FormatParagraph(const std::string &in, size_t width,
                             size_t indent) {
     std::stringstream out;
     size_t ptr = 0;
     size_t indented = 0;
     while (ptr < in.size()) {
         size_t lineend = in.find_first_of('\n', ptr);
         if (lineend == std::string::npos) {
             lineend = in.size();
         }
         const size_t linelen = lineend - ptr;
         const size_t rem_width = width - indented;
         if (linelen <= rem_width) {
             out << in.substr(ptr, linelen + 1);
             ptr = lineend + 1;
             indented = 0;
         } else {
             size_t finalspace = in.find_last_of(" \n", ptr + rem_width);
             if (finalspace == std::string::npos || finalspace < ptr) {
                 // No place to break; just include the entire word and move on
                 finalspace = in.find_first_of("\n ", ptr);
                 if (finalspace == std::string::npos) {
                     // End of the string, just add it and break
                     out << in.substr(ptr);
                     break;
                 }
             }
             out << in.substr(ptr, finalspace - ptr) << "\n";
             if (in[finalspace] == '\n') {
                 indented = 0;
             } else if (indent) {
                 out << std::string(indent, ' ');
                 indented = indent;
             }
             ptr = finalspace + 1;
         }
     }
     return out.str();
 }
 
 std::string i64tostr(int64_t n) {
     return strprintf("%d", n);
 }
 
 std::string itostr(int n) {
     return strprintf("%d", n);
 }
 
 int64_t atoi64(const char *psz) {
 #ifdef _MSC_VER
     return _atoi64(psz);
 #else
     return strtoll(psz, nullptr, 10);
 #endif
 }
 
 int64_t atoi64(const std::string &str) {
 #ifdef _MSC_VER
     return _atoi64(str.c_str());
 #else
     return strtoll(str.c_str(), nullptr, 10);
 #endif
 }
 
 int atoi(const std::string &str) {
     return atoi(str.c_str());
 }
 
 /**
  * Upper bound for mantissa.
  * 10^18-1 is the largest arbitrary decimal that will fit in a signed 64-bit
  * integer. Larger integers cannot consist of arbitrary combinations of 0-9:
  *
  *   999999999999999999  1^18-1
  *  9223372036854775807  (1<<63)-1  (max int64_t)
  *  9999999999999999999  1^19-1     (would overflow)
  */
 static const int64_t UPPER_BOUND = 1000000000000000000LL - 1LL;
 
 /** Helper function for ParseFixedPoint */
 static inline bool ProcessMantissaDigit(char ch, int64_t &mantissa,
                                         int &mantissa_tzeros) {
     if (ch == '0')
         ++mantissa_tzeros;
     else {
         for (int i = 0; i <= mantissa_tzeros; ++i) {
             // overflow
             if (mantissa > (UPPER_BOUND / 10LL)) return false;
             mantissa *= 10;
         }
         mantissa += ch - '0';
         mantissa_tzeros = 0;
     }
     return true;
 }
 
 bool ParseFixedPoint(const std::string &val, int decimals,
                      int64_t *amount_out) {
     int64_t mantissa = 0;
     int64_t exponent = 0;
     int mantissa_tzeros = 0;
     bool mantissa_sign = false;
     bool exponent_sign = false;
     int ptr = 0;
     int end = val.size();
     int point_ofs = 0;
 
     if (ptr < end && val[ptr] == '-') {
         mantissa_sign = true;
         ++ptr;
     }
     if (ptr < end) {
         if (val[ptr] == '0') {
             // pass single 0
             ++ptr;
         } else if (val[ptr] >= '1' && val[ptr] <= '9') {
             while (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') {
                 if (!ProcessMantissaDigit(val[ptr], mantissa,
                                           mantissa_tzeros)) {
                     // overflow
                     return false;
                 }
                 ++ptr;
             }
         } else {
             // missing expected digit
             return false;
         }
     } else {
         // empty string or loose '-'
         return false;
     }
     if (ptr < end && val[ptr] == '.') {
         ++ptr;
         if (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') {
             while (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') {
                 if (!ProcessMantissaDigit(val[ptr], mantissa,
                                           mantissa_tzeros)) {
                     // overflow
                     return false;
                 }
                 ++ptr;
                 ++point_ofs;
             }
         } else {
             // missing expected digit
             return false;
         }
     }
     if (ptr < end && (val[ptr] == 'e' || val[ptr] == 'E')) {
         ++ptr;
         if (ptr < end && val[ptr] == '+')
             ++ptr;
         else if (ptr < end && val[ptr] == '-') {
             exponent_sign = true;
             ++ptr;
         }
         if (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') {
             while (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') {
                 if (exponent > (UPPER_BOUND / 10LL)) {
                     // overflow
                     return false;
                 }
                 exponent = exponent * 10 + val[ptr] - '0';
                 ++ptr;
             }
         } else {
             // missing expected digit
             return false;
         }
     }
     if (ptr != end) {
         // trailing garbage
         return false;
     }
     // finalize exponent
     if (exponent_sign) exponent = -exponent;
     exponent = exponent - point_ofs + mantissa_tzeros;
 
     // finalize mantissa
     if (mantissa_sign) mantissa = -mantissa;
 
     // convert to one 64-bit fixed-point value
     exponent += decimals;
     if (exponent < 0) {
         // cannot represent values smaller than 10^-decimals
         return false;
     }
     if (exponent >= 18) {
         // cannot represent values larger than or equal to 10^(18-decimals)
         return false;
     }
 
     for (int i = 0; i < exponent; ++i) {
         if (mantissa > (UPPER_BOUND / 10LL) ||
             mantissa < -(UPPER_BOUND / 10LL)) {
             // overflow
             return false;
         }
         mantissa *= 10;
     }
     if (mantissa > UPPER_BOUND || mantissa < -UPPER_BOUND) {
         // overflow
         return false;
     }
 
     if (amount_out) *amount_out = mantissa;
 
     return true;
 }
diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h
index bf3921543..1a1d52bc6 100644
--- a/src/utilstrencodings.h
+++ b/src/utilstrencodings.h
@@ -1,147 +1,145 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 /**
  * Utilities for converting data from/to strings.
  */
 #ifndef BITCOIN_UTILSTRENCODINGS_H
 #define BITCOIN_UTILSTRENCODINGS_H
 
 #include <cstdint>
 #include <string>
 #include <vector>
 
 #define BEGIN(a) ((char *)&(a))
 #define END(a) ((char *)&((&(a))[1]))
-#define UBEGIN(a) ((unsigned char *)&(a))
-#define UEND(a) ((unsigned char *)&((&(a))[1]))
+#define UBEGIN(a) ((uint8_t *)&(a))
+#define UEND(a) ((uint8_t *)&((&(a))[1]))
 #define ARRAYLEN(array) (sizeof(array) / sizeof((array)[0]))
 
 /** Used by SanitizeString() */
 enum SafeChars {
     //!< The full set of allowed chars
     SAFE_CHARS_DEFAULT,
     //!< BIP-0014 subset
     SAFE_CHARS_UA_COMMENT,
 };
 
 /**
  * Remove unsafe chars. Safe chars chosen to allow simple messages/URLs/email
  * addresses, but avoid anything even possibly remotely dangerous like & or >
  * @param[in] str    The string to sanitize
  * @param[in] rule   The set of safe chars to choose (default: least
  * restrictive)
  * @return           A new string without unsafe chars
  */
 std::string SanitizeString(const std::string &str,
                            int rule = SAFE_CHARS_DEFAULT);
-std::vector<unsigned char> ParseHex(const char *psz);
-std::vector<unsigned char> ParseHex(const std::string &str);
+std::vector<uint8_t> ParseHex(const char *psz);
+std::vector<uint8_t> ParseHex(const std::string &str);
 signed char HexDigit(char c);
 bool IsHex(const std::string &str);
-std::vector<unsigned char> DecodeBase64(const char *p,
-                                        bool *pfInvalid = nullptr);
+std::vector<uint8_t> DecodeBase64(const char *p, bool *pfInvalid = nullptr);
 std::string DecodeBase64(const std::string &str);
-std::string EncodeBase64(const unsigned char *pch, size_t len);
+std::string EncodeBase64(const uint8_t *pch, size_t len);
 std::string EncodeBase64(const std::string &str);
-std::vector<unsigned char> DecodeBase32(const char *p,
-                                        bool *pfInvalid = nullptr);
+std::vector<uint8_t> DecodeBase32(const char *p, bool *pfInvalid = nullptr);
 std::string DecodeBase32(const std::string &str);
-std::string EncodeBase32(const unsigned char *pch, size_t len);
+std::string EncodeBase32(const uint8_t *pch, size_t len);
 std::string EncodeBase32(const std::string &str);
 
 std::string i64tostr(int64_t n);
 std::string itostr(int n);
 int64_t atoi64(const char *psz);
 int64_t atoi64(const std::string &str);
 int atoi(const std::string &str);
 
 /**
  * Convert string to signed 32-bit integer with strict parse error feedback.
  * @returns true if the entire string could be parsed as valid integer, false if
  * not the entire string could be parsed or when overflow or underflow occurred.
  */
 bool ParseInt32(const std::string &str, int32_t *out);
 
 /**
  * Convert string to signed 64-bit integer with strict parse error feedback.
  * @returns true if the entire string could be parsed as valid integer, false if
  * not the entire string could be parsed or when overflow or underflow occurred.
  */
 bool ParseInt64(const std::string &str, int64_t *out);
 
 /**
  * Convert decimal string to unsigned 32-bit integer with strict parse error
  * feedback.
  * @returns true if the entire string could be parsed as valid integer, false if
  * not the entire string could be parsed or when overflow or underflow occurred.
  */
 bool ParseUInt32(const std::string &str, uint32_t *out);
 
 /**
  * Convert decimal string to unsigned 64-bit integer with strict parse error
  * feedback.
  * @returns true if the entire string could be parsed as valid integer, false if
  * not the entire string could be parsed or when overflow or underflow occurred.
  */
 bool ParseUInt64(const std::string &str, uint64_t *out);
 
 /**
  * Convert string to double with strict parse error feedback.
  * @returns true if the entire string could be parsed as valid double, false if
  * not the entire string could be parsed or when overflow or underflow occurred.
  */
 bool ParseDouble(const std::string &str, double *out);
 
 template <typename T>
 std::string HexStr(const T itbegin, const T itend, bool fSpaces = false) {
     std::string rv;
     static const char hexmap[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
                                     '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
     rv.reserve((itend - itbegin) * 3);
     for (T it = itbegin; it < itend; ++it) {
-        unsigned char val = (unsigned char)(*it);
+        uint8_t val = uint8_t(*it);
         if (fSpaces && it != itbegin) rv.push_back(' ');
         rv.push_back(hexmap[val >> 4]);
         rv.push_back(hexmap[val & 15]);
     }
 
     return rv;
 }
 
 template <typename T>
 inline std::string HexStr(const T &vch, bool fSpaces = false) {
     return HexStr(vch.begin(), vch.end(), fSpaces);
 }
 
 /**
  * Format a paragraph of text to a fixed width, adding spaces for indentation to
  * any added line.
  */
 std::string FormatParagraph(const std::string &in, size_t width = 79,
                             size_t indent = 0);
 
 /**
  * Timing-attack-resistant comparison.
  * Takes time proportional to length of first argument.
  */
 template <typename T> bool TimingResistantEqual(const T &a, const T &b) {
     if (b.size() == 0) return a.size() == 0;
     size_t accumulator = a.size() ^ b.size();
     for (size_t i = 0; i < a.size(); i++)
         accumulator |= a[i] ^ b[i % b.size()];
     return accumulator == 0;
 }
 
 /**
  * Parse number as fixed point according to JSON number syntax.
  * See http://json.org/number.gif
  * @returns true on success, false on error.
  * @note The result must be in the range (-10^18,10^18), otherwise an overflow
  * error will trigger.
  */
 bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out);
 
 #endif // BITCOIN_UTILSTRENCODINGS_H
diff --git a/src/validation.cpp b/src/validation.cpp
index ba196c500..ebfc3ea17 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -1,4969 +1,4969 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-2016 The Bitcoin Core developers
 // Copyright (c) 2017 The Bitcoin developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #include "validation.h"
 
 #include "arith_uint256.h"
 #include "chainparams.h"
 #include "checkpoints.h"
 #include "checkqueue.h"
 #include "config.h"
 #include "consensus/consensus.h"
 #include "consensus/merkle.h"
 #include "consensus/validation.h"
 #include "hash.h"
 #include "init.h"
 #include "policy/fees.h"
 #include "policy/policy.h"
 #include "pow.h"
 #include "primitives/block.h"
 #include "primitives/transaction.h"
 #include "random.h"
 #include "script/script.h"
 #include "script/sigcache.h"
 #include "script/standard.h"
 #include "timedata.h"
 #include "tinyformat.h"
 #include "txdb.h"
 #include "txmempool.h"
 #include "ui_interface.h"
 #include "undo.h"
 #include "util.h"
 #include "utilmoneystr.h"
 #include "utilstrencodings.h"
 #include "validationinterface.h"
 #include "versionbits.h"
 #include "warnings.h"
 
 #include <atomic>
 #include <sstream>
 
 #include <boost/algorithm/string/join.hpp>
 #include <boost/algorithm/string/replace.hpp>
 #include <boost/filesystem.hpp>
 #include <boost/filesystem/fstream.hpp>
 #include <boost/math/distributions/poisson.hpp>
 #include <boost/range/adaptor/reversed.hpp>
 #include <boost/thread.hpp>
 
 #if defined(NDEBUG)
 #error "Bitcoin cannot be compiled without assertions."
 #endif
 
 /**
  * Global state
  */
 
 CCriticalSection cs_main;
 
 BlockMap mapBlockIndex;
 CChain chainActive;
 CBlockIndex *pindexBestHeader = nullptr;
 CWaitableCriticalSection csBestBlock;
 CConditionVariable cvBlockChange;
 int nScriptCheckThreads = 0;
 std::atomic_bool fImporting(false);
 bool fReindex = false;
 bool fTxIndex = false;
 bool fHavePruned = false;
 bool fPruneMode = false;
 bool fIsBareMultisigStd = DEFAULT_PERMIT_BAREMULTISIG;
 bool fRequireStandard = true;
 bool fCheckBlockIndex = false;
 bool fCheckpointsEnabled = DEFAULT_CHECKPOINTS_ENABLED;
 size_t nCoinCacheUsage = 5000 * 300;
 uint64_t nPruneTarget = 0;
 int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE;
 
 uint256 hashAssumeValid;
 
 CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
 CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE;
 
 CTxMemPool mempool(::minRelayTxFee);
 
 static void CheckBlockIndex(const Consensus::Params &consensusParams);
 
 /** Constant stuff for coinbase transactions we create: */
 CScript COINBASE_FLAGS;
 
 const std::string strMessageMagic = "Bitcoin Signed Message:\n";
 
 // Internal stuff
 namespace {
 
 struct CBlockIndexWorkComparator {
     bool operator()(CBlockIndex *pa, CBlockIndex *pb) const {
         // First sort by most total work, ...
         if (pa->nChainWork > pb->nChainWork) return false;
         if (pa->nChainWork < pb->nChainWork) return true;
 
         // ... then by earliest time received, ...
         if (pa->nSequenceId < pb->nSequenceId) return false;
         if (pa->nSequenceId > pb->nSequenceId) return true;
 
         // Use pointer address as tie breaker (should only happen with blocks
         // loaded from disk, as those all have id 0).
         if (pa < pb) return false;
         if (pa > pb) return true;
 
         // Identical blocks.
         return false;
     }
 };
 
 CBlockIndex *pindexBestInvalid;
 
 /**
  * The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS (for itself
  * and all ancestors) and as good as our current tip or better. Entries may be
  * failed, though, and pruning nodes may be missing the data for the block.
  */
 std::set<CBlockIndex *, CBlockIndexWorkComparator> setBlockIndexCandidates;
 /**
  * All pairs A->B, where A (or one of its ancestors) misses transactions, but B
  * has transactions. Pruned nodes may have entries where B is missing data.
  */
 std::multimap<CBlockIndex *, CBlockIndex *> mapBlocksUnlinked;
 
 CCriticalSection cs_LastBlockFile;
 std::vector<CBlockFileInfo> vinfoBlockFile;
 int nLastBlockFile = 0;
 /**
  * Global flag to indicate we should check to see if there are block/undo files
  * that should be deleted. Set on startup or if we allocate more file space when
  * we're in prune mode.
  */
 bool fCheckForPruning = false;
 
 /**
  * Every received block is assigned a unique and increasing identifier, so we
  * know which one to give priority in case of a fork.
  */
 CCriticalSection cs_nBlockSequenceId;
 /** Blocks loaded from disk are assigned id 0, so start the counter at 1. */
 int32_t nBlockSequenceId = 1;
 /** Decreasing counter (used by subsequent preciousblock calls). */
 int32_t nBlockReverseSequenceId = -1;
 /** chainwork for the last block that preciousblock has been applied to. */
 arith_uint256 nLastPreciousChainwork = 0;
 
 /** Dirty block index entries. */
 std::set<CBlockIndex *> setDirtyBlockIndex;
 
 /** Dirty block file entries. */
 std::set<int> setDirtyFileInfo;
 } // anon namespace
 
 /* Use this class to start tracking transactions that are removed from the
  * mempool and pass all those transactions through SyncTransaction when the
  * object goes out of scope. This is currently only used to call SyncTransaction
  * on conflicts removed from the mempool during block connection.  Applied in
  * ActivateBestChain around ActivateBestStep which in turn calls:
  * ConnectTip->removeForBlock->removeConflicts
  */
 class MemPoolConflictRemovalTracker {
 private:
     std::vector<CTransactionRef> conflictedTxs;
     CTxMemPool &pool;
 
 public:
     MemPoolConflictRemovalTracker(CTxMemPool &_pool) : pool(_pool) {
         pool.NotifyEntryRemoved.connect(boost::bind(
             &MemPoolConflictRemovalTracker::NotifyEntryRemoved, this, _1, _2));
     }
 
     void NotifyEntryRemoved(CTransactionRef txRemoved,
                             MemPoolRemovalReason reason) {
         if (reason == MemPoolRemovalReason::CONFLICT) {
             conflictedTxs.push_back(txRemoved);
         }
     }
 
     ~MemPoolConflictRemovalTracker() {
         pool.NotifyEntryRemoved.disconnect(boost::bind(
             &MemPoolConflictRemovalTracker::NotifyEntryRemoved, this, _1, _2));
         for (const auto &tx : conflictedTxs) {
             GetMainSignals().SyncTransaction(
                 *tx, nullptr, CMainSignals::SYNC_TRANSACTION_NOT_IN_BLOCK);
         }
         conflictedTxs.clear();
     }
 };
 
 CBlockIndex *FindForkInGlobalIndex(const CChain &chain,
                                    const CBlockLocator &locator) {
     // Find the first block the caller has in the main chain
     for (const uint256 &hash : locator.vHave) {
         BlockMap::iterator mi = mapBlockIndex.find(hash);
         if (mi != mapBlockIndex.end()) {
             CBlockIndex *pindex = (*mi).second;
             if (chain.Contains(pindex)) return pindex;
             if (pindex->GetAncestor(chain.Height()) == chain.Tip()) {
                 return chain.Tip();
             }
         }
     }
     return chain.Genesis();
 }
 
 CCoinsViewCache *pcoinsTip = nullptr;
 CBlockTreeDB *pblocktree = nullptr;
 
 enum FlushStateMode {
     FLUSH_STATE_NONE,
     FLUSH_STATE_IF_NEEDED,
     FLUSH_STATE_PERIODIC,
     FLUSH_STATE_ALWAYS
 };
 
 // See definition for documentation
 static bool FlushStateToDisk(CValidationState &state, FlushStateMode mode,
                              int nManualPruneHeight = 0);
 void FindFilesToPruneManual(std::set<int> &setFilesToPrune,
                             int nManualPruneHeight);
 
 static bool IsFinalTx(const CTransaction &tx, int nBlockHeight,
                       int64_t nBlockTime) {
     if (tx.nLockTime == 0) {
         return true;
     }
 
     int64_t lockTime = tx.nLockTime;
     int64_t lockTimeLimit =
         (lockTime < LOCKTIME_THRESHOLD) ? nBlockHeight : nBlockTime;
     if (lockTime < lockTimeLimit) {
         return true;
     }
 
     for (const auto &txin : tx.vin) {
         if (txin.nSequence != CTxIn::SEQUENCE_FINAL) {
             return false;
         }
     }
     return true;
 }
 
 /**
  * Calculates the block height and previous block's median time past at
  * which the transaction will be considered final in the context of BIP 68.
  * Also removes from the vector of input heights any entries which did not
  * correspond to sequence locked inputs as they do not affect the calculation.
  */
 static std::pair<int, int64_t>
 CalculateSequenceLocks(const CTransaction &tx, int flags,
                        std::vector<int> *prevHeights,
                        const CBlockIndex &block) {
     assert(prevHeights->size() == tx.vin.size());
 
     // Will be set to the equivalent height- and time-based nLockTime
     // values that would be necessary to satisfy all relative lock-
     // time constraints given our view of block chain history.
     // The semantics of nLockTime are the last invalid height/time, so
     // use -1 to have the effect of any height or time being valid.
     int nMinHeight = -1;
     int64_t nMinTime = -1;
 
     // tx.nVersion is signed integer so requires cast to unsigned otherwise
     // we would be doing a signed comparison and half the range of nVersion
     // wouldn't support BIP 68.
     bool fEnforceBIP68 = static_cast<uint32_t>(tx.nVersion) >= 2 &&
                          flags & LOCKTIME_VERIFY_SEQUENCE;
 
     // Do not enforce sequence numbers as a relative lock time
     // unless we have been instructed to
     if (!fEnforceBIP68) {
         return std::make_pair(nMinHeight, nMinTime);
     }
 
     for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) {
         const CTxIn &txin = tx.vin[txinIndex];
 
         // Sequence numbers with the most significant bit set are not
         // treated as relative lock-times, nor are they given any
         // consensus-enforced meaning at this point.
         if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) {
             // The height of this input is not relevant for sequence locks
             (*prevHeights)[txinIndex] = 0;
             continue;
         }
 
         int nCoinHeight = (*prevHeights)[txinIndex];
 
         if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) {
             int64_t nCoinTime = block.GetAncestor(std::max(nCoinHeight - 1, 0))
                                     ->GetMedianTimePast();
             // NOTE: Subtract 1 to maintain nLockTime semantics.
             // BIP 68 relative lock times have the semantics of calculating the
             // first block or time at which the transaction would be valid. When
             // calculating the effective block time or height for the entire
             // transaction, we switch to using the semantics of nLockTime which
             // is the last invalid block time or height. Thus we subtract 1 from
             // the calculated time or height.
 
             // Time-based relative lock-times are measured from the smallest
             // allowed timestamp of the block containing the txout being spent,
             // which is the median time past of the block prior.
             nMinTime = std::max(
                 nMinTime,
                 nCoinTime +
                     (int64_t)((txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK)
                               << CTxIn::SEQUENCE_LOCKTIME_GRANULARITY) -
                     1);
         } else {
             nMinHeight = std::max(
                 nMinHeight,
                 nCoinHeight +
                     (int)(txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) - 1);
         }
     }
 
     return std::make_pair(nMinHeight, nMinTime);
 }
 
 static bool EvaluateSequenceLocks(const CBlockIndex &block,
                                   std::pair<int, int64_t> lockPair) {
     assert(block.pprev);
     int64_t nBlockTime = block.pprev->GetMedianTimePast();
     if (lockPair.first >= block.nHeight || lockPair.second >= nBlockTime)
         return false;
 
     return true;
 }
 
 bool SequenceLocks(const CTransaction &tx, int flags,
                    std::vector<int> *prevHeights, const CBlockIndex &block) {
     return EvaluateSequenceLocks(
         block, CalculateSequenceLocks(tx, flags, prevHeights, block));
 }
 
 bool TestLockPointValidity(const LockPoints *lp) {
     AssertLockHeld(cs_main);
     assert(lp);
     // If there are relative lock times then the maxInputBlock will be set
     // If there are no relative lock times, the LockPoints don't depend on the
     // chain
     if (lp->maxInputBlock) {
         // Check whether chainActive is an extension of the block at which the
         // LockPoints
         // calculation was valid.  If not LockPoints are no longer valid
         if (!chainActive.Contains(lp->maxInputBlock)) {
             return false;
         }
     }
 
     // LockPoints still valid
     return true;
 }
 
 bool CheckSequenceLocks(const CTransaction &tx, int flags, LockPoints *lp,
                         bool useExistingLockPoints) {
     AssertLockHeld(cs_main);
     AssertLockHeld(mempool.cs);
 
     CBlockIndex *tip = chainActive.Tip();
     CBlockIndex index;
     index.pprev = tip;
     // CheckSequenceLocks() uses chainActive.Height()+1 to evaluate height based
     // locks because when SequenceLocks() is called within ConnectBlock(), the
     // height of the block *being* evaluated is what is used. Thus if we want to
     // know if a transaction can be part of the *next* block, we need to use one
     // more than chainActive.Height()
     index.nHeight = tip->nHeight + 1;
 
     std::pair<int, int64_t> lockPair;
     if (useExistingLockPoints) {
         assert(lp);
         lockPair.first = lp->height;
         lockPair.second = lp->time;
     } else {
         // pcoinsTip contains the UTXO set for chainActive.Tip()
         CCoinsViewMemPool viewMemPool(pcoinsTip, mempool);
         std::vector<int> prevheights;
         prevheights.resize(tx.vin.size());
         for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) {
             const CTxIn &txin = tx.vin[txinIndex];
             Coin coin;
             if (!viewMemPool.GetCoin(txin.prevout, coin)) {
                 return error("%s: Missing input", __func__);
             }
             if (coin.GetHeight() == MEMPOOL_HEIGHT) {
                 // Assume all mempool transaction confirm in the next block
                 prevheights[txinIndex] = tip->nHeight + 1;
             } else {
                 prevheights[txinIndex] = coin.GetHeight();
             }
         }
         lockPair = CalculateSequenceLocks(tx, flags, &prevheights, index);
         if (lp) {
             lp->height = lockPair.first;
             lp->time = lockPair.second;
             // Also store the hash of the block with the highest height of all
             // the blocks which have sequence locked prevouts. This hash needs
             // to still be on the chain for these LockPoint calculations to be
             // valid.
             // Note: It is impossible to correctly calculate a maxInputBlock if
             // any of the sequence locked inputs depend on unconfirmed txs,
             // except in the special case where the relative lock time/height is
             // 0, which is equivalent to no sequence lock. Since we assume input
             // height of tip+1 for mempool txs and test the resulting lockPair
             // from CalculateSequenceLocks against tip+1. We know
             // EvaluateSequenceLocks will fail if there was a non-zero sequence
             // lock on a mempool input, so we can use the return value of
             // CheckSequenceLocks to indicate the LockPoints validity
             int maxInputHeight = 0;
             for (int height : prevheights) {
                 // Can ignore mempool inputs since we'll fail if they had
                 // non-zero locks
                 if (height != tip->nHeight + 1) {
                     maxInputHeight = std::max(maxInputHeight, height);
                 }
             }
             lp->maxInputBlock = tip->GetAncestor(maxInputHeight);
         }
     }
     return EvaluateSequenceLocks(index, lockPair);
 }
 
 uint64_t GetSigOpCountWithoutP2SH(const CTransaction &tx) {
     uint64_t nSigOps = 0;
     for (const auto &txin : tx.vin) {
         nSigOps += txin.scriptSig.GetSigOpCount(false);
     }
     for (const auto &txout : tx.vout) {
         nSigOps += txout.scriptPubKey.GetSigOpCount(false);
     }
     return nSigOps;
 }
 
 uint64_t GetP2SHSigOpCount(const CTransaction &tx,
                            const CCoinsViewCache &inputs) {
     if (tx.IsCoinBase()) {
         return 0;
     }
 
     uint64_t nSigOps = 0;
     for (unsigned int i = 0; i < tx.vin.size(); i++) {
         const CTxOut &prevout = inputs.GetOutputFor(tx.vin[i]);
         if (prevout.scriptPubKey.IsPayToScriptHash())
             nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
     }
     return nSigOps;
 }
 
 uint64_t GetTransactionSigOpCount(const CTransaction &tx,
                                   const CCoinsViewCache &inputs, int flags) {
     uint64_t nSigOps = GetSigOpCountWithoutP2SH(tx);
     if (tx.IsCoinBase()) {
         return nSigOps;
     }
 
     if (flags & SCRIPT_VERIFY_P2SH) {
         nSigOps += GetP2SHSigOpCount(tx, inputs);
     }
 
     return nSigOps;
 }
 
 static bool CheckTransactionCommon(const CTransaction &tx,
                                    CValidationState &state,
                                    bool fCheckDuplicateInputs) {
     // Basic checks that don't depend on any context
     if (tx.vin.empty()) {
         return state.DoS(10, false, REJECT_INVALID, "bad-txns-vin-empty");
     }
 
     if (tx.vout.empty()) {
         return state.DoS(10, false, REJECT_INVALID, "bad-txns-vout-empty");
     }
 
     // Size limit
     if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_TX_SIZE) {
         return state.DoS(100, false, REJECT_INVALID, "bad-txns-oversize");
     }
 
     // Check for negative or overflow output values
     CAmount nValueOut = 0;
     for (const auto &txout : tx.vout) {
         if (txout.nValue < 0) {
             return state.DoS(100, false, REJECT_INVALID,
                              "bad-txns-vout-negative");
         }
 
         if (txout.nValue > MAX_MONEY) {
             return state.DoS(100, false, REJECT_INVALID,
                              "bad-txns-vout-toolarge");
         }
 
         nValueOut += txout.nValue;
         if (!MoneyRange(nValueOut)) {
             return state.DoS(100, false, REJECT_INVALID,
                              "bad-txns-txouttotal-toolarge");
         }
     }
 
     if (GetSigOpCountWithoutP2SH(tx) > MAX_TX_SIGOPS_COUNT) {
         return state.DoS(100, false, REJECT_INVALID, "bad-txn-sigops");
     }
 
     // Check for duplicate inputs - note that this check is slow so we skip it
     // in CheckBlock
     if (fCheckDuplicateInputs) {
         std::set<COutPoint> vInOutPoints;
         for (const auto &txin : tx.vin) {
             if (!vInOutPoints.insert(txin.prevout).second) {
                 return state.DoS(100, false, REJECT_INVALID,
                                  "bad-txns-inputs-duplicate");
             }
         }
     }
 
     return true;
 }
 
 bool CheckCoinbase(const CTransaction &tx, CValidationState &state,
                    bool fCheckDuplicateInputs) {
     if (!tx.IsCoinBase()) {
         return state.DoS(100, false, REJECT_INVALID, "bad-cb-missing", false,
                          "first tx is not coinbase");
     }
 
     if (!CheckTransactionCommon(tx, state, fCheckDuplicateInputs)) {
         // CheckTransactionCommon fill in the state.
         return false;
     }
 
     if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100) {
         return state.DoS(100, false, REJECT_INVALID, "bad-cb-length");
     }
 
     return true;
 }
 
 bool CheckRegularTransaction(const CTransaction &tx, CValidationState &state,
                              bool fCheckDuplicateInputs) {
     if (tx.IsCoinBase()) {
         return state.DoS(100, false, REJECT_INVALID, "bad-tx-coinbase");
     }
 
     if (!CheckTransactionCommon(tx, state, fCheckDuplicateInputs)) {
         // CheckTransactionCommon fill in the state.
         return false;
     }
 
     for (const auto &txin : tx.vin) {
         if (txin.prevout.IsNull()) {
             return state.DoS(10, false, REJECT_INVALID,
                              "bad-txns-prevout-null");
         }
     }
 
     return true;
 }
 
 void LimitMempoolSize(CTxMemPool &pool, size_t limit, unsigned long age) {
     int expired = pool.Expire(GetTime() - age);
     if (expired != 0) {
         LogPrint("mempool", "Expired %i transactions from the memory pool\n",
                  expired);
     }
 
     std::vector<COutPoint> vNoSpendsRemaining;
     pool.TrimToSize(limit, &vNoSpendsRemaining);
     for (const COutPoint &removed : vNoSpendsRemaining) {
         pcoinsTip->Uncache(removed);
     }
 }
 
 /** Convert CValidationState to a human-readable message for logging */
 std::string FormatStateMessage(const CValidationState &state) {
     return strprintf(
         "%s%s (code %i)", state.GetRejectReason(),
         state.GetDebugMessage().empty() ? "" : ", " + state.GetDebugMessage(),
         state.GetRejectCode());
 }
 
 static bool IsCurrentForFeeEstimation() {
     AssertLockHeld(cs_main);
     if (IsInitialBlockDownload()) {
         return false;
     }
     if (chainActive.Tip()->GetBlockTime() <
         (GetTime() - MAX_FEE_ESTIMATION_TIP_AGE)) {
         return false;
     }
     if (chainActive.Height() < pindexBestHeader->nHeight - 1) {
         return false;
     }
     return true;
 }
 
 static bool IsUAHFenabled(const Config &config, int64_t nMedianTimePast) {
     return nMedianTimePast >= config.GetUAHFStartTime();
 }
 
 bool IsUAHFenabled(const Config &config, const CBlockIndex *pindexPrev) {
     if (pindexPrev == nullptr) {
         return false;
     }
 
     return IsUAHFenabled(config, pindexPrev->GetMedianTimePast());
 }
 
 bool IsUAHFenabledForCurrentBlock(const Config &config) {
     AssertLockHeld(cs_main);
     return IsUAHFenabled(config, chainActive.Tip());
 }
 
 static bool AcceptToMemoryPoolWorker(
     const Config &config, CTxMemPool &pool, CValidationState &state,
     const CTransactionRef &ptx, bool fLimitFree, bool *pfMissingInputs,
     int64_t nAcceptTime, std::list<CTransactionRef> *plTxnReplaced,
     bool fOverrideMempoolLimit, const CAmount &nAbsurdFee,
     std::vector<COutPoint> &coins_to_uncache) {
     AssertLockHeld(cs_main);
 
     const CTransaction &tx = *ptx;
     const uint256 txid = tx.GetId();
     if (pfMissingInputs) {
         *pfMissingInputs = false;
     }
 
     // Coinbase is only valid in a block, not as a loose transaction.
     if (!CheckRegularTransaction(tx, state, true)) {
         // state filled in by CheckRegularTransaction.
         return false;
     }
 
     // Rather not work on nonstandard transactions (unless -testnet/-regtest)
     std::string reason;
     if (fRequireStandard && !IsStandardTx(tx, reason)) {
         return state.DoS(0, false, REJECT_NONSTANDARD, reason);
     }
 
     // Only accept nLockTime-using transactions that can be mined in the next
     // block; we don't want our mempool filled up with transactions that can't
     // be mined yet.
     CValidationState ctxState;
     if (!ContextualCheckTransactionForCurrentBlock(
             config, tx, ctxState, config.GetChainParams().GetConsensus(),
             STANDARD_LOCKTIME_VERIFY_FLAGS)) {
         // We copy the state from a dummy to ensure we don't increase the
         // ban score of peer for transaction that could be valid in the future.
         return state.DoS(
             0, false, REJECT_NONSTANDARD, ctxState.GetRejectReason(),
             ctxState.CorruptionPossible(), ctxState.GetDebugMessage());
     }
 
     // Is it already in the memory pool?
     if (pool.exists(txid)) {
         return state.Invalid(false, REJECT_ALREADY_KNOWN,
                              "txn-already-in-mempool");
     }
 
     // Check for conflicts with in-memory transactions
     {
         // Protect pool.mapNextTx
         LOCK(pool.cs);
         for (const CTxIn &txin : tx.vin) {
             auto itConflicting = pool.mapNextTx.find(txin.prevout);
             if (itConflicting != pool.mapNextTx.end()) {
                 // Disable replacement feature for good
                 return state.Invalid(false, REJECT_CONFLICT,
                                      "txn-mempool-conflict");
             }
         }
     }
 
     {
         CCoinsView dummy;
         CCoinsViewCache view(&dummy);
 
         CAmount nValueIn = 0;
         LockPoints lp;
         {
             LOCK(pool.cs);
             CCoinsViewMemPool viewMemPool(pcoinsTip, pool);
             view.SetBackend(viewMemPool);
 
             // Do we already have it?
             for (size_t out = 0; out < tx.vout.size(); out++) {
                 COutPoint outpoint(txid, out);
                 bool had_coin_in_cache = pcoinsTip->HaveCoinInCache(outpoint);
                 if (view.HaveCoin(outpoint)) {
                     if (!had_coin_in_cache) {
                         coins_to_uncache.push_back(outpoint);
                     }
 
                     return state.Invalid(false, REJECT_ALREADY_KNOWN,
                                          "txn-already-known");
                 }
             }
 
             // Do all inputs exist?
             for (const CTxIn txin : tx.vin) {
                 if (!pcoinsTip->HaveCoinInCache(txin.prevout)) {
                     coins_to_uncache.push_back(txin.prevout);
                 }
 
                 if (!view.HaveCoin(txin.prevout)) {
                     if (pfMissingInputs) {
                         *pfMissingInputs = true;
                     }
 
                     // fMissingInputs and !state.IsInvalid() is used to detect
                     // this condition, don't set state.Invalid()
                     return false;
                 }
             }
 
             // Are the actual inputs available?
             if (!view.HaveInputs(tx)) {
                 return state.Invalid(false, REJECT_DUPLICATE,
                                      "bad-txns-inputs-spent");
             }
 
             // Bring the best block into scope.
             view.GetBestBlock();
 
             nValueIn = view.GetValueIn(tx);
 
             // We have all inputs cached now, so switch back to dummy, so we
             // don't need to keep lock on mempool.
             view.SetBackend(dummy);
 
             // Only accept BIP68 sequence locked transactions that can be mined
             // in the next block; we don't want our mempool filled up with
             // transactions that can't be mined yet. Must keep pool.cs for this
             // unless we change CheckSequenceLocks to take a CoinsViewCache
             // instead of create its own.
             if (!CheckSequenceLocks(tx, STANDARD_LOCKTIME_VERIFY_FLAGS, &lp)) {
                 return state.DoS(0, false, REJECT_NONSTANDARD,
                                  "non-BIP68-final");
             }
         }
 
         // Check for non-standard pay-to-script-hash in inputs
         if (fRequireStandard && !AreInputsStandard(tx, view)) {
             return state.Invalid(false, REJECT_NONSTANDARD,
                                  "bad-txns-nonstandard-inputs");
         }
 
         int64_t nSigOpsCount =
             GetTransactionSigOpCount(tx, view, STANDARD_SCRIPT_VERIFY_FLAGS);
 
         CAmount nValueOut = tx.GetValueOut();
         CAmount nFees = nValueIn - nValueOut;
         // nModifiedFees includes any fee deltas from PrioritiseTransaction
         CAmount nModifiedFees = nFees;
         double nPriorityDummy = 0;
         pool.ApplyDeltas(txid, nPriorityDummy, nModifiedFees);
 
         CAmount inChainInputValue;
         double dPriority =
             view.GetPriority(tx, chainActive.Height(), inChainInputValue);
 
         // Keep track of transactions that spend a coinbase, which we re-scan
         // during reorgs to ensure COINBASE_MATURITY is still met.
         bool fSpendsCoinbase = false;
         for (const CTxIn &txin : tx.vin) {
             const Coin &coin = view.AccessCoin(txin.prevout);
             if (coin.IsCoinBase()) {
                 fSpendsCoinbase = true;
                 break;
             }
         }
 
         CTxMemPoolEntry entry(ptx, nFees, nAcceptTime, dPriority,
                               chainActive.Height(), inChainInputValue,
                               fSpendsCoinbase, nSigOpsCount, lp);
         unsigned int nSize = entry.GetTxSize();
 
         // Check that the transaction doesn't have an excessive number of
         // sigops, making it impossible to mine. Since the coinbase transaction
         // itself can contain sigops MAX_STANDARD_TX_SIGOPS is less than
         // MAX_BLOCK_SIGOPS_PER_MB; we still consider this an invalid rather
         // than merely non-standard transaction.
         if (nSigOpsCount > MAX_STANDARD_TX_SIGOPS) {
             return state.DoS(0, false, REJECT_NONSTANDARD,
                              "bad-txns-too-many-sigops", false,
                              strprintf("%d", nSigOpsCount));
         }
 
         CAmount mempoolRejectFee =
             pool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) *
                            1000000)
                 .GetFee(nSize);
         if (mempoolRejectFee > 0 && nModifiedFees < mempoolRejectFee) {
             return state.DoS(0, false, REJECT_INSUFFICIENTFEE,
                              "mempool min fee not met", false,
                              strprintf("%d < %d", nFees, mempoolRejectFee));
         } else if (GetBoolArg("-relaypriority", DEFAULT_RELAYPRIORITY) &&
                    nModifiedFees < ::minRelayTxFee.GetFee(nSize) &&
                    !AllowFree(entry.GetPriority(chainActive.Height() + 1))) {
             // Require that free transactions have sufficient priority to be
             // mined in the next block.
             return state.DoS(0, false, REJECT_INSUFFICIENTFEE,
                              "insufficient priority");
         }
 
         // Continuously rate-limit free (really, very-low-fee) transactions.
         // This mitigates 'penny-flooding' -- sending thousands of free
         // transactions just to be annoying or make others' transactions take
         // longer to confirm.
         if (fLimitFree && nModifiedFees < ::minRelayTxFee.GetFee(nSize)) {
             static CCriticalSection csFreeLimiter;
             static double dFreeCount;
             static int64_t nLastTime;
             int64_t nNow = GetTime();
 
             LOCK(csFreeLimiter);
 
             // Use an exponentially decaying ~10-minute window:
             dFreeCount *= pow(1.0 - 1.0 / 600.0, (double)(nNow - nLastTime));
             nLastTime = nNow;
             // -limitfreerelay unit is thousand-bytes-per-minute
             // At default rate it would take over a month to fill 1GB
             if (dFreeCount + nSize >=
                 GetArg("-limitfreerelay", DEFAULT_LIMITFREERELAY) * 10 * 1000) {
                 return state.DoS(0, false, REJECT_INSUFFICIENTFEE,
                                  "rate limited free transaction");
             }
 
             LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount,
                      dFreeCount + nSize);
             dFreeCount += nSize;
         }
 
         if (nAbsurdFee && nFees > nAbsurdFee) {
             return state.Invalid(false, REJECT_HIGHFEE, "absurdly-high-fee",
                                  strprintf("%d > %d", nFees, nAbsurdFee));
         }
 
         // Calculate in-mempool ancestors, up to a limit.
         CTxMemPool::setEntries setAncestors;
         size_t nLimitAncestors =
             GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT);
         size_t nLimitAncestorSize =
             GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT) * 1000;
         size_t nLimitDescendants =
             GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT);
         size_t nLimitDescendantSize =
             GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) *
             1000;
         std::string errString;
         if (!pool.CalculateMemPoolAncestors(
                 entry, setAncestors, nLimitAncestors, nLimitAncestorSize,
                 nLimitDescendants, nLimitDescendantSize, errString)) {
             return state.DoS(0, false, REJECT_NONSTANDARD,
                              "too-long-mempool-chain", false, errString);
         }
 
         uint32_t scriptVerifyFlags =
             STANDARD_SCRIPT_VERIFY_FLAGS | SCRIPT_ENABLE_SIGHASH_FORKID;
         if (!Params().RequireStandard()) {
             scriptVerifyFlags =
                 GetArg("-promiscuousmempoolflags", scriptVerifyFlags);
         }
 
         // Check against previous transactions. This is done last to help
         // prevent CPU exhaustion denial-of-service attacks.
         PrecomputedTransactionData txdata(tx);
         if (!CheckInputs(tx, state, view, true, scriptVerifyFlags, true,
                          txdata)) {
             // State filled in by CheckInputs.
             return false;
         }
 
         // Check again against just the consensus-critical mandatory script
         // verification flags, in case of bugs in the standard flags that cause
         // transactions to pass as valid when they're actually invalid. For
         // instance the STRICTENC flag was incorrectly allowing certain
         // CHECKSIG NOT scripts to pass, even though they were invalid.
         //
         // There is a similar check in CreateNewBlock() to prevent creating
         // invalid blocks, however allowing such transactions into the mempool
         // can be exploited as a DoS attack.
         //
         // SCRIPT_ENABLE_SIGHASH_FORKID is also added as to ensure we do not
         // filter out transactions using the antireplay feature.
         {
             if (!CheckInputs(tx, state, view, true,
                              MANDATORY_SCRIPT_VERIFY_FLAGS |
                                  SCRIPT_ENABLE_SIGHASH_FORKID,
                              true, txdata)) {
                 return error(
                     "%s: BUG! PLEASE REPORT THIS! ConnectInputs failed "
                     "against MANDATORY but not STANDARD flags %s, %s",
                     __func__, txid.ToString(), FormatStateMessage(state));
             }
         }
 
         // This transaction should only count for fee estimation if
         // the node is not behind and it is not dependent on any other
         // transactions in the mempool.
         bool validForFeeEstimation =
             IsCurrentForFeeEstimation() && pool.HasNoInputsOf(tx);
 
         // Store transaction in memory.
         pool.addUnchecked(txid, entry, setAncestors, validForFeeEstimation);
 
         // Trim mempool and check if tx was trimmed.
         if (!fOverrideMempoolLimit) {
             LimitMempoolSize(
                 pool, GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000,
                 GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
             if (!pool.exists(txid))
                 return state.DoS(0, false, REJECT_INSUFFICIENTFEE,
                                  "mempool full");
         }
     }
 
     GetMainSignals().SyncTransaction(
         tx, nullptr, CMainSignals::SYNC_TRANSACTION_NOT_IN_BLOCK);
 
     return true;
 }
 
 static bool AcceptToMemoryPoolWithTime(
     const Config &config, CTxMemPool &pool, CValidationState &state,
     const CTransactionRef &tx, bool fLimitFree, bool *pfMissingInputs,
     int64_t nAcceptTime, std::list<CTransactionRef> *plTxnReplaced = nullptr,
     bool fOverrideMempoolLimit = false, const CAmount nAbsurdFee = 0) {
     std::vector<COutPoint> coins_to_uncache;
     bool res = AcceptToMemoryPoolWorker(
         config, pool, state, tx, fLimitFree, pfMissingInputs, nAcceptTime,
         plTxnReplaced, fOverrideMempoolLimit, nAbsurdFee, coins_to_uncache);
     if (!res) {
         for (const COutPoint &outpoint : coins_to_uncache) {
             pcoinsTip->Uncache(outpoint);
         }
     }
 
     // After we've (potentially) uncached entries, ensure our coins cache is
     // still within its size limits
     CValidationState stateDummy;
     FlushStateToDisk(stateDummy, FLUSH_STATE_PERIODIC);
     return res;
 }
 
 bool AcceptToMemoryPool(const Config &config, CTxMemPool &pool,
                         CValidationState &state, const CTransactionRef &tx,
                         bool fLimitFree, bool *pfMissingInputs,
                         std::list<CTransactionRef> *plTxnReplaced,
                         bool fOverrideMempoolLimit, const CAmount nAbsurdFee) {
     return AcceptToMemoryPoolWithTime(config, pool, state, tx, fLimitFree,
                                       pfMissingInputs, GetTime(), plTxnReplaced,
                                       fOverrideMempoolLimit, nAbsurdFee);
 }
 
 /** Return transaction in txOut, and if it was found inside a block, its hash is
  * placed in hashBlock */
 bool GetTransaction(const Config &config, const uint256 &txid,
                     CTransactionRef &txOut, uint256 &hashBlock,
                     bool fAllowSlow) {
     CBlockIndex *pindexSlow = nullptr;
 
     LOCK(cs_main);
 
     CTransactionRef ptx = mempool.get(txid);
     if (ptx) {
         txOut = ptx;
         return true;
     }
 
     if (fTxIndex) {
         CDiskTxPos postx;
         if (pblocktree->ReadTxIndex(txid, postx)) {
             CAutoFile file(OpenBlockFile(postx, true), SER_DISK,
                            CLIENT_VERSION);
             if (file.IsNull())
                 return error("%s: OpenBlockFile failed", __func__);
             CBlockHeader header;
             try {
                 file >> header;
                 fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
                 file >> txOut;
             } catch (const std::exception &e) {
                 return error("%s: Deserialize or I/O error - %s", __func__,
                              e.what());
             }
             hashBlock = header.GetHash();
             if (txOut->GetId() != txid)
                 return error("%s: txid mismatch", __func__);
             return true;
         }
     }
 
     // use coin database to locate block that contains transaction, and scan it
     if (fAllowSlow) {
         const Coin &coin = AccessByTxid(*pcoinsTip, txid);
         if (!coin.IsSpent()) {
             pindexSlow = chainActive[coin.GetHeight()];
         }
     }
 
     if (pindexSlow) {
         auto &params = config.GetChainParams().GetConsensus();
 
         CBlock block;
         if (ReadBlockFromDisk(block, pindexSlow, params)) {
             for (const auto &tx : block.vtx) {
                 if (tx->GetId() == txid) {
                     txOut = tx;
                     hashBlock = pindexSlow->GetBlockHash();
                     return true;
                 }
             }
         }
     }
 
     return false;
 }
 
 //////////////////////////////////////////////////////////////////////////////
 //
 // CBlock and CBlockIndex
 //
 
 bool WriteBlockToDisk(const CBlock &block, CDiskBlockPos &pos,
                       const CMessageHeader::MessageStartChars &messageStart) {
     // Open history file to append
     CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
     if (fileout.IsNull())
         return error("WriteBlockToDisk: OpenBlockFile failed");
 
     // Write index header
     unsigned int nSize = GetSerializeSize(fileout, block);
     fileout << FLATDATA(messageStart) << nSize;
 
     // Write block
     long fileOutPos = ftell(fileout.Get());
     if (fileOutPos < 0) return error("WriteBlockToDisk: ftell failed");
     pos.nPos = (unsigned int)fileOutPos;
     fileout << block;
 
     return true;
 }
 
 bool ReadBlockFromDisk(CBlock &block, const CDiskBlockPos &pos,
                        const Consensus::Params &consensusParams) {
     block.SetNull();
 
     // Open history file to read
     CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
     if (filein.IsNull())
         return error("ReadBlockFromDisk: OpenBlockFile failed for %s",
                      pos.ToString());
 
     // Read block
     try {
         filein >> block;
     } catch (const std::exception &e) {
         return error("%s: Deserialize or I/O error - %s at %s", __func__,
                      e.what(), pos.ToString());
     }
 
     // Check the header
     if (!CheckProofOfWork(block.GetHash(), block.nBits, consensusParams))
         return error("ReadBlockFromDisk: Errors in block header at %s",
                      pos.ToString());
 
     return true;
 }
 
 bool ReadBlockFromDisk(CBlock &block, const CBlockIndex *pindex,
                        const Consensus::Params &consensusParams) {
     if (!ReadBlockFromDisk(block, pindex->GetBlockPos(), consensusParams))
         return false;
     if (block.GetHash() != pindex->GetBlockHash())
         return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() "
                      "doesn't match index for %s at %s",
                      pindex->ToString(), pindex->GetBlockPos().ToString());
     return true;
 }
 
 CAmount GetBlockSubsidy(int nHeight, const Consensus::Params &consensusParams) {
     int halvings = nHeight / consensusParams.nSubsidyHalvingInterval;
     // Force block reward to zero when right shift is undefined.
     if (halvings >= 64) return 0;
 
     CAmount nSubsidy = 50 * COIN;
     // Subsidy is cut in half every 210,000 blocks which will occur
     // approximately every 4 years.
     nSubsidy >>= halvings;
     return nSubsidy;
 }
 
 bool IsInitialBlockDownload() {
     const CChainParams &chainParams = Params();
 
     // Once this function has returned false, it must remain false.
     static std::atomic<bool> latchToFalse{false};
     // Optimization: pre-test latch before taking the lock.
     if (latchToFalse.load(std::memory_order_relaxed)) return false;
 
     LOCK(cs_main);
     if (latchToFalse.load(std::memory_order_relaxed)) return false;
     if (fImporting || fReindex) return true;
     if (chainActive.Tip() == nullptr) return true;
     if (chainActive.Tip()->nChainWork <
         UintToArith256(chainParams.GetConsensus().nMinimumChainWork))
         return true;
     if (chainActive.Tip()->GetBlockTime() < (GetTime() - nMaxTipAge))
         return true;
     latchToFalse.store(true, std::memory_order_relaxed);
     return false;
 }
 
 CBlockIndex *pindexBestForkTip = nullptr, *pindexBestForkBase = nullptr;
 
 static void AlertNotify(const std::string &strMessage) {
     uiInterface.NotifyAlertChanged();
     std::string strCmd = GetArg("-alertnotify", "");
     if (strCmd.empty()) return;
 
     // Alert text should be plain ascii coming from a trusted source, but to be
     // safe we first strip anything not in safeChars, then add single quotes
     // around the whole string before passing it to the shell:
     std::string singleQuote("'");
     std::string safeStatus = SanitizeString(strMessage);
     safeStatus = singleQuote + safeStatus + singleQuote;
     boost::replace_all(strCmd, "%s", safeStatus);
 
     boost::thread t(runCommand, strCmd); // thread runs free
 }
 
 void CheckForkWarningConditions() {
     AssertLockHeld(cs_main);
     // Before we get past initial download, we cannot reliably alert about forks
     // (we assume we don't get stuck on a fork before finishing our initial
     // sync)
     if (IsInitialBlockDownload()) return;
 
     // If our best fork is no longer within 72 blocks (+/- 12 hours if no one
     // mines it) of our head, drop it
     if (pindexBestForkTip &&
         chainActive.Height() - pindexBestForkTip->nHeight >= 72)
         pindexBestForkTip = nullptr;
 
     if (pindexBestForkTip ||
         (pindexBestInvalid &&
          pindexBestInvalid->nChainWork >
              chainActive.Tip()->nChainWork +
                  (GetBlockProof(*chainActive.Tip()) * 6))) {
         if (!GetfLargeWorkForkFound() && pindexBestForkBase) {
             std::string warning =
                 std::string("'Warning: Large-work fork detected, forking after "
                             "block ") +
                 pindexBestForkBase->phashBlock->ToString() + std::string("'");
             AlertNotify(warning);
         }
         if (pindexBestForkTip && pindexBestForkBase) {
             LogPrintf("%s: Warning: Large valid fork found\n  forking the "
                       "chain at height %d (%s)\n  lasting to height %d "
                       "(%s).\nChain state database corruption likely.\n",
                       __func__, pindexBestForkBase->nHeight,
                       pindexBestForkBase->phashBlock->ToString(),
                       pindexBestForkTip->nHeight,
                       pindexBestForkTip->phashBlock->ToString());
             SetfLargeWorkForkFound(true);
         } else {
             LogPrintf("%s: Warning: Found invalid chain at least ~6 blocks "
                       "longer than our best chain.\nChain state database "
                       "corruption likely.\n",
                       __func__);
             SetfLargeWorkInvalidChainFound(true);
         }
     } else {
         SetfLargeWorkForkFound(false);
         SetfLargeWorkInvalidChainFound(false);
     }
 }
 
 void CheckForkWarningConditionsOnNewFork(CBlockIndex *pindexNewForkTip) {
     AssertLockHeld(cs_main);
     // If we are on a fork that is sufficiently large, set a warning flag
     CBlockIndex *pfork = pindexNewForkTip;
     CBlockIndex *plonger = chainActive.Tip();
     while (pfork && pfork != plonger) {
         while (plonger && plonger->nHeight > pfork->nHeight)
             plonger = plonger->pprev;
         if (pfork == plonger) break;
         pfork = pfork->pprev;
     }
 
     // We define a condition where we should warn the user about as a fork of at
     // least 7 blocks with a tip within 72 blocks (+/- 12 hours if no one mines
     // it) of ours. We use 7 blocks rather arbitrarily as it represents just
     // under 10% of sustained network hash rate operating on the fork, or a
     // chain that is entirely longer than ours and invalid (note that this
     // should be detected by both). We define it this way because it allows us
     // to only store the highest fork tip (+ base) which meets the 7-block
     // condition and from this always have the most-likely-to-cause-warning fork
     if (pfork && (!pindexBestForkTip ||
                   (pindexBestForkTip &&
                    pindexNewForkTip->nHeight > pindexBestForkTip->nHeight)) &&
         pindexNewForkTip->nChainWork - pfork->nChainWork >
             (GetBlockProof(*pfork) * 7) &&
         chainActive.Height() - pindexNewForkTip->nHeight < 72) {
         pindexBestForkTip = pindexNewForkTip;
         pindexBestForkBase = pfork;
     }
 
     CheckForkWarningConditions();
 }
 
 static void InvalidChainFound(CBlockIndex *pindexNew) {
     if (!pindexBestInvalid ||
         pindexNew->nChainWork > pindexBestInvalid->nChainWork)
         pindexBestInvalid = pindexNew;
 
     LogPrintf(
         "%s: invalid block=%s  height=%d  log2_work=%.8g  date=%s\n", __func__,
         pindexNew->GetBlockHash().ToString(), pindexNew->nHeight,
         log(pindexNew->nChainWork.getdouble()) / log(2.0),
         DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexNew->GetBlockTime()));
     CBlockIndex *tip = chainActive.Tip();
     assert(tip);
     LogPrintf("%s:  current best=%s  height=%d  log2_work=%.8g  date=%s\n",
               __func__, tip->GetBlockHash().ToString(), chainActive.Height(),
               log(tip->nChainWork.getdouble()) / log(2.0),
               DateTimeStrFormat("%Y-%m-%d %H:%M:%S", tip->GetBlockTime()));
     CheckForkWarningConditions();
 }
 
 static void InvalidBlockFound(CBlockIndex *pindex,
                               const CValidationState &state) {
     if (!state.CorruptionPossible()) {
         pindex->nStatus |= BLOCK_FAILED_VALID;
         setDirtyBlockIndex.insert(pindex);
         setBlockIndexCandidates.erase(pindex);
         InvalidChainFound(pindex);
     }
 }
 
 void UpdateCoins(const CTransaction &tx, CCoinsViewCache &inputs,
                  CTxUndo &txundo, int nHeight) {
     // mark inputs spent
     if (!tx.IsCoinBase()) {
         txundo.vprevout.reserve(tx.vin.size());
         for (const CTxIn &txin : tx.vin) {
             CCoinsModifier coins = inputs.ModifyCoins(txin.prevout.hash);
             unsigned nPos = txin.prevout.n;
 
             if (nPos >= coins->vout.size() || coins->vout[nPos].IsNull())
                 assert(false);
             // mark an outpoint spent, and construct undo information
             txundo.vprevout.push_back(CTxInUndo(coins->vout[nPos]));
             coins->Spend(nPos);
             if (coins->vout.size() == 0) {
                 CTxInUndo &undo = txundo.vprevout.back();
                 undo.nHeight = coins->nHeight;
                 undo.fCoinBase = coins->fCoinBase;
                 undo.nVersion = coins->nVersion;
             }
         }
     }
     // add outputs
     inputs.ModifyNewCoins(tx.GetId(), tx.IsCoinBase())->FromTx(tx, nHeight);
 }
 
 void UpdateCoins(const CTransaction &tx, CCoinsViewCache &inputs, int nHeight) {
     CTxUndo txundo;
     UpdateCoins(tx, inputs, txundo, nHeight);
 }
 
 bool CScriptCheck::operator()() {
     const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
     if (!VerifyScript(scriptSig, scriptPubKey, nFlags,
                       CachingTransactionSignatureChecker(ptxTo, nIn, amount,
                                                          cacheStore, txdata),
                       &error)) {
         return false;
     }
     return true;
 }
 
 int GetSpendHeight(const CCoinsViewCache &inputs) {
     LOCK(cs_main);
     CBlockIndex *pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
     return pindexPrev->nHeight + 1;
 }
 
 namespace Consensus {
 bool CheckTxInputs(const CTransaction &tx, CValidationState &state,
                    const CCoinsViewCache &inputs, int nSpendHeight) {
     // This doesn't trigger the DoS code on purpose; if it did, it would make it
     // easier for an attacker to attempt to split the network.
     if (!inputs.HaveInputs(tx)) {
         return state.Invalid(false, 0, "", "Inputs unavailable");
     }
 
     CAmount nValueIn = 0;
     CAmount nFees = 0;
     for (size_t i = 0; i < tx.vin.size(); i++) {
         const COutPoint &prevout = tx.vin[i].prevout;
         const Coin &coin = inputs.AccessCoin(prevout);
         assert(!coin.IsSpent());
 
         // If prev is coinbase, check that it's matured
         if (coin.IsCoinBase()) {
             if (nSpendHeight - coin.GetHeight() < COINBASE_MATURITY) {
                 return state.Invalid(
                     false, REJECT_INVALID,
                     "bad-txns-premature-spend-of-coinbase",
                     strprintf("tried to spend coinbase at depth %d",
                               nSpendHeight - coin.GetHeight()));
             }
         }
 
         // Check for negative or overflow input values
         nValueIn += coin.GetTxOut().nValue;
         if (!MoneyRange(coin.GetTxOut().nValue) || !MoneyRange(nValueIn)) {
             return state.DoS(100, false, REJECT_INVALID,
                              "bad-txns-inputvalues-outofrange");
         }
     }
 
     if (nValueIn < tx.GetValueOut()) {
         return state.DoS(100, false, REJECT_INVALID, "bad-txns-in-belowout",
                          false, strprintf("value in (%s) < value out (%s)",
                                           FormatMoney(nValueIn),
                                           FormatMoney(tx.GetValueOut())));
     }
 
     // Tally transaction fees
     CAmount nTxFee = nValueIn - tx.GetValueOut();
     if (nTxFee < 0) {
         return state.DoS(100, false, REJECT_INVALID, "bad-txns-fee-negative");
     }
     nFees += nTxFee;
     if (!MoneyRange(nFees)) {
         return state.DoS(100, false, REJECT_INVALID, "bad-txns-fee-outofrange");
     }
 
     return true;
 }
 } // namespace Consensus
 
 bool CheckInputs(const CTransaction &tx, CValidationState &state,
                  const CCoinsViewCache &inputs, bool fScriptChecks,
                  unsigned int flags, bool cacheStore,
                  const PrecomputedTransactionData &txdata,
                  std::vector<CScriptCheck> *pvChecks) {
     assert(!tx.IsCoinBase());
 
     if (!Consensus::CheckTxInputs(tx, state, inputs, GetSpendHeight(inputs))) {
         return false;
     }
 
     if (pvChecks) {
         pvChecks->reserve(tx.vin.size());
     }
 
     // The first loop above does all the inexpensive checks. Only if ALL inputs
     // pass do we perform expensive ECDSA signature checks. Helps prevent CPU
     // exhaustion attacks.
 
     // Skip script verification when connecting blocks under the assumedvalid
     // block. Assuming the assumedvalid block is valid this is safe because
     // block merkle hashes are still computed and checked, of course, if an
     // assumed valid block is invalid due to false scriptSigs this optimization
     // would allow an invalid chain to be accepted.
     if (!fScriptChecks) {
         return true;
     }
 
     for (size_t i = 0; i < tx.vin.size(); i++) {
         const COutPoint &prevout = tx.vin[i].prevout;
         const Coin &coin = inputs.AccessCoin(prevout);
         assert(!coin.IsSpent());
 
         // We very carefully only pass in things to CScriptCheck which are
         // clearly committed to by tx' witness hash. This provides a sanity
         // check that our caching is not introducing consensus failures through
         // additional data in, eg, the coins being spent being checked as a part
         // of CScriptCheck.
         const CScript &scriptPubKey = coin.GetTxOut().scriptPubKey;
         const CAmount amount = coin.GetTxOut().nValue;
 
         // Verify signature
         CScriptCheck check(scriptPubKey, amount, tx, i, flags, cacheStore,
                            txdata);
         if (pvChecks) {
             pvChecks->push_back(std::move(check));
         } else if (!check()) {
             if (flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) {
                 // Check whether the failure was caused by a non-mandatory
                 // script verification check, such as non-standard DER encodings
                 // or non-null dummy arguments; if so, don't trigger DoS
                 // protection to avoid splitting the network between upgraded
                 // and non-upgraded nodes.
                 uint32_t mandatoryFlags =
                     flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS;
                 CScriptCheck check2(scriptPubKey, amount, tx, i,
                                     mandatoryFlags |
                                         SCRIPT_ENABLE_SIGHASH_FORKID,
                                     cacheStore, txdata);
                 if (check2()) {
                     return state.Invalid(
                         false, REJECT_NONSTANDARD,
                         strprintf("non-mandatory-script-verify-flag (%s)",
                                   ScriptErrorString(check.GetScriptError())));
                 }
             }
 
             // Failures of other flags indicate a transaction that is invalid in
             // new blocks, e.g. a invalid P2SH. We DoS ban such nodes as they
             // are not following the protocol. That said during an upgrade
             // careful thought should be taken as to the correct behavior - we
             // may want to continue peering with non-upgraded nodes even after
             // soft-fork super-majority signaling has occurred.
             return state.DoS(
                 100, false, REJECT_INVALID,
                 strprintf("mandatory-script-verify-flag-failed (%s)",
                           ScriptErrorString(check.GetScriptError())));
         }
     }
 
     return true;
 }
 
 namespace {
 
 bool UndoWriteToDisk(const CBlockUndo &blockundo, CDiskBlockPos &pos,
                      const uint256 &hashBlock,
                      const CMessageHeader::MessageStartChars &messageStart) {
     // Open history file to append
     CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
     if (fileout.IsNull()) return error("%s: OpenUndoFile failed", __func__);
 
     // Write index header
     unsigned int nSize = GetSerializeSize(fileout, blockundo);
     fileout << FLATDATA(messageStart) << nSize;
 
     // Write undo data
     long fileOutPos = ftell(fileout.Get());
     if (fileOutPos < 0) return error("%s: ftell failed", __func__);
     pos.nPos = (unsigned int)fileOutPos;
     fileout << blockundo;
 
     // calculate & write checksum
     CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
     hasher << hashBlock;
     hasher << blockundo;
     fileout << hasher.GetHash();
 
     return true;
 }
 
 bool UndoReadFromDisk(CBlockUndo &blockundo, const CDiskBlockPos &pos,
                       const uint256 &hashBlock) {
     // Open history file to read
     CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
     if (filein.IsNull()) {
         return error("%s: OpenUndoFile failed", __func__);
     }
 
     // Read block
     uint256 hashChecksum;
     try {
         filein >> blockundo;
         filein >> hashChecksum;
     } catch (const std::exception &e) {
         return error("%s: Deserialize or I/O error - %s", __func__, e.what());
     }
 
     // Verify checksum
     CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
     hasher << hashBlock;
     hasher << blockundo;
     if (hashChecksum != hasher.GetHash()) {
         return error("%s: Checksum mismatch", __func__);
     }
 
     return true;
 }
 
 /** Abort with a message */
 bool AbortNode(const std::string &strMessage,
                const std::string &userMessage = "") {
     SetMiscWarning(strMessage);
     LogPrintf("*** %s\n", strMessage);
     uiInterface.ThreadSafeMessageBox(
         userMessage.empty() ? _("Error: A fatal internal error occurred, see "
                                 "debug.log for details")
                             : userMessage,
         "", CClientUIInterface::MSG_ERROR);
     StartShutdown();
     return false;
 }
 
 bool AbortNode(CValidationState &state, const std::string &strMessage,
                const std::string &userMessage = "") {
     AbortNode(strMessage, userMessage);
     return state.Error(strMessage);
 }
 
 } // anon namespace
 
 /** Apply the undo operation of a CTxInUndo to the given chain state. */
 DisconnectResult ApplyTxInUndo(const CTxInUndo &undo, CCoinsViewCache &view,
                                const COutPoint &out) {
     bool fClean = true;
 
     CCoinsModifier coins = view.ModifyCoins(out.hash);
     if (undo.nHeight != 0) {
         // undo data contains height: this is the last output of the prevout tx
         // being spent
         if (!coins->IsPruned()) {
             // Overwriting existing transaction.
             fClean = false;
         }
         coins->fCoinBase = undo.fCoinBase;
         coins->nHeight = undo.nHeight;
         coins->nVersion = undo.nVersion;
     } else {
         if (coins->IsPruned()) {
             // Adding output to missing transaction.
             fClean = false;
         }
     }
 
     if (coins->IsAvailable(out.n)) {
         // Overwriting existing output.
         fClean = false;
     }
 
     if (coins->vout.size() < out.n + 1) {
         coins->vout.resize(out.n + 1);
     }
 
     coins->vout[out.n] = undo.txout;
 
     return fClean ? DISCONNECT_OK : DISCONNECT_UNCLEAN;
 }
 
 /**
  * Undo the effects of this block (with given index) on the UTXO set represented
  * by coins. When UNCLEAN or FAILED is returned, view is left in an
  * indeterminate state.
  */
 static DisconnectResult DisconnectBlock(const CBlock &block,
                                         const CBlockIndex *pindex,
                                         CCoinsViewCache &view) {
     assert(pindex->GetBlockHash() == view.GetBestBlock());
 
     CBlockUndo blockUndo;
     CDiskBlockPos pos = pindex->GetUndoPos();
     if (pos.IsNull()) {
         error("DisconnectBlock(): no undo data available");
         return DISCONNECT_FAILED;
     }
 
     if (!UndoReadFromDisk(blockUndo, pos, pindex->pprev->GetBlockHash())) {
         error("DisconnectBlock(): failure reading undo data");
         return DISCONNECT_FAILED;
     }
 
     return ApplyBlockUndo(blockUndo, block, pindex, view);
 }
 
 DisconnectResult ApplyBlockUndo(const CBlockUndo &blockUndo,
                                 const CBlock &block, const CBlockIndex *pindex,
                                 CCoinsViewCache &view) {
     bool fClean = true;
 
     if (blockUndo.vtxundo.size() + 1 != block.vtx.size()) {
         error("DisconnectBlock(): block and undo data inconsistent");
         return DISCONNECT_FAILED;
     }
 
     // Undo transactions in reverse order.
     size_t i = block.vtx.size();
     while (i-- > 0) {
         const CTransaction &tx = *(block.vtx[i]);
         uint256 txid = tx.GetId();
 
         // Check that all outputs are available and match the outputs in the
         // block itself exactly.
         {
             CCoinsModifier outs = view.ModifyCoins(txid);
             outs->ClearUnspendable();
 
             CCoins outsBlock(tx, pindex->nHeight);
             // The CCoins serialization does not serialize negative numbers. No
             // network rules currently depend on the version here, so an
             // inconsistency is harmless but it must be corrected before txout
             // nversion ever influences a network rule.
             if (outsBlock.nVersion < 0) {
                 outs->nVersion = outsBlock.nVersion;
             }
 
             if (*outs != outsBlock) {
                 // Transaction mismatch.
                 fClean = false;
             }
 
             // Remove outputs.
             outs->Clear();
         }
 
         // Restore inputs.
         if (i < 1) {
             // Skip the coinbase.
             continue;
         }
 
         const CTxUndo &txundo = blockUndo.vtxundo[i - 1];
         if (txundo.vprevout.size() != tx.vin.size()) {
             error("DisconnectBlock(): transaction and undo data inconsistent");
             return DISCONNECT_FAILED;
         }
 
         for (size_t j = tx.vin.size(); j-- > 0;) {
             const COutPoint &out = tx.vin[j].prevout;
             const CTxInUndo &undo = txundo.vprevout[j];
             DisconnectResult res = ApplyTxInUndo(undo, view, out);
             if (res == DISCONNECT_FAILED) {
                 return DISCONNECT_FAILED;
             }
             fClean = fClean && res != DISCONNECT_UNCLEAN;
         }
     }
 
     // Move best block pointer to previous block.
     view.SetBestBlock(block.hashPrevBlock);
 
     return fClean ? DISCONNECT_OK : DISCONNECT_UNCLEAN;
 }
 
 static void FlushBlockFile(bool fFinalize = false) {
     LOCK(cs_LastBlockFile);
 
     CDiskBlockPos posOld(nLastBlockFile, 0);
 
     FILE *fileOld = OpenBlockFile(posOld);
     if (fileOld) {
         if (fFinalize)
             TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nSize);
         FileCommit(fileOld);
         fclose(fileOld);
     }
 
     fileOld = OpenUndoFile(posOld);
     if (fileOld) {
         if (fFinalize)
             TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nUndoSize);
         FileCommit(fileOld);
         fclose(fileOld);
     }
 }
 
 bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos,
                  unsigned int nAddSize);
 
 static CCheckQueue<CScriptCheck> scriptcheckqueue(128);
 
 void ThreadScriptCheck() {
     RenameThread("bitcoin-scriptch");
     scriptcheckqueue.Thread();
 }
 
 // Protected by cs_main
 VersionBitsCache versionbitscache;
 
 int32_t ComputeBlockVersion(const CBlockIndex *pindexPrev,
                             const Consensus::Params &params) {
     LOCK(cs_main);
     int32_t nVersion = VERSIONBITS_TOP_BITS;
 
     for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; i++) {
         ThresholdState state = VersionBitsState(
             pindexPrev, params, (Consensus::DeploymentPos)i, versionbitscache);
         if (state == THRESHOLD_LOCKED_IN || state == THRESHOLD_STARTED) {
             nVersion |= VersionBitsMask(params, (Consensus::DeploymentPos)i);
         }
     }
 
     return nVersion;
 }
 
 /**
  * Threshold condition checker that triggers when unknown versionbits are seen
  * on the network.
  */
 class WarningBitsConditionChecker : public AbstractThresholdConditionChecker {
 private:
     int bit;
 
 public:
     WarningBitsConditionChecker(int bitIn) : bit(bitIn) {}
 
     int64_t BeginTime(const Consensus::Params &params) const { return 0; }
     int64_t EndTime(const Consensus::Params &params) const {
         return std::numeric_limits<int64_t>::max();
     }
     int Period(const Consensus::Params &params) const {
         return params.nMinerConfirmationWindow;
     }
     int Threshold(const Consensus::Params &params) const {
         return params.nRuleChangeActivationThreshold;
     }
 
     bool Condition(const CBlockIndex *pindex,
                    const Consensus::Params &params) const {
         return ((pindex->nVersion & VERSIONBITS_TOP_MASK) ==
                 VERSIONBITS_TOP_BITS) &&
                ((pindex->nVersion >> bit) & 1) != 0 &&
                ((ComputeBlockVersion(pindex->pprev, params) >> bit) & 1) == 0;
     }
 };
 
 // Protected by cs_main
 static ThresholdConditionCache warningcache[VERSIONBITS_NUM_BITS];
 
 static int64_t nTimeCheck = 0;
 static int64_t nTimeForks = 0;
 static int64_t nTimeVerify = 0;
 static int64_t nTimeConnect = 0;
 static int64_t nTimeIndex = 0;
 static int64_t nTimeCallbacks = 0;
 static int64_t nTimeTotal = 0;
 
 /**
  * Apply the effects of this block (with given index) on the UTXO set
  * represented by coins. Validity checks that depend on the UTXO set are also
  * done; ConnectBlock() can fail if those validity checks fail (among other
  * reasons).
  */
 static bool ConnectBlock(const Config &config, const CBlock &block,
                          CValidationState &state, CBlockIndex *pindex,
                          CCoinsViewCache &view, const CChainParams &chainparams,
                          bool fJustCheck = false) {
     AssertLockHeld(cs_main);
 
     int64_t nTimeStart = GetTimeMicros();
 
     // Check it again in case a previous version let a bad block in
     if (!CheckBlock(config, block, state, chainparams.GetConsensus(),
                     !fJustCheck, !fJustCheck)) {
         return error("%s: Consensus::CheckBlock: %s", __func__,
                      FormatStateMessage(state));
     }
 
     // Verify that the view's current state corresponds to the previous block
     uint256 hashPrevBlock =
         pindex->pprev == nullptr ? uint256() : pindex->pprev->GetBlockHash();
     assert(hashPrevBlock == view.GetBestBlock());
 
     // Special case for the genesis block, skipping connection of its
     // transactions (its coinbase is unspendable)
     if (block.GetHash() == chainparams.GetConsensus().hashGenesisBlock) {
         if (!fJustCheck) {
             view.SetBestBlock(pindex->GetBlockHash());
         }
 
         return true;
     }
 
     bool fScriptChecks = true;
     if (!hashAssumeValid.IsNull()) {
         // We've been configured with the hash of a block which has been
         // externally verified to have a valid history. A suitable default value
         // is included with the software and updated from time to time. Because
         // validity relative to a piece of software is an objective fact these
         // defaults can be easily reviewed. This setting doesn't force the
         // selection of any particular chain but makes validating some faster by
         // effectively caching the result of part of the verification.
         BlockMap::const_iterator it = mapBlockIndex.find(hashAssumeValid);
         if (it != mapBlockIndex.end()) {
             if (it->second->GetAncestor(pindex->nHeight) == pindex &&
                 pindexBestHeader->GetAncestor(pindex->nHeight) == pindex &&
                 pindexBestHeader->nChainWork >=
                     UintToArith256(
                         chainparams.GetConsensus().nMinimumChainWork)) {
                 // This block is a member of the assumed verified chain and an
                 // ancestor of the best header. The equivalent time check
                 // discourages hashpower from extorting the network via DOS
                 // attack into accepting an invalid block through telling users
                 // they must manually set assumevalid. Requiring a software
                 // change or burying the invalid block, regardless of the
                 // setting, makes it hard to hide the implication of the demand.
                 // This also avoids having release candidates that are hardly
                 // doing any signature verification at all in testing without
                 // having to artificially set the default assumed verified block
                 // further back. The test against nMinimumChainWork prevents the
                 // skipping when denied access to any chain at least as good as
                 // the expected chain.
                 fScriptChecks =
                     (GetBlockProofEquivalentTime(
                          *pindexBestHeader, *pindex, *pindexBestHeader,
                          chainparams.GetConsensus()) <= 60 * 60 * 24 * 7 * 2);
             }
         }
     }
 
     int64_t nTime1 = GetTimeMicros();
     nTimeCheck += nTime1 - nTimeStart;
     LogPrint("bench", "    - Sanity checks: %.2fms [%.2fs]\n",
              0.001 * (nTime1 - nTimeStart), nTimeCheck * 0.000001);
 
     // Do not allow blocks that contain transactions which 'overwrite' older
     // transactions, unless those are already completely spent. If such
     // overwrites are allowed, coinbases and transactions depending upon those
     // can be duplicated to remove the ability to spend the first instance --
     // even after being sent to another address. See BIP30 and
     // http://r6.ca/blog/20120206T005236Z.html for more information. This logic
     // is not necessary for memory pool transactions, as AcceptToMemoryPool
     // already refuses previously-known transaction ids entirely. This rule was
     // originally applied to all blocks with a timestamp after March 15, 2012,
     // 0:00 UTC. Now that the whole chain is irreversibly beyond that time it is
     // applied to all blocks except the two in the chain that violate it. This
     // prevents exploiting the issue against nodes during their initial block
     // download.
     bool fEnforceBIP30 = (!pindex->phashBlock) || // Enforce on CreateNewBlock
                                                   // invocations which don't
                                                   // have a hash.
                          !((pindex->nHeight == 91842 &&
                             pindex->GetBlockHash() ==
                                 uint256S("0x00000000000a4d0a398161ffc163c503763"
                                          "b1f4360639393e0e4c8e300e0caec")) ||
                            (pindex->nHeight == 91880 &&
                             pindex->GetBlockHash() ==
                                 uint256S("0x00000000000743f190a18c5577a3c2d2a1f"
                                          "610ae9601ac046a38084ccb7cd721")));
 
     // Once BIP34 activated it was not possible to create new duplicate
     // coinbases and thus other than starting with the 2 existing duplicate
     // coinbase pairs, not possible to create overwriting txs. But by the time
     // BIP34 activated, in each of the existing pairs the duplicate coinbase had
     // overwritten the first before the first had been spent. Since those
     // coinbases are sufficiently buried its no longer possible to create
     // further duplicate transactions descending from the known pairs either. If
     // we're on the known chain at height greater than where BIP34 activated, we
     // can save the db accesses needed for the BIP30 check.
     CBlockIndex *pindexBIP34height =
         pindex->pprev->GetAncestor(chainparams.GetConsensus().BIP34Height);
     // Only continue to enforce if we're below BIP34 activation height or the
     // block hash at that height doesn't correspond.
     fEnforceBIP30 = fEnforceBIP30 && (!pindexBIP34height ||
                                       !(pindexBIP34height->GetBlockHash() ==
                                         chainparams.GetConsensus().BIP34Hash));
 
     if (fEnforceBIP30) {
         for (const auto &tx : block.vtx) {
             for (size_t o = 0; o < tx->vout.size(); o++) {
                 if (view.HaveCoin(COutPoint(tx->GetHash(), o))) {
                     return state.DoS(
                         100,
                         error("ConnectBlock(): tried to overwrite transaction"),
                         REJECT_INVALID, "bad-txns-BIP30");
                 }
             }
         }
     }
 
     // BIP16 didn't become active until Apr 1 2012
     int64_t nBIP16SwitchTime = 1333238400;
     bool fStrictPayToScriptHash = (pindex->GetBlockTime() >= nBIP16SwitchTime);
 
     uint32_t flags =
         fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE;
 
     // Start enforcing the DERSIG (BIP66) rule
     if (pindex->nHeight >= chainparams.GetConsensus().BIP66Height) {
         flags |= SCRIPT_VERIFY_DERSIG;
     }
 
     // Start enforcing CHECKLOCKTIMEVERIFY (BIP65) rule
     if (pindex->nHeight >= chainparams.GetConsensus().BIP65Height) {
         flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
     }
 
     // Start enforcing BIP68 (sequence locks) and BIP112 (CHECKSEQUENCEVERIFY)
     // using versionbits logic.
     int nLockTimeFlags = 0;
     if (VersionBitsState(pindex->pprev, chainparams.GetConsensus(),
                          Consensus::DEPLOYMENT_CSV,
                          versionbitscache) == THRESHOLD_ACTIVE) {
         flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY;
         nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE;
     }
 
     // If the UAHF is enabled, we start accepting replay protected txns
     const bool hasUAHF = IsUAHFenabled(config, pindex->pprev);
     if (hasUAHF) {
         flags |= SCRIPT_VERIFY_STRICTENC;
         flags |= SCRIPT_ENABLE_SIGHASH_FORKID;
     }
 
     int64_t nTime2 = GetTimeMicros();
     nTimeForks += nTime2 - nTime1;
     LogPrint("bench", "    - Fork checks: %.2fms [%.2fs]\n",
              0.001 * (nTime2 - nTime1), nTimeForks * 0.000001);
 
     CBlockUndo blockundo;
 
     CCheckQueueControl<CScriptCheck> control(
         fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : nullptr);
 
     std::vector<int> prevheights;
     CAmount nFees = 0;
     int nInputs = 0;
 
     // Sigops counting. We need to do it again because of P2SH.
     uint64_t nSigOpsCount = 0;
     const uint64_t currentBlockSize =
         ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION);
     const uint64_t nMaxSigOpsCount = GetMaxBlockSigOpsCount(currentBlockSize);
 
     CDiskTxPos pos(pindex->GetBlockPos(),
                    GetSizeOfCompactSize(block.vtx.size()));
     std::vector<std::pair<uint256, CDiskTxPos>> vPos;
     vPos.reserve(block.vtx.size());
     blockundo.vtxundo.reserve(block.vtx.size() - 1);
 
     for (size_t i = 0; i < block.vtx.size(); i++) {
         const CTransaction &tx = *(block.vtx[i]);
 
         nInputs += tx.vin.size();
 
         if (!tx.IsCoinBase()) {
             if (!view.HaveInputs(tx)) {
                 return state.DoS(
                     100, error("ConnectBlock(): inputs missing/spent"),
                     REJECT_INVALID, "bad-txns-inputs-missingorspent");
             }
 
             // Check that transaction is BIP68 final BIP68 lock checks (as
             // opposed to nLockTime checks) must be in ConnectBlock because they
             // require the UTXO set.
             prevheights.resize(tx.vin.size());
             for (size_t j = 0; j < tx.vin.size(); j++) {
                 prevheights[j] = view.AccessCoin(tx.vin[j].prevout).GetHeight();
             }
 
             if (!SequenceLocks(tx, nLockTimeFlags, &prevheights, *pindex)) {
                 return state.DoS(
                     100, error("%s: contains a non-BIP68-final transaction",
                                __func__),
                     REJECT_INVALID, "bad-txns-nonfinal");
             }
         }
 
         // GetTransactionSigOpCount counts 2 types of sigops:
         // * legacy (always)
         // * p2sh (when P2SH enabled in flags and excludes coinbase)
         auto txSigOpsCount = GetTransactionSigOpCount(tx, view, flags);
         if (txSigOpsCount > MAX_TX_SIGOPS_COUNT) {
             return state.DoS(100, false, REJECT_INVALID, "bad-txn-sigops");
         }
 
         nSigOpsCount += txSigOpsCount;
         if (nSigOpsCount > nMaxSigOpsCount) {
             return state.DoS(100, error("ConnectBlock(): too many sigops"),
                              REJECT_INVALID, "bad-blk-sigops");
         }
 
         if (!tx.IsCoinBase()) {
             nFees += view.GetValueIn(tx) - tx.GetValueOut();
 
             // Don't cache results if we're actually connecting blocks (still
             // consult the cache, though).
             bool fCacheResults = fJustCheck;
 
             std::vector<CScriptCheck> vChecks;
             if (!CheckInputs(tx, state, view, fScriptChecks, flags,
                              fCacheResults, PrecomputedTransactionData(tx),
                              nScriptCheckThreads ? &vChecks : nullptr)) {
                 return error("ConnectBlock(): CheckInputs on %s failed with %s",
                              tx.GetId().ToString(), FormatStateMessage(state));
             }
 
             control.Add(vChecks);
         }
 
         CTxUndo undoDummy;
         if (i > 0) {
             blockundo.vtxundo.push_back(CTxUndo());
         }
         UpdateCoins(tx, view, i == 0 ? undoDummy : blockundo.vtxundo.back(),
                     pindex->nHeight);
 
         vPos.push_back(std::make_pair(tx.GetId(), pos));
         pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
     }
 
     int64_t nTime3 = GetTimeMicros();
     nTimeConnect += nTime3 - nTime2;
     LogPrint("bench", "      - Connect %u transactions: %.2fms (%.3fms/tx, "
                       "%.3fms/txin) [%.2fs]\n",
              (unsigned)block.vtx.size(), 0.001 * (nTime3 - nTime2),
              0.001 * (nTime3 - nTime2) / block.vtx.size(),
              nInputs <= 1 ? 0 : 0.001 * (nTime3 - nTime2) / (nInputs - 1),
              nTimeConnect * 0.000001);
 
     CAmount blockReward =
         nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus());
     if (block.vtx[0]->GetValueOut() > blockReward) {
         return state.DoS(100, error("ConnectBlock(): coinbase pays too much "
                                     "(actual=%d vs limit=%d)",
                                     block.vtx[0]->GetValueOut(), blockReward),
                          REJECT_INVALID, "bad-cb-amount");
     }
 
     if (!control.Wait()) {
         return state.DoS(100, false, REJECT_INVALID, "blk-bad-inputs", false,
                          "parallel script check failed");
     }
 
     int64_t nTime4 = GetTimeMicros();
     nTimeVerify += nTime4 - nTime2;
     LogPrint("bench", "    - Verify %u txins: %.2fms (%.3fms/txin) [%.2fs]\n",
              nInputs - 1, 0.001 * (nTime4 - nTime2),
              nInputs <= 1 ? 0 : 0.001 * (nTime4 - nTime2) / (nInputs - 1),
              nTimeVerify * 0.000001);
 
     if (fJustCheck) {
         return true;
     }
 
     // Write undo information to disk
     if (pindex->GetUndoPos().IsNull() ||
         !pindex->IsValid(BLOCK_VALID_SCRIPTS)) {
         if (pindex->GetUndoPos().IsNull()) {
             CDiskBlockPos _pos;
             if (!FindUndoPos(
                     state, pindex->nFile, _pos,
                     ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) +
                         40)) {
                 return error("ConnectBlock(): FindUndoPos failed");
             }
             if (!UndoWriteToDisk(blockundo, _pos, pindex->pprev->GetBlockHash(),
                                  chainparams.MessageStart())) {
                 return AbortNode(state, "Failed to write undo data");
             }
 
             // update nUndoPos in block index
             pindex->nUndoPos = _pos.nPos;
             pindex->nStatus |= BLOCK_HAVE_UNDO;
         }
 
         pindex->RaiseValidity(BLOCK_VALID_SCRIPTS);
         setDirtyBlockIndex.insert(pindex);
     }
 
     if (fTxIndex && !pblocktree->WriteTxIndex(vPos)) {
         return AbortNode(state, "Failed to write transaction index");
     }
 
     // add this block to the view's block chain
     view.SetBestBlock(pindex->GetBlockHash());
 
     int64_t nTime5 = GetTimeMicros();
     nTimeIndex += nTime5 - nTime4;
     LogPrint("bench", "    - Index writing: %.2fms [%.2fs]\n",
              0.001 * (nTime5 - nTime4), nTimeIndex * 0.000001);
 
     // Watch for changes to the previous coinbase transaction.
     static uint256 hashPrevBestCoinBase;
     GetMainSignals().UpdatedTransaction(hashPrevBestCoinBase);
     hashPrevBestCoinBase = block.vtx[0]->GetId();
 
     int64_t nTime6 = GetTimeMicros();
     nTimeCallbacks += nTime6 - nTime5;
     LogPrint("bench", "    - Callbacks: %.2fms [%.2fs]\n",
              0.001 * (nTime6 - nTime5), nTimeCallbacks * 0.000001);
 
     return true;
 }
 
 /**
  * Update the on-disk chain state.
  * The caches and indexes are flushed depending on the mode we're called with if
  * they're too large, if it's been a while since the last write, or always and
  * in all cases if we're in prune mode and are deleting files.
  */
 static bool FlushStateToDisk(CValidationState &state, FlushStateMode mode,
                              int nManualPruneHeight) {
     int64_t nMempoolUsage = mempool.DynamicMemoryUsage();
     const CChainParams &chainparams = Params();
     LOCK2(cs_main, cs_LastBlockFile);
     static int64_t nLastWrite = 0;
     static int64_t nLastFlush = 0;
     static int64_t nLastSetChain = 0;
     std::set<int> setFilesToPrune;
     bool fFlushForPrune = false;
     try {
         if (fPruneMode && (fCheckForPruning || nManualPruneHeight > 0) &&
             !fReindex) {
             if (nManualPruneHeight > 0) {
                 FindFilesToPruneManual(setFilesToPrune, nManualPruneHeight);
             } else {
                 FindFilesToPrune(setFilesToPrune,
                                  chainparams.PruneAfterHeight());
                 fCheckForPruning = false;
             }
             if (!setFilesToPrune.empty()) {
                 fFlushForPrune = true;
                 if (!fHavePruned) {
                     pblocktree->WriteFlag("prunedblockfiles", true);
                     fHavePruned = true;
                 }
             }
         }
         int64_t nNow = GetTimeMicros();
         // Avoid writing/flushing immediately after startup.
         if (nLastWrite == 0) {
             nLastWrite = nNow;
         }
         if (nLastFlush == 0) {
             nLastFlush = nNow;
         }
         if (nLastSetChain == 0) {
             nLastSetChain = nNow;
         }
         int64_t nMempoolSizeMax =
             GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
         int64_t cacheSize =
             pcoinsTip->DynamicMemoryUsage() * DB_PEAK_USAGE_FACTOR;
         int64_t nTotalSpace =
             nCoinCacheUsage +
             std::max<int64_t>(nMempoolSizeMax - nMempoolUsage, 0);
         // The cache is large and we're within 10% and 200 MiB or 50% and 50MiB
         // of the limit, but we have time now (not in the middle of a block
         // processing).
         bool fCacheLarge =
             mode == FLUSH_STATE_PERIODIC &&
             cacheSize >
                 std::min(std::max(nTotalSpace / 2,
                                   nTotalSpace -
                                       MIN_BLOCK_COINSDB_USAGE * 1024 * 1024),
                          std::max((9 * nTotalSpace) / 10,
                                   nTotalSpace -
                                       MAX_BLOCK_COINSDB_USAGE * 1024 * 1024));
         // The cache is over the limit, we have to write now.
         bool fCacheCritical =
             mode == FLUSH_STATE_IF_NEEDED && cacheSize > nTotalSpace;
         // It's been a while since we wrote the block index to disk. Do this
         // frequently, so we don't need to redownload after a crash.
         bool fPeriodicWrite =
             mode == FLUSH_STATE_PERIODIC &&
             nNow > nLastWrite + (int64_t)DATABASE_WRITE_INTERVAL * 1000000;
         // It's been very long since we flushed the cache. Do this infrequently,
         // to optimize cache usage.
         bool fPeriodicFlush =
             mode == FLUSH_STATE_PERIODIC &&
             nNow > nLastFlush + (int64_t)DATABASE_FLUSH_INTERVAL * 1000000;
         // Combine all conditions that result in a full cache flush.
         bool fDoFullFlush = (mode == FLUSH_STATE_ALWAYS) || fCacheLarge ||
                             fCacheCritical || fPeriodicFlush || fFlushForPrune;
         // Write blocks and block index to disk.
         if (fDoFullFlush || fPeriodicWrite) {
             // Depend on nMinDiskSpace to ensure we can write block index
             if (!CheckDiskSpace(0)) return state.Error("out of disk space");
             // First make sure all block and undo data is flushed to disk.
             FlushBlockFile();
             // Then update all block file information (which may refer to block
             // and undo files).
             {
                 std::vector<std::pair<int, const CBlockFileInfo *>> vFiles;
                 vFiles.reserve(setDirtyFileInfo.size());
                 for (std::set<int>::iterator it = setDirtyFileInfo.begin();
                      it != setDirtyFileInfo.end();) {
                     vFiles.push_back(std::make_pair(*it, &vinfoBlockFile[*it]));
                     setDirtyFileInfo.erase(it++);
                 }
                 std::vector<const CBlockIndex *> vBlocks;
                 vBlocks.reserve(setDirtyBlockIndex.size());
                 for (std::set<CBlockIndex *>::iterator it =
                          setDirtyBlockIndex.begin();
                      it != setDirtyBlockIndex.end();) {
                     vBlocks.push_back(*it);
                     setDirtyBlockIndex.erase(it++);
                 }
                 if (!pblocktree->WriteBatchSync(vFiles, nLastBlockFile,
                                                 vBlocks)) {
                     return AbortNode(state,
                                      "Failed to write to block index database");
                 }
             }
             // Finally remove any pruned files
             if (fFlushForPrune) UnlinkPrunedFiles(setFilesToPrune);
             nLastWrite = nNow;
         }
         // Flush best chain related state. This can only be done if the blocks /
         // block index write was also done.
         if (fDoFullFlush) {
             // Typical CCoins structures on disk are around 128 bytes in size.
             // Pushing a new one to the database can cause it to be written
             // twice (once in the log, and once in the tables). This is already
             // an overestimation, as most will delete an existing entry or
             // overwrite one. Still, use a conservative safety factor of 2.
             if (!CheckDiskSpace(128 * 2 * 2 * pcoinsTip->GetCacheSize()))
                 return state.Error("out of disk space");
             // Flush the chainstate (which may refer to block index entries).
             if (!pcoinsTip->Flush())
                 return AbortNode(state, "Failed to write to coin database");
             nLastFlush = nNow;
         }
         if (fDoFullFlush ||
             ((mode == FLUSH_STATE_ALWAYS || mode == FLUSH_STATE_PERIODIC) &&
              nNow >
                  nLastSetChain + (int64_t)DATABASE_WRITE_INTERVAL * 1000000)) {
             // Update best block in wallet (so we can detect restored wallets).
             GetMainSignals().SetBestChain(chainActive.GetLocator());
             nLastSetChain = nNow;
         }
     } catch (const std::runtime_error &e) {
         return AbortNode(state, std::string("System error while flushing: ") +
                                     e.what());
     }
     return true;
 }
 
 void FlushStateToDisk() {
     CValidationState state;
     FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
 }
 
 void PruneAndFlush() {
     CValidationState state;
     fCheckForPruning = true;
     FlushStateToDisk(state, FLUSH_STATE_NONE);
 }
 
 /** Update chainActive and related internal data structures. */
 static void UpdateTip(const Config &config, CBlockIndex *pindexNew) {
     const CChainParams &chainParams = config.GetChainParams();
 
     chainActive.SetTip(pindexNew);
 
     // New best block
     mempool.AddTransactionsUpdated(1);
 
     cvBlockChange.notify_all();
 
     static bool fWarned = false;
     std::vector<std::string> warningMessages;
     if (!IsInitialBlockDownload()) {
         int nUpgraded = 0;
         const CBlockIndex *pindex = chainActive.Tip();
         for (int bit = 0; bit < VERSIONBITS_NUM_BITS; bit++) {
             WarningBitsConditionChecker checker(bit);
             ThresholdState state = checker.GetStateFor(
                 pindex, chainParams.GetConsensus(), warningcache[bit]);
             if (state == THRESHOLD_ACTIVE || state == THRESHOLD_LOCKED_IN) {
                 if (state == THRESHOLD_ACTIVE) {
                     std::string strWarning =
                         strprintf(_("Warning: unknown new rules activated "
                                     "(versionbit %i)"),
                                   bit);
                     SetMiscWarning(strWarning);
                     if (!fWarned) {
                         AlertNotify(strWarning);
                         fWarned = true;
                     }
                 } else {
                     warningMessages.push_back(
                         strprintf("unknown new rules are about to activate "
                                   "(versionbit %i)",
                                   bit));
                 }
             }
         }
         // Check the version of the last 100 blocks to see if we need to
         // upgrade:
         for (int i = 0; i < 100 && pindex != nullptr; i++) {
             int32_t nExpectedVersion =
                 ComputeBlockVersion(pindex->pprev, chainParams.GetConsensus());
             if (pindex->nVersion > VERSIONBITS_LAST_OLD_BLOCK_VERSION &&
                 (pindex->nVersion & ~nExpectedVersion) != 0)
                 ++nUpgraded;
             pindex = pindex->pprev;
         }
         if (nUpgraded > 0)
             warningMessages.push_back(strprintf(
                 "%d of last 100 blocks have unexpected version", nUpgraded));
         if (nUpgraded > 100 / 2) {
             std::string strWarning =
                 _("Warning: Unknown block versions being mined! It's possible "
                   "unknown rules are in effect");
             // notify GetWarnings(), called by Qt and the JSON-RPC code to warn
             // the user:
             SetMiscWarning(strWarning);
             if (!fWarned) {
                 AlertNotify(strWarning);
                 fWarned = true;
             }
         }
     }
     LogPrintf(
         "%s: new best=%s height=%d version=0x%08x log2_work=%.8g tx=%lu "
         "date='%s' progress=%f cache=%.1fMiB(%utx)",
         __func__, chainActive.Tip()->GetBlockHash().ToString(),
         chainActive.Height(), chainActive.Tip()->nVersion,
         log(chainActive.Tip()->nChainWork.getdouble()) / log(2.0),
         (unsigned long)chainActive.Tip()->nChainTx,
         DateTimeStrFormat("%Y-%m-%d %H:%M:%S",
                           chainActive.Tip()->GetBlockTime()),
         GuessVerificationProgress(chainParams.TxData(), chainActive.Tip()),
         pcoinsTip->DynamicMemoryUsage() * (1.0 / (1 << 20)),
         pcoinsTip->GetCacheSize());
     if (!warningMessages.empty())
         LogPrintf(" warning='%s'",
                   boost::algorithm::join(warningMessages, ", "));
     LogPrintf("\n");
 }
 
 /**
  * Disconnect chainActive's tip. You probably want to call
  * mempool.removeForReorg and manually re-limit mempool size after this, with
  * cs_main held.
  */
 static bool DisconnectTip(const Config &config, CValidationState &state,
                           bool fBare = false) {
     const Consensus::Params &consensusParams =
         config.GetChainParams().GetConsensus();
     CBlockIndex *pindexDelete = chainActive.Tip();
     assert(pindexDelete);
     // Read block from disk.
     CBlock block;
     if (!ReadBlockFromDisk(block, pindexDelete, consensusParams)) {
         return AbortNode(state, "Failed to read block");
     }
 
     // Apply the block atomically to the chain state.
     int64_t nStart = GetTimeMicros();
     {
         CCoinsViewCache view(pcoinsTip);
         if (DisconnectBlock(block, pindexDelete, view) != DISCONNECT_OK) {
             return error("DisconnectTip(): DisconnectBlock %s failed",
                          pindexDelete->GetBlockHash().ToString());
         }
 
         bool flushed = view.Flush();
         assert(flushed);
     }
 
     LogPrint("bench", "- Disconnect block: %.2fms\n",
              (GetTimeMicros() - nStart) * 0.001);
 
     // Write the chain state to disk, if necessary.
     if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED)) {
         return false;
     }
 
     if (!fBare) {
         // Resurrect mempool transactions from the disconnected block.
         std::vector<uint256> vHashUpdate;
         for (const auto &it : block.vtx) {
             const CTransaction &tx = *it;
             // ignore validation errors in resurrected transactions
             CValidationState stateDummy;
             if (tx.IsCoinBase() ||
                 !AcceptToMemoryPool(config, mempool, stateDummy, it, false,
                                     nullptr, nullptr, true)) {
                 mempool.removeRecursive(tx, MemPoolRemovalReason::REORG);
             } else if (mempool.exists(tx.GetId())) {
                 vHashUpdate.push_back(tx.GetId());
             }
         }
         // AcceptToMemoryPool/addUnchecked all assume that new mempool entries
         // have no in-mempool children, which is generally not true when adding
         // previously-confirmed transactions back to the mempool.
         // UpdateTransactionsFromBlock finds descendants of any transactions in
         // this block that were added back and cleans up the mempool state.
         mempool.UpdateTransactionsFromBlock(vHashUpdate);
     }
 
     // Update chainActive and related variables.
     UpdateTip(config, pindexDelete->pprev);
     // Let wallets know transactions went from 1-confirmed to
     // 0-confirmed or conflicted:
     for (const auto &tx : block.vtx) {
         GetMainSignals().SyncTransaction(
             *tx, pindexDelete->pprev,
             CMainSignals::SYNC_TRANSACTION_NOT_IN_BLOCK);
     }
     return true;
 }
 
 static int64_t nTimeReadFromDisk = 0;
 static int64_t nTimeConnectTotal = 0;
 static int64_t nTimeFlush = 0;
 static int64_t nTimeChainState = 0;
 static int64_t nTimePostConnect = 0;
 
 /**
  * Used to track blocks whose transactions were applied to the UTXO state as a
  * part of a single ActivateBestChainStep call.
  */
 struct ConnectTrace {
     std::vector<std::pair<CBlockIndex *, std::shared_ptr<const CBlock>>>
         blocksConnected;
 };
 
 /**
  * Connect a new block to chainActive. pblock is either nullptr or a pointer to
  * a CBlock corresponding to pindexNew, to bypass loading it again from disk.
  *
  * The block is always added to connectTrace (either after loading from disk or
  * by copying pblock) - if that is not intended, care must be taken to remove
  * the last entry in blocksConnected in case of failure.
  */
 static bool ConnectTip(const Config &config, CValidationState &state,
                        CBlockIndex *pindexNew,
                        const std::shared_ptr<const CBlock> &pblock,
                        ConnectTrace &connectTrace) {
     const CChainParams &chainparams = config.GetChainParams();
     assert(pindexNew->pprev == chainActive.Tip());
     // Read block from disk.
     int64_t nTime1 = GetTimeMicros();
     if (!pblock) {
         std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>();
         connectTrace.blocksConnected.emplace_back(pindexNew, pblockNew);
         if (!ReadBlockFromDisk(*pblockNew, pindexNew,
                                chainparams.GetConsensus()))
             return AbortNode(state, "Failed to read block");
     } else {
         connectTrace.blocksConnected.emplace_back(pindexNew, pblock);
     }
     const CBlock &blockConnecting = *connectTrace.blocksConnected.back().second;
     // Apply the block atomically to the chain state.
     int64_t nTime2 = GetTimeMicros();
     nTimeReadFromDisk += nTime2 - nTime1;
     int64_t nTime3;
     LogPrint("bench", "  - Load block from disk: %.2fms [%.2fs]\n",
              (nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001);
     {
         CCoinsViewCache view(pcoinsTip);
         bool rv = ConnectBlock(config, blockConnecting, state, pindexNew, view,
                                chainparams);
         GetMainSignals().BlockChecked(blockConnecting, state);
         if (!rv) {
             if (state.IsInvalid()) {
                 InvalidBlockFound(pindexNew, state);
             }
             return error("ConnectTip(): ConnectBlock %s failed",
                          pindexNew->GetBlockHash().ToString());
         }
         nTime3 = GetTimeMicros();
         nTimeConnectTotal += nTime3 - nTime2;
         LogPrint("bench", "  - Connect total: %.2fms [%.2fs]\n",
                  (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001);
         bool flushed = view.Flush();
         assert(flushed);
     }
     int64_t nTime4 = GetTimeMicros();
     nTimeFlush += nTime4 - nTime3;
     LogPrint("bench", "  - Flush: %.2fms [%.2fs]\n", (nTime4 - nTime3) * 0.001,
              nTimeFlush * 0.000001);
     // Write the chain state to disk, if necessary.
     if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED)) return false;
     int64_t nTime5 = GetTimeMicros();
     nTimeChainState += nTime5 - nTime4;
     LogPrint("bench", "  - Writing chainstate: %.2fms [%.2fs]\n",
              (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001);
     // Remove conflicting transactions from the mempool.;
     mempool.removeForBlock(blockConnecting.vtx, pindexNew->nHeight);
     // Update chainActive & related variables.
     UpdateTip(config, pindexNew);
 
     int64_t nTime6 = GetTimeMicros();
     nTimePostConnect += nTime6 - nTime5;
     nTimeTotal += nTime6 - nTime1;
     LogPrint("bench", "  - Connect postprocess: %.2fms [%.2fs]\n",
              (nTime6 - nTime5) * 0.001, nTimePostConnect * 0.000001);
     LogPrint("bench", "- Connect block: %.2fms [%.2fs]\n",
              (nTime6 - nTime1) * 0.001, nTimeTotal * 0.000001);
     return true;
 }
 
 /**
  * Return the tip of the chain with the most work in it, that isn't known to be
  * invalid (it's however far from certain to be valid).
  */
 static CBlockIndex *FindMostWorkChain() {
     do {
         CBlockIndex *pindexNew = nullptr;
 
         // Find the best candidate header.
         {
             std::set<CBlockIndex *, CBlockIndexWorkComparator>::reverse_iterator
                 it = setBlockIndexCandidates.rbegin();
             if (it == setBlockIndexCandidates.rend()) return nullptr;
             pindexNew = *it;
         }
 
         // Check whether all blocks on the path between the currently active
         // chain and the candidate are valid. Just going until the active chain
         // is an optimization, as we know all blocks in it are valid already.
         CBlockIndex *pindexTest = pindexNew;
         bool fInvalidAncestor = false;
         while (pindexTest && !chainActive.Contains(pindexTest)) {
             assert(pindexTest->nChainTx || pindexTest->nHeight == 0);
 
             // Pruned nodes may have entries in setBlockIndexCandidates for
             // which block files have been deleted. Remove those as candidates
             // for the most work chain if we come across them; we can't switch
             // to a chain unless we have all the non-active-chain parent blocks.
             bool fFailedChain = pindexTest->nStatus & BLOCK_FAILED_MASK;
             bool fMissingData = !(pindexTest->nStatus & BLOCK_HAVE_DATA);
             if (fFailedChain || fMissingData) {
                 // Candidate chain is not usable (either invalid or missing
                 // data)
                 if (fFailedChain &&
                     (pindexBestInvalid == nullptr ||
                      pindexNew->nChainWork > pindexBestInvalid->nChainWork))
                     pindexBestInvalid = pindexNew;
                 CBlockIndex *pindexFailed = pindexNew;
                 // Remove the entire chain from the set.
                 while (pindexTest != pindexFailed) {
                     if (fFailedChain) {
                         pindexFailed->nStatus |= BLOCK_FAILED_CHILD;
                     } else if (fMissingData) {
                         // If we're missing data, then add back to
                         // mapBlocksUnlinked, so that if the block arrives in
                         // the future we can try adding to
                         // setBlockIndexCandidates again.
                         mapBlocksUnlinked.insert(
                             std::make_pair(pindexFailed->pprev, pindexFailed));
                     }
                     setBlockIndexCandidates.erase(pindexFailed);
                     pindexFailed = pindexFailed->pprev;
                 }
                 setBlockIndexCandidates.erase(pindexTest);
                 fInvalidAncestor = true;
                 break;
             }
             pindexTest = pindexTest->pprev;
         }
         if (!fInvalidAncestor) return pindexNew;
     } while (true);
 }
 
 /** Delete all entries in setBlockIndexCandidates that are worse than the
  * current tip. */
 static void PruneBlockIndexCandidates() {
     // Note that we can't delete the current block itself, as we may need to
     // return to it later in case a reorganization to a better block fails.
     std::set<CBlockIndex *, CBlockIndexWorkComparator>::iterator it =
         setBlockIndexCandidates.begin();
     while (it != setBlockIndexCandidates.end() &&
            setBlockIndexCandidates.value_comp()(*it, chainActive.Tip())) {
         setBlockIndexCandidates.erase(it++);
     }
     // Either the current tip or a successor of it we're working towards is left
     // in setBlockIndexCandidates.
     assert(!setBlockIndexCandidates.empty());
 }
 
 /**
  * Try to make some progress towards making pindexMostWork the active block.
  * pblock is either nullptr or a pointer to a CBlock corresponding to
  * pindexMostWork.
  */
 static bool ActivateBestChainStep(const Config &config, CValidationState &state,
                                   CBlockIndex *pindexMostWork,
                                   const std::shared_ptr<const CBlock> &pblock,
                                   bool &fInvalidFound,
                                   ConnectTrace &connectTrace) {
     AssertLockHeld(cs_main);
     const CBlockIndex *pindexOldTip = chainActive.Tip();
     const CBlockIndex *pindexFork = chainActive.FindFork(pindexMostWork);
 
     // Disconnect active blocks which are no longer in the best chain.
     bool fBlocksDisconnected = false;
     while (chainActive.Tip() && chainActive.Tip() != pindexFork) {
         if (!DisconnectTip(config, state)) return false;
         fBlocksDisconnected = true;
     }
 
     // Build list of new blocks to connect.
     std::vector<CBlockIndex *> vpindexToConnect;
     bool fContinue = true;
     int nHeight = pindexFork ? pindexFork->nHeight : -1;
     while (fContinue && nHeight != pindexMostWork->nHeight) {
         // Don't iterate the entire list of potential improvements toward the
         // best tip, as we likely only need a few blocks along the way.
         int nTargetHeight = std::min(nHeight + 32, pindexMostWork->nHeight);
         vpindexToConnect.clear();
         vpindexToConnect.reserve(nTargetHeight - nHeight);
         CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight);
         while (pindexIter && pindexIter->nHeight != nHeight) {
             vpindexToConnect.push_back(pindexIter);
             pindexIter = pindexIter->pprev;
         }
         nHeight = nTargetHeight;
 
         // Connect new blocks.
         for (CBlockIndex *pindexConnect :
              boost::adaptors::reverse(vpindexToConnect)) {
             if (!ConnectTip(config, state, pindexConnect,
                             pindexConnect == pindexMostWork
                                 ? pblock
                                 : std::shared_ptr<const CBlock>(),
                             connectTrace)) {
                 if (state.IsInvalid()) {
                     // The block violates a consensus rule.
                     if (!state.CorruptionPossible())
                         InvalidChainFound(vpindexToConnect.back());
                     state = CValidationState();
                     fInvalidFound = true;
                     fContinue = false;
                     // If we didn't actually connect the block, don't notify
                     // listeners about it
                     connectTrace.blocksConnected.pop_back();
                     break;
                 } else {
                     // A system error occurred (disk space, database error,
                     // ...).
                     return false;
                 }
             } else {
                 PruneBlockIndexCandidates();
                 if (!pindexOldTip ||
                     chainActive.Tip()->nChainWork > pindexOldTip->nChainWork) {
                     // We're in a better position than we were. Return
                     // temporarily to release the lock.
                     fContinue = false;
                     break;
                 }
             }
         }
     }
 
     if (fBlocksDisconnected) {
         mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1,
                                STANDARD_LOCKTIME_VERIFY_FLAGS);
         LimitMempoolSize(
             mempool, GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000,
             GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
     }
     mempool.check(pcoinsTip);
 
     // Callbacks/notifications for a new best chain.
     if (fInvalidFound)
         CheckForkWarningConditionsOnNewFork(vpindexToConnect.back());
     else
         CheckForkWarningConditions();
 
     return true;
 }
 
 static void NotifyHeaderTip() {
     bool fNotify = false;
     bool fInitialBlockDownload = false;
     static CBlockIndex *pindexHeaderOld = nullptr;
     CBlockIndex *pindexHeader = nullptr;
     {
         LOCK(cs_main);
         pindexHeader = pindexBestHeader;
 
         if (pindexHeader != pindexHeaderOld) {
             fNotify = true;
             fInitialBlockDownload = IsInitialBlockDownload();
             pindexHeaderOld = pindexHeader;
         }
     }
     // Send block tip changed notifications without cs_main
     if (fNotify) {
         uiInterface.NotifyHeaderTip(fInitialBlockDownload, pindexHeader);
     }
 }
 
 /**
  * Make the best chain active, in multiple steps. The result is either failure
  * or an activated best chain. pblock is either nullptr or a pointer to a block
  * that is already loaded (to avoid loading it again from disk).
  */
 bool ActivateBestChain(const Config &config, CValidationState &state,
                        std::shared_ptr<const CBlock> pblock) {
     // Note that while we're often called here from ProcessNewBlock, this is
     // far from a guarantee. Things in the P2P/RPC will often end up calling
     // us in the middle of ProcessNewBlock - do not assume pblock is set
     // sanely for performance or correctness!
 
     CBlockIndex *pindexMostWork = nullptr;
     CBlockIndex *pindexNewTip = nullptr;
     do {
         boost::this_thread::interruption_point();
         if (ShutdownRequested()) break;
 
         const CBlockIndex *pindexFork;
         ConnectTrace connectTrace;
         bool fInitialDownload;
         {
             LOCK(cs_main);
             {
                 // TODO: Tempoarily ensure that mempool removals are notified
                 // before connected transactions. This shouldn't matter, but the
                 // abandoned state of transactions in our wallet is currently
                 // cleared when we receive another notification and there is a
                 // race condition where notification of a connected conflict
                 // might cause an outside process to abandon a transaction and
                 // then have it inadvertantly cleared by the notification that
                 // the conflicted transaction was evicted.
                 MemPoolConflictRemovalTracker mrt(mempool);
                 CBlockIndex *pindexOldTip = chainActive.Tip();
                 if (pindexMostWork == nullptr) {
                     pindexMostWork = FindMostWorkChain();
                 }
 
                 // Whether we have anything to do at all.
                 if (pindexMostWork == nullptr ||
                     pindexMostWork == chainActive.Tip())
                     return true;
 
                 bool fInvalidFound = false;
                 std::shared_ptr<const CBlock> nullBlockPtr;
                 if (!ActivateBestChainStep(
                         config, state, pindexMostWork,
                         pblock &&
                                 pblock->GetHash() ==
                                     pindexMostWork->GetBlockHash()
                             ? pblock
                             : nullBlockPtr,
                         fInvalidFound, connectTrace))
                     return false;
 
                 if (fInvalidFound) {
                     // Wipe cache, we may need another branch now.
                     pindexMostWork = nullptr;
                 }
                 pindexNewTip = chainActive.Tip();
                 pindexFork = chainActive.FindFork(pindexOldTip);
                 fInitialDownload = IsInitialBlockDownload();
 
                 // throw all transactions though the signal-interface
 
             } // MemPoolConflictRemovalTracker destroyed and conflict evictions
               // are notified
 
             // Transactions in the connnected block are notified
             for (const auto &pair : connectTrace.blocksConnected) {
                 assert(pair.second);
                 const CBlock &block = *(pair.second);
                 for (unsigned int i = 0; i < block.vtx.size(); i++)
                     GetMainSignals().SyncTransaction(*block.vtx[i], pair.first,
                                                      i);
             }
         }
         // When we reach this point, we switched to a new tip (stored in
         // pindexNewTip).
 
         // Notifications/callbacks that can run without cs_main
 
         // Notify external listeners about the new tip.
         GetMainSignals().UpdatedBlockTip(pindexNewTip, pindexFork,
                                          fInitialDownload);
 
         // Always notify the UI if a new block tip was connected
         if (pindexFork != pindexNewTip) {
             uiInterface.NotifyBlockTip(fInitialDownload, pindexNewTip);
         }
     } while (pindexNewTip != pindexMostWork);
     CheckBlockIndex(config.GetChainParams().GetConsensus());
 
     // Write changes periodically to disk, after relay.
     if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) {
         return false;
     }
 
     return true;
 }
 
 bool PreciousBlock(const Config &config, CValidationState &state,
                    CBlockIndex *pindex) {
     {
         LOCK(cs_main);
         if (pindex->nChainWork < chainActive.Tip()->nChainWork) {
             // Nothing to do, this block is not at the tip.
             return true;
         }
         if (chainActive.Tip()->nChainWork > nLastPreciousChainwork) {
             // The chain has been extended since the last call, reset the
             // counter.
             nBlockReverseSequenceId = -1;
         }
         nLastPreciousChainwork = chainActive.Tip()->nChainWork;
         setBlockIndexCandidates.erase(pindex);
         pindex->nSequenceId = nBlockReverseSequenceId;
         if (nBlockReverseSequenceId > std::numeric_limits<int32_t>::min()) {
             // We can't keep reducing the counter if somebody really wants to
             // call preciousblock 2**31-1 times on the same set of tips...
             nBlockReverseSequenceId--;
         }
         if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) && pindex->nChainTx) {
             setBlockIndexCandidates.insert(pindex);
             PruneBlockIndexCandidates();
         }
     }
 
     return ActivateBestChain(config, state);
 }
 
 bool InvalidateBlock(const Config &config, CValidationState &state,
                      CBlockIndex *pindex) {
     AssertLockHeld(cs_main);
 
     // Mark the block itself as invalid.
     pindex->nStatus |= BLOCK_FAILED_VALID;
     setDirtyBlockIndex.insert(pindex);
     setBlockIndexCandidates.erase(pindex);
 
     while (chainActive.Contains(pindex)) {
         CBlockIndex *pindexWalk = chainActive.Tip();
         pindexWalk->nStatus |= BLOCK_FAILED_CHILD;
         setDirtyBlockIndex.insert(pindexWalk);
         setBlockIndexCandidates.erase(pindexWalk);
         // ActivateBestChain considers blocks already in chainActive
         // unconditionally valid already, so force disconnect away from it.
         if (!DisconnectTip(config, state)) {
             mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1,
                                    STANDARD_LOCKTIME_VERIFY_FLAGS);
             return false;
         }
     }
 
     LimitMempoolSize(
         mempool, GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000,
         GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
 
     // The resulting new best tip may not be in setBlockIndexCandidates anymore,
     // so add it again.
     BlockMap::iterator it = mapBlockIndex.begin();
     while (it != mapBlockIndex.end()) {
         if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) &&
             it->second->nChainTx &&
             !setBlockIndexCandidates.value_comp()(it->second,
                                                   chainActive.Tip())) {
             setBlockIndexCandidates.insert(it->second);
         }
         it++;
     }
 
     InvalidChainFound(pindex);
     mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1,
                            STANDARD_LOCKTIME_VERIFY_FLAGS);
     uiInterface.NotifyBlockTip(IsInitialBlockDownload(), pindex->pprev);
     return true;
 }
 
 bool ResetBlockFailureFlags(CBlockIndex *pindex) {
     AssertLockHeld(cs_main);
 
     int nHeight = pindex->nHeight;
 
     // Remove the invalidity flag from this block and all its descendants.
     BlockMap::iterator it = mapBlockIndex.begin();
     while (it != mapBlockIndex.end()) {
         if (!it->second->IsValid() &&
             it->second->GetAncestor(nHeight) == pindex) {
             it->second->nStatus &= ~BLOCK_FAILED_MASK;
             setDirtyBlockIndex.insert(it->second);
             if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) &&
                 it->second->nChainTx &&
                 setBlockIndexCandidates.value_comp()(chainActive.Tip(),
                                                      it->second)) {
                 setBlockIndexCandidates.insert(it->second);
             }
             if (it->second == pindexBestInvalid) {
                 // Reset invalid block marker if it was pointing to one of
                 // those.
                 pindexBestInvalid = nullptr;
             }
         }
         it++;
     }
 
     // Remove the invalidity flag from all ancestors too.
     while (pindex != nullptr) {
         if (pindex->nStatus & BLOCK_FAILED_MASK) {
             pindex->nStatus &= ~BLOCK_FAILED_MASK;
             setDirtyBlockIndex.insert(pindex);
         }
         pindex = pindex->pprev;
     }
     return true;
 }
 
 CBlockIndex *AddToBlockIndex(const CBlockHeader &block) {
     // Check for duplicate
     uint256 hash = block.GetHash();
     BlockMap::iterator it = mapBlockIndex.find(hash);
     if (it != mapBlockIndex.end()) return it->second;
 
     // Construct new block index object
     CBlockIndex *pindexNew = new CBlockIndex(block);
     assert(pindexNew);
     // We assign the sequence id to blocks only when the full data is available,
     // to avoid miners withholding blocks but broadcasting headers, to get a
     // competitive advantage.
     pindexNew->nSequenceId = 0;
     BlockMap::iterator mi =
         mapBlockIndex.insert(std::make_pair(hash, pindexNew)).first;
     pindexNew->phashBlock = &((*mi).first);
     BlockMap::iterator miPrev = mapBlockIndex.find(block.hashPrevBlock);
     if (miPrev != mapBlockIndex.end()) {
         pindexNew->pprev = (*miPrev).second;
         pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
         pindexNew->BuildSkip();
     }
     pindexNew->nTimeMax =
         (pindexNew->pprev
              ? std::max(pindexNew->pprev->nTimeMax, pindexNew->nTime)
              : pindexNew->nTime);
     pindexNew->nChainWork =
         (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) +
         GetBlockProof(*pindexNew);
     pindexNew->RaiseValidity(BLOCK_VALID_TREE);
     if (pindexBestHeader == nullptr ||
         pindexBestHeader->nChainWork < pindexNew->nChainWork) {
         pindexBestHeader = pindexNew;
     }
 
     setDirtyBlockIndex.insert(pindexNew);
 
     return pindexNew;
 }
 
 /**
  * Mark a block as having its data received and checked (up to
  * BLOCK_VALID_TRANSACTIONS).
  */
 bool ReceivedBlockTransactions(const CBlock &block, CValidationState &state,
                                CBlockIndex *pindexNew,
                                const CDiskBlockPos &pos) {
     pindexNew->nTx = block.vtx.size();
     pindexNew->nChainTx = 0;
     pindexNew->nFile = pos.nFile;
     pindexNew->nDataPos = pos.nPos;
     pindexNew->nUndoPos = 0;
     pindexNew->nStatus |= BLOCK_HAVE_DATA;
     pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
     setDirtyBlockIndex.insert(pindexNew);
 
     if (pindexNew->pprev == nullptr || pindexNew->pprev->nChainTx) {
         // If pindexNew is the genesis block or all parents are
         // BLOCK_VALID_TRANSACTIONS.
         std::deque<CBlockIndex *> queue;
         queue.push_back(pindexNew);
 
         // Recursively process any descendant blocks that now may be eligible to
         // be connected.
         while (!queue.empty()) {
             CBlockIndex *pindex = queue.front();
             queue.pop_front();
             pindex->nChainTx =
                 (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx;
             {
                 LOCK(cs_nBlockSequenceId);
                 pindex->nSequenceId = nBlockSequenceId++;
             }
             if (chainActive.Tip() == nullptr ||
                 !setBlockIndexCandidates.value_comp()(pindex,
                                                       chainActive.Tip())) {
                 setBlockIndexCandidates.insert(pindex);
             }
             std::pair<std::multimap<CBlockIndex *, CBlockIndex *>::iterator,
                       std::multimap<CBlockIndex *, CBlockIndex *>::iterator>
                 range = mapBlocksUnlinked.equal_range(pindex);
             while (range.first != range.second) {
                 std::multimap<CBlockIndex *, CBlockIndex *>::iterator it =
                     range.first;
                 queue.push_back(it->second);
                 range.first++;
                 mapBlocksUnlinked.erase(it);
             }
         }
     } else {
         if (pindexNew->pprev && pindexNew->pprev->IsValid(BLOCK_VALID_TREE)) {
             mapBlocksUnlinked.insert(
                 std::make_pair(pindexNew->pprev, pindexNew));
         }
     }
 
     return true;
 }
 
 bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos,
                   unsigned int nAddSize, unsigned int nHeight, uint64_t nTime,
                   bool fKnown = false) {
     LOCK(cs_LastBlockFile);
 
     unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile;
     if (vinfoBlockFile.size() <= nFile) {
         vinfoBlockFile.resize(nFile + 1);
     }
 
     if (!fKnown) {
         while (vinfoBlockFile[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) {
             nFile++;
             if (vinfoBlockFile.size() <= nFile) {
                 vinfoBlockFile.resize(nFile + 1);
             }
         }
         pos.nFile = nFile;
         pos.nPos = vinfoBlockFile[nFile].nSize;
     }
 
     if ((int)nFile != nLastBlockFile) {
         if (!fKnown) {
             LogPrintf("Leaving block file %i: %s\n", nLastBlockFile,
                       vinfoBlockFile[nLastBlockFile].ToString());
         }
         FlushBlockFile(!fKnown);
         nLastBlockFile = nFile;
     }
 
     vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
     if (fKnown)
         vinfoBlockFile[nFile].nSize =
             std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize);
     else
         vinfoBlockFile[nFile].nSize += nAddSize;
 
     if (!fKnown) {
         unsigned int nOldChunks =
             (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
         unsigned int nNewChunks =
             (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) /
             BLOCKFILE_CHUNK_SIZE;
         if (nNewChunks > nOldChunks) {
             if (fPruneMode) fCheckForPruning = true;
             if (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) {
                 FILE *file = OpenBlockFile(pos);
                 if (file) {
                     LogPrintf(
                         "Pre-allocating up to position 0x%x in blk%05u.dat\n",
                         nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.nFile);
                     AllocateFileRange(file, pos.nPos,
                                       nNewChunks * BLOCKFILE_CHUNK_SIZE -
                                           pos.nPos);
                     fclose(file);
                 }
             } else
                 return state.Error("out of disk space");
         }
     }
 
     setDirtyFileInfo.insert(nFile);
     return true;
 }
 
 bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos,
                  unsigned int nAddSize) {
     pos.nFile = nFile;
 
     LOCK(cs_LastBlockFile);
 
     unsigned int nNewSize;
     pos.nPos = vinfoBlockFile[nFile].nUndoSize;
     nNewSize = vinfoBlockFile[nFile].nUndoSize += nAddSize;
     setDirtyFileInfo.insert(nFile);
 
     unsigned int nOldChunks =
         (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
     unsigned int nNewChunks =
         (nNewSize + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
     if (nNewChunks > nOldChunks) {
         if (fPruneMode) fCheckForPruning = true;
         if (CheckDiskSpace(nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos)) {
             FILE *file = OpenUndoFile(pos);
             if (file) {
                 LogPrintf("Pre-allocating up to position 0x%x in rev%05u.dat\n",
                           nNewChunks * UNDOFILE_CHUNK_SIZE, pos.nFile);
                 AllocateFileRange(file, pos.nPos,
                                   nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos);
                 fclose(file);
             }
         } else
             return state.Error("out of disk space");
     }
 
     return true;
 }
 
 bool CheckBlockHeader(const CBlockHeader &block, CValidationState &state,
                       const Consensus::Params &consensusParams,
                       bool fCheckPOW) {
     // Check proof of work matches claimed amount
     if (fCheckPOW &&
         !CheckProofOfWork(block.GetHash(), block.nBits, consensusParams))
         return state.DoS(50, false, REJECT_INVALID, "high-hash", false,
                          "proof of work failed");
 
     return true;
 }
 
 bool CheckBlock(const Config &config, const CBlock &block,
                 CValidationState &state,
                 const Consensus::Params &consensusParams, bool fCheckPOW,
                 bool fCheckMerkleRoot) {
     // These are checks that are independent of context.
     if (block.fChecked) {
         return true;
     }
 
     // Check that the header is valid (particularly PoW).  This is mostly
     // redundant with the call in AcceptBlockHeader.
     if (!CheckBlockHeader(block, state, consensusParams, fCheckPOW)) {
         return false;
     }
 
     // Check the merkle root.
     if (fCheckMerkleRoot) {
         bool mutated;
         uint256 hashMerkleRoot2 = BlockMerkleRoot(block, &mutated);
         if (block.hashMerkleRoot != hashMerkleRoot2) {
             return state.DoS(100, false, REJECT_INVALID, "bad-txnmrklroot",
                              true, "hashMerkleRoot mismatch");
         }
 
         // Check for merkle tree malleability (CVE-2012-2459): repeating
         // sequences of transactions in a block without affecting the merkle
         // root of a block, while still invalidating it.
         if (mutated) {
             return state.DoS(100, false, REJECT_INVALID, "bad-txns-duplicate",
                              true, "duplicate transaction");
         }
     }
 
     // All potential-corruption validation must be done before we do any
     // transaction validation, as otherwise we may mark the header as invalid
     // because we receive the wrong transactions for it.
 
     // First transaction must be coinbase.
     if (block.vtx.empty()) {
         return state.DoS(100, false, REJECT_INVALID, "bad-cb-missing", false,
                          "first tx is not coinbase");
     }
 
     // Size limits.
     auto nMaxBlockSize = config.GetMaxBlockSize();
 
     // Bail early if there is no way this block is of reasonable size.
     if ((block.vtx.size() * MIN_TRANSACTION_SIZE) > nMaxBlockSize) {
         return state.DoS(100, false, REJECT_INVALID, "bad-blk-length", false,
                          "size limits failed");
     }
 
     auto currentBlockSize =
         ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION);
     if (currentBlockSize > nMaxBlockSize) {
         return state.DoS(100, false, REJECT_INVALID, "bad-blk-length", false,
                          "size limits failed");
     }
 
     // And a valid coinbase.
     if (!CheckCoinbase(*block.vtx[0], state, false)) {
         return state.Invalid(false, state.GetRejectCode(),
                              state.GetRejectReason(),
                              strprintf("Coinbase check failed (txid %s) %s",
                                        block.vtx[0]->GetId().ToString(),
                                        state.GetDebugMessage()));
     }
 
     // Keep track of the sigops count.
     uint64_t nSigOps = 0;
     auto nMaxSigOpsCount = GetMaxBlockSigOpsCount(currentBlockSize);
 
     // Check transactions
     auto txCount = block.vtx.size();
     auto *tx = block.vtx[0].get();
 
     size_t i = 0;
     while (true) {
         // Count the sigops for the current transaction. If the total sigops
         // count is too high, the the block is invalid.
         nSigOps += GetSigOpCountWithoutP2SH(*tx);
         if (nSigOps > nMaxSigOpsCount) {
             return state.DoS(100, false, REJECT_INVALID, "bad-blk-sigops",
                              false, "out-of-bounds SigOpCount");
         }
 
         // Go to the next transaction.
         i++;
 
         // We reached the end of the block, success.
         if (i >= txCount) {
             break;
         }
 
         // Check that the transaction is valid. because this check differs for
         // the coinbase, the loos is arranged such as this only runs after at
         // least one increment.
         tx = block.vtx[i].get();
         if (!CheckRegularTransaction(*tx, state, false)) {
             return state.Invalid(
                 false, state.GetRejectCode(), state.GetRejectReason(),
                 strprintf("Transaction check failed (txid %s) %s",
                           tx->GetId().ToString(), state.GetDebugMessage()));
         }
     }
 
     if (fCheckPOW && fCheckMerkleRoot) {
         block.fChecked = true;
     }
 
     return true;
 }
 
 static bool CheckIndexAgainstCheckpoint(const CBlockIndex *pindexPrev,
                                         CValidationState &state,
                                         const CChainParams &chainparams,
                                         const uint256 &hash) {
     if (*pindexPrev->phashBlock ==
         chainparams.GetConsensus().hashGenesisBlock) {
         return true;
     }
 
     int nHeight = pindexPrev->nHeight + 1;
     // Don't accept any forks from the main chain prior to last checkpoint
     CBlockIndex *pcheckpoint =
         Checkpoints::GetLastCheckpoint(chainparams.Checkpoints());
     if (pcheckpoint && nHeight < pcheckpoint->nHeight) {
         return state.DoS(
             100,
             error("%s: forked chain older than last checkpoint (height %d)",
                   __func__, nHeight));
     }
 
     return true;
 }
 
 bool ContextualCheckBlockHeader(const CBlockHeader &block,
                                 CValidationState &state,
                                 const Consensus::Params &consensusParams,
                                 const CBlockIndex *pindexPrev,
                                 int64_t nAdjustedTime) {
     const int nHeight = pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1;
 
     // Check proof of work
     if (block.nBits !=
         GetNextWorkRequired(pindexPrev, &block, consensusParams)) {
         return state.DoS(100, false, REJECT_INVALID, "bad-diffbits", false,
                          "incorrect proof of work");
     }
 
     // Check timestamp against prev
     if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast()) {
         return state.Invalid(false, REJECT_INVALID, "time-too-old",
                              "block's timestamp is too early");
     }
 
     // Check timestamp
     if (block.GetBlockTime() > nAdjustedTime + 2 * 60 * 60) {
         return state.Invalid(false, REJECT_INVALID, "time-too-new",
                              "block timestamp too far in the future");
     }
 
     // Reject outdated version blocks when 95% (75% on testnet) of the network
     // has upgraded:
     // check for version 2, 3 and 4 upgrades
     if ((block.nVersion < 2 && nHeight >= consensusParams.BIP34Height) ||
         (block.nVersion < 3 && nHeight >= consensusParams.BIP66Height) ||
         (block.nVersion < 4 && nHeight >= consensusParams.BIP65Height)) {
         return state.Invalid(
             false, REJECT_OBSOLETE,
             strprintf("bad-version(0x%08x)", block.nVersion),
             strprintf("rejected nVersion=0x%08x block", block.nVersion));
     }
 
     return true;
 }
 
 bool ContextualCheckTransaction(const Config &config, const CTransaction &tx,
                                 CValidationState &state,
                                 const Consensus::Params &consensusParams,
                                 int nHeight, int64_t nLockTimeCutoff,
                                 int64_t nMedianTimePast) {
     if (!IsFinalTx(tx, nHeight, nLockTimeCutoff)) {
         // While this is only one transaction, we use txns in the error to
         // ensure continuity with other clients.
         return state.DoS(10, false, REJECT_INVALID, "bad-txns-nonfinal", false,
                          "non-final transaction");
     }
 
     if (IsUAHFenabled(config, nMedianTimePast) &&
         nHeight <= consensusParams.antiReplayOpReturnSunsetHeight) {
         for (const CTxOut &o : tx.vout) {
             if (o.scriptPubKey.IsCommitment(
                     consensusParams.antiReplayOpReturnCommitment)) {
                 return state.DoS(10, false, REJECT_INVALID, "bad-txn-replay",
                                  false, "non playable transaction");
             }
         }
     }
 
     return true;
 }
 
 bool ContextualCheckTransactionForCurrentBlock(
     const Config &config, const CTransaction &tx, CValidationState &state,
     const Consensus::Params &consensusParams, int flags) {
     AssertLockHeld(cs_main);
 
     // By convention a negative value for flags indicates that the current
     // network-enforced consensus rules should be used. In a future soft-fork
     // scenario that would mean checking which rules would be enforced for the
     // next block and setting the appropriate flags. At the present time no
     // soft-forks are scheduled, so no flags are set.
     flags = std::max(flags, 0);
 
     // ContextualCheckTransactionForCurrentBlock() uses chainActive.Height()+1
     // to evaluate nLockTime because when IsFinalTx() is called within
     // CBlock::AcceptBlock(), the height of the block *being* evaluated is what
     // is used. Thus if we want to know if a transaction can be part of the
     // *next* block, we need to call ContextualCheckTransaction() with one more
     // than chainActive.Height().
     const int nBlockHeight = chainActive.Height() + 1;
 
     // BIP113 will require that time-locked transactions have nLockTime set to
     // less than the median time of the previous block they're contained in.
     // When the next block is created its previous block will be the current
     // chain tip, so we use that to calculate the median time passed to
     // ContextualCheckTransaction() if LOCKTIME_MEDIAN_TIME_PAST is set.
     const int64_t nMedianTimePast = chainActive.Tip()->GetMedianTimePast();
     const int64_t nLockTimeCutoff = (flags & LOCKTIME_MEDIAN_TIME_PAST)
                                         ? nMedianTimePast
                                         : GetAdjustedTime();
 
     return ContextualCheckTransaction(config, tx, state, consensusParams,
                                       nBlockHeight, nLockTimeCutoff,
                                       nMedianTimePast);
 }
 
 bool ContextualCheckBlock(const Config &config, const CBlock &block,
                           CValidationState &state,
                           const Consensus::Params &consensusParams,
                           const CBlockIndex *pindexPrev) {
     const int nHeight = pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1;
 
     // Start enforcing BIP113 (Median Time Past) using versionbits logic.
     int nLockTimeFlags = 0;
     if (VersionBitsState(pindexPrev, consensusParams, Consensus::DEPLOYMENT_CSV,
                          versionbitscache) == THRESHOLD_ACTIVE) {
         nLockTimeFlags |= LOCKTIME_MEDIAN_TIME_PAST;
     }
 
     const int64_t nMedianTimePast =
         pindexPrev == nullptr ? 0 : pindexPrev->GetMedianTimePast();
 
     const int64_t nLockTimeCutoff = (nLockTimeFlags & LOCKTIME_MEDIAN_TIME_PAST)
                                         ? nMedianTimePast
                                         : block.GetBlockTime();
 
     // Check that all transactions are finalized
     for (const auto &tx : block.vtx) {
         if (!ContextualCheckTransaction(config, *tx, state, consensusParams,
                                         nHeight, nLockTimeCutoff,
                                         nMedianTimePast)) {
             // state set by ContextualCheckTransaction.
             return false;
         }
     }
 
     // Enforce rule that the coinbase starts with serialized block height
     if (nHeight >= consensusParams.BIP34Height) {
         CScript expect = CScript() << nHeight;
         if (block.vtx[0]->vin[0].scriptSig.size() < expect.size() ||
             !std::equal(expect.begin(), expect.end(),
                         block.vtx[0]->vin[0].scriptSig.begin())) {
             return state.DoS(100, false, REJECT_INVALID, "bad-cb-height", false,
                              "block height mismatch in coinbase");
         }
     }
 
     return true;
 }
 
 static bool AcceptBlockHeader(const Config &config, const CBlockHeader &block,
                               CValidationState &state, CBlockIndex **ppindex) {
     AssertLockHeld(cs_main);
     const CChainParams &chainparams = config.GetChainParams();
 
     // Check for duplicate
     uint256 hash = block.GetHash();
     BlockMap::iterator miSelf = mapBlockIndex.find(hash);
     CBlockIndex *pindex = nullptr;
     if (hash != chainparams.GetConsensus().hashGenesisBlock) {
         if (miSelf != mapBlockIndex.end()) {
             // Block header is already known.
             pindex = miSelf->second;
             if (ppindex) {
                 *ppindex = pindex;
             }
             if (pindex->nStatus & BLOCK_FAILED_MASK) {
                 return state.Invalid(error("%s: block %s is marked invalid",
                                            __func__, hash.ToString()),
                                      0, "duplicate");
             }
             return true;
         }
 
         if (!CheckBlockHeader(block, state, chainparams.GetConsensus())) {
             return error("%s: Consensus::CheckBlockHeader: %s, %s", __func__,
                          hash.ToString(), FormatStateMessage(state));
         }
 
         // Get prev block index
         CBlockIndex *pindexPrev = nullptr;
         BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock);
         if (mi == mapBlockIndex.end()) {
             return state.DoS(10, error("%s: prev block not found", __func__), 0,
                              "bad-prevblk");
         }
         pindexPrev = (*mi).second;
         if (pindexPrev->nStatus & BLOCK_FAILED_MASK) {
             return state.DoS(100, error("%s: prev block invalid", __func__),
                              REJECT_INVALID, "bad-prevblk");
         }
 
         assert(pindexPrev);
         if (fCheckpointsEnabled &&
             !CheckIndexAgainstCheckpoint(pindexPrev, state, chainparams,
                                          hash)) {
             return error("%s: CheckIndexAgainstCheckpoint(): %s", __func__,
                          state.GetRejectReason().c_str());
         }
 
         if (!ContextualCheckBlockHeader(block, state,
                                         chainparams.GetConsensus(), pindexPrev,
                                         GetAdjustedTime())) {
             return error("%s: Consensus::ContextualCheckBlockHeader: %s, %s",
                          __func__, hash.ToString(), FormatStateMessage(state));
         }
     }
 
     if (pindex == nullptr) {
         pindex = AddToBlockIndex(block);
     }
 
     if (ppindex) {
         *ppindex = pindex;
     }
 
     CheckBlockIndex(chainparams.GetConsensus());
 
     return true;
 }
 
 // Exposed wrapper for AcceptBlockHeader
 bool ProcessNewBlockHeaders(const Config &config,
                             const std::vector<CBlockHeader> &headers,
                             CValidationState &state,
                             const CBlockIndex **ppindex) {
     {
         LOCK(cs_main);
         for (const CBlockHeader &header : headers) {
             // Use a temp pindex instead of ppindex to avoid a const_cast
             CBlockIndex *pindex = nullptr;
             if (!AcceptBlockHeader(config, header, state, &pindex)) {
                 return false;
             }
             if (ppindex) {
                 *ppindex = pindex;
             }
         }
     }
     NotifyHeaderTip();
     return true;
 }
 
 /**
  * Store block on disk. If dbp is non-null, the file is known to already reside
  * on disk.
  */
 static bool AcceptBlock(const Config &config,
                         const std::shared_ptr<const CBlock> &pblock,
                         CValidationState &state, CBlockIndex **ppindex,
                         bool fRequested, const CDiskBlockPos *dbp,
                         bool *fNewBlock) {
     AssertLockHeld(cs_main);
 
     const CBlock &block = *pblock;
     if (fNewBlock) {
         *fNewBlock = false;
     }
 
     CBlockIndex *pindexDummy = nullptr;
     CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy;
 
     if (!AcceptBlockHeader(config, block, state, &pindex)) {
         return false;
     }
 
     // Try to process all requested blocks that we don't have, but only
     // process an unrequested block if it's new and has enough work to
     // advance our tip, and isn't too many blocks ahead.
     bool fAlreadyHave = pindex->nStatus & BLOCK_HAVE_DATA;
     bool fHasMoreWork =
         (chainActive.Tip() ? pindex->nChainWork > chainActive.Tip()->nChainWork
                            : true);
     // Blocks that are too out-of-order needlessly limit the effectiveness of
     // pruning, because pruning will not delete block files that contain any
     // blocks which are too close in height to the tip.  Apply this test
     // regardless of whether pruning is enabled; it should generally be safe to
     // not process unrequested blocks.
     bool fTooFarAhead =
         (pindex->nHeight > int(chainActive.Height() + MIN_BLOCKS_TO_KEEP));
 
     // TODO: Decouple this function from the block download logic by removing
     // fRequested
     // This requires some new chain datastructure to efficiently look up if a
     // block is in a chain leading to a candidate for best tip, despite not
     // being such a candidate itself.
 
     // TODO: deal better with return value and error conditions for duplicate
     // and unrequested blocks.
     if (fAlreadyHave) {
         return true;
     }
 
     // If we didn't ask for it:
     if (!fRequested) {
         // This is a previously-processed block that was pruned.
         if (pindex->nTx != 0) {
             return true;
         }
 
         // Don't process less-work chains.
         if (!fHasMoreWork) {
             return true;
         }
 
         // Block height is too high.
         if (fTooFarAhead) {
             return true;
         }
     }
 
     if (fNewBlock) {
         *fNewBlock = true;
     }
 
     const CChainParams &chainparams = config.GetChainParams();
     if (!CheckBlock(config, block, state, chainparams.GetConsensus()) ||
         !ContextualCheckBlock(config, block, state, chainparams.GetConsensus(),
                               pindex->pprev)) {
         if (state.IsInvalid() && !state.CorruptionPossible()) {
             pindex->nStatus |= BLOCK_FAILED_VALID;
             setDirtyBlockIndex.insert(pindex);
         }
         return error("%s: %s (block %s)", __func__, FormatStateMessage(state),
                      block.GetHash().ToString());
     }
 
     // Header is valid/has work, merkle tree and segwit merkle tree are
     // good...RELAY NOW (but if it does not build on our best tip, let the
     // SendMessages loop relay it)
     if (!IsInitialBlockDownload() && chainActive.Tip() == pindex->pprev) {
         GetMainSignals().NewPoWValidBlock(pindex, pblock);
     }
 
     int nHeight = pindex->nHeight;
 
     // Write block to history file
     try {
         unsigned int nBlockSize =
             ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
         CDiskBlockPos blockPos;
         if (dbp != nullptr) {
             blockPos = *dbp;
         }
         if (!FindBlockPos(state, blockPos, nBlockSize + 8, nHeight,
                           block.GetBlockTime(), dbp != nullptr)) {
             return error("AcceptBlock(): FindBlockPos failed");
         }
         if (dbp == nullptr) {
             if (!WriteBlockToDisk(block, blockPos,
                                   chainparams.MessageStart())) {
                 AbortNode(state, "Failed to write block");
             }
         }
         if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) {
             return error("AcceptBlock(): ReceivedBlockTransactions failed");
         }
     } catch (const std::runtime_error &e) {
         return AbortNode(state, std::string("System error: ") + e.what());
     }
 
     if (fCheckForPruning) {
         // we just allocated more disk space for block files.
         FlushStateToDisk(state, FLUSH_STATE_NONE);
     }
 
     return true;
 }
 
 bool ProcessNewBlock(const Config &config,
                      const std::shared_ptr<const CBlock> pblock,
                      bool fForceProcessing, bool *fNewBlock) {
     {
         CBlockIndex *pindex = nullptr;
         if (fNewBlock) *fNewBlock = false;
 
         const CChainParams &chainparams = config.GetChainParams();
 
         CValidationState state;
         // Ensure that CheckBlock() passes before calling AcceptBlock, as
         // belt-and-suspenders.
         bool ret =
             CheckBlock(config, *pblock, state, chainparams.GetConsensus());
 
         LOCK(cs_main);
 
         if (ret) {
             // Store to disk
             ret = AcceptBlock(config, pblock, state, &pindex, fForceProcessing,
                               nullptr, fNewBlock);
         }
         CheckBlockIndex(chainparams.GetConsensus());
         if (!ret) {
             GetMainSignals().BlockChecked(*pblock, state);
             return error("%s: AcceptBlock FAILED", __func__);
         }
     }
 
     NotifyHeaderTip();
 
     // Only used to report errors, not invalidity - ignore it
     CValidationState state;
     if (!ActivateBestChain(config, state, pblock))
         return error("%s: ActivateBestChain failed", __func__);
 
     return true;
 }
 
 bool TestBlockValidity(const Config &config, CValidationState &state,
                        const CChainParams &chainparams, const CBlock &block,
                        CBlockIndex *pindexPrev, bool fCheckPOW,
                        bool fCheckMerkleRoot) {
     AssertLockHeld(cs_main);
     assert(pindexPrev && pindexPrev == chainActive.Tip());
     if (fCheckpointsEnabled &&
         !CheckIndexAgainstCheckpoint(pindexPrev, state, chainparams,
                                      block.GetHash())) {
         return error("%s: CheckIndexAgainstCheckpoint(): %s", __func__,
                      state.GetRejectReason().c_str());
     }
 
     CCoinsViewCache viewNew(pcoinsTip);
     CBlockIndex indexDummy(block);
     indexDummy.pprev = pindexPrev;
     indexDummy.nHeight = pindexPrev->nHeight + 1;
 
     // NOTE: CheckBlockHeader is called by CheckBlock
     if (!ContextualCheckBlockHeader(block, state, chainparams.GetConsensus(),
                                     pindexPrev, GetAdjustedTime())) {
         return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__,
                      FormatStateMessage(state));
     }
     if (!CheckBlock(config, block, state, chainparams.GetConsensus(), fCheckPOW,
                     fCheckMerkleRoot)) {
         return error("%s: Consensus::CheckBlock: %s", __func__,
                      FormatStateMessage(state));
     }
     if (!ContextualCheckBlock(config, block, state, chainparams.GetConsensus(),
                               pindexPrev)) {
         return error("%s: Consensus::ContextualCheckBlock: %s", __func__,
                      FormatStateMessage(state));
     }
     if (!ConnectBlock(config, block, state, &indexDummy, viewNew, chainparams,
                       true)) {
         return false;
     }
 
     assert(state.IsValid());
     return true;
 }
 
 /**
  * BLOCK PRUNING CODE
  */
 
 /* Calculate the amount of disk space the block & undo files currently use */
 uint64_t CalculateCurrentUsage() {
     uint64_t retval = 0;
     for (const CBlockFileInfo &file : vinfoBlockFile) {
         retval += file.nSize + file.nUndoSize;
     }
     return retval;
 }
 
 /* Prune a block file (modify associated database entries)*/
 void PruneOneBlockFile(const int fileNumber) {
     for (BlockMap::iterator it = mapBlockIndex.begin();
          it != mapBlockIndex.end(); ++it) {
         CBlockIndex *pindex = it->second;
         if (pindex->nFile == fileNumber) {
             pindex->nStatus &= ~BLOCK_HAVE_DATA;
             pindex->nStatus &= ~BLOCK_HAVE_UNDO;
             pindex->nFile = 0;
             pindex->nDataPos = 0;
             pindex->nUndoPos = 0;
             setDirtyBlockIndex.insert(pindex);
 
             // Prune from mapBlocksUnlinked -- any block we prune would have
             // to be downloaded again in order to consider its chain, at which
             // point it would be considered as a candidate for
             // mapBlocksUnlinked or setBlockIndexCandidates.
             std::pair<std::multimap<CBlockIndex *, CBlockIndex *>::iterator,
                       std::multimap<CBlockIndex *, CBlockIndex *>::iterator>
                 range = mapBlocksUnlinked.equal_range(pindex->pprev);
             while (range.first != range.second) {
                 std::multimap<CBlockIndex *, CBlockIndex *>::iterator _it =
                     range.first;
                 range.first++;
                 if (_it->second == pindex) {
                     mapBlocksUnlinked.erase(_it);
                 }
             }
         }
     }
 
     vinfoBlockFile[fileNumber].SetNull();
     setDirtyFileInfo.insert(fileNumber);
 }
 
 void UnlinkPrunedFiles(const std::set<int> &setFilesToPrune) {
     for (std::set<int>::iterator it = setFilesToPrune.begin();
          it != setFilesToPrune.end(); ++it) {
         CDiskBlockPos pos(*it, 0);
         boost::filesystem::remove(GetBlockPosFilename(pos, "blk"));
         boost::filesystem::remove(GetBlockPosFilename(pos, "rev"));
         LogPrintf("Prune: %s deleted blk/rev (%05u)\n", __func__, *it);
     }
 }
 
 /**
  * Calculate the block/rev files to delete based on height specified by user
  * with RPC command pruneblockchain.
  */
 void FindFilesToPruneManual(std::set<int> &setFilesToPrune,
                             int nManualPruneHeight) {
     assert(fPruneMode && nManualPruneHeight > 0);
 
     LOCK2(cs_main, cs_LastBlockFile);
     if (chainActive.Tip() == nullptr) {
         return;
     }
 
     // last block to prune is the lesser of (user-specified height,
     // MIN_BLOCKS_TO_KEEP from the tip)
     unsigned int nLastBlockWeCanPrune =
         std::min((unsigned)nManualPruneHeight,
                  chainActive.Tip()->nHeight - MIN_BLOCKS_TO_KEEP);
     int count = 0;
     for (int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) {
         if (vinfoBlockFile[fileNumber].nSize == 0 ||
             vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune) {
             continue;
         }
         PruneOneBlockFile(fileNumber);
         setFilesToPrune.insert(fileNumber);
         count++;
     }
     LogPrintf("Prune (Manual): prune_height=%d removed %d blk/rev pairs\n",
               nLastBlockWeCanPrune, count);
 }
 
 /* This function is called from the RPC code for pruneblockchain */
 void PruneBlockFilesManual(int nManualPruneHeight) {
     CValidationState state;
     FlushStateToDisk(state, FLUSH_STATE_NONE, nManualPruneHeight);
 }
 
 /* Calculate the block/rev files that should be deleted to remain under target*/
 void FindFilesToPrune(std::set<int> &setFilesToPrune,
                       uint64_t nPruneAfterHeight) {
     LOCK2(cs_main, cs_LastBlockFile);
     if (chainActive.Tip() == nullptr || nPruneTarget == 0) {
         return;
     }
     if (uint64_t(chainActive.Tip()->nHeight) <= nPruneAfterHeight) {
         return;
     }
 
     unsigned int nLastBlockWeCanPrune =
         chainActive.Tip()->nHeight - MIN_BLOCKS_TO_KEEP;
     uint64_t nCurrentUsage = CalculateCurrentUsage();
     // We don't check to prune until after we've allocated new space for files,
     // so we should leave a buffer under our target to account for another
     // allocation before the next pruning.
     uint64_t nBuffer = BLOCKFILE_CHUNK_SIZE + UNDOFILE_CHUNK_SIZE;
     uint64_t nBytesToPrune;
     int count = 0;
 
     if (nCurrentUsage + nBuffer >= nPruneTarget) {
         for (int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) {
             nBytesToPrune = vinfoBlockFile[fileNumber].nSize +
                             vinfoBlockFile[fileNumber].nUndoSize;
 
             if (vinfoBlockFile[fileNumber].nSize == 0) {
                 continue;
             }
 
             // are we below our target?
             if (nCurrentUsage + nBuffer < nPruneTarget) {
                 break;
             }
 
             // don't prune files that could have a block within
             // MIN_BLOCKS_TO_KEEP of the main chain's tip but keep scanning
             if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune) {
                 continue;
             }
 
             PruneOneBlockFile(fileNumber);
             // Queue up the files for removal
             setFilesToPrune.insert(fileNumber);
             nCurrentUsage -= nBytesToPrune;
             count++;
         }
     }
 
     LogPrint("prune", "Prune: target=%dMiB actual=%dMiB diff=%dMiB "
                       "max_prune_height=%d removed %d blk/rev pairs\n",
              nPruneTarget / 1024 / 1024, nCurrentUsage / 1024 / 1024,
              ((int64_t)nPruneTarget - (int64_t)nCurrentUsage) / 1024 / 1024,
              nLastBlockWeCanPrune, count);
 }
 
 bool CheckDiskSpace(uint64_t nAdditionalBytes) {
     uint64_t nFreeBytesAvailable =
         boost::filesystem::space(GetDataDir()).available;
 
     // Check for nMinDiskSpace bytes (currently 50MB)
     if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes)
         return AbortNode("Disk space is low!", _("Error: Disk space is low!"));
 
     return true;
 }
 
 FILE *OpenDiskFile(const CDiskBlockPos &pos, const char *prefix,
                    bool fReadOnly) {
     if (pos.IsNull()) return nullptr;
     boost::filesystem::path path = GetBlockPosFilename(pos, prefix);
     boost::filesystem::create_directories(path.parent_path());
     FILE *file = fopen(path.string().c_str(), "rb+");
     if (!file && !fReadOnly) file = fopen(path.string().c_str(), "wb+");
     if (!file) {
         LogPrintf("Unable to open file %s\n", path.string());
         return nullptr;
     }
     if (pos.nPos) {
         if (fseek(file, pos.nPos, SEEK_SET)) {
             LogPrintf("Unable to seek to position %u of %s\n", pos.nPos,
                       path.string());
             fclose(file);
             return nullptr;
         }
     }
     return file;
 }
 
 FILE *OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly) {
     return OpenDiskFile(pos, "blk", fReadOnly);
 }
 
 FILE *OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly) {
     return OpenDiskFile(pos, "rev", fReadOnly);
 }
 
 boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos,
                                             const char *prefix) {
     return GetDataDir() / "blocks" / strprintf("%s%05u.dat", prefix, pos.nFile);
 }
 
 CBlockIndex *InsertBlockIndex(uint256 hash) {
     if (hash.IsNull()) return nullptr;
 
     // Return existing
     BlockMap::iterator mi = mapBlockIndex.find(hash);
     if (mi != mapBlockIndex.end()) return (*mi).second;
 
     // Create new
     CBlockIndex *pindexNew = new CBlockIndex();
     if (!pindexNew)
         throw std::runtime_error(std::string(__func__) +
                                  ": new CBlockIndex failed");
     mi = mapBlockIndex.insert(std::make_pair(hash, pindexNew)).first;
     pindexNew->phashBlock = &((*mi).first);
 
     return pindexNew;
 }
 
 static bool LoadBlockIndexDB(const CChainParams &chainparams) {
     if (!pblocktree->LoadBlockIndexGuts(InsertBlockIndex)) return false;
 
     boost::this_thread::interruption_point();
 
     // Calculate nChainWork
     std::vector<std::pair<int, CBlockIndex *>> vSortedByHeight;
     vSortedByHeight.reserve(mapBlockIndex.size());
     for (const std::pair<uint256, CBlockIndex *> &item : mapBlockIndex) {
         CBlockIndex *pindex = item.second;
         vSortedByHeight.push_back(std::make_pair(pindex->nHeight, pindex));
     }
     sort(vSortedByHeight.begin(), vSortedByHeight.end());
     for (const std::pair<int, CBlockIndex *> &item : vSortedByHeight) {
         CBlockIndex *pindex = item.second;
         pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) +
                              GetBlockProof(*pindex);
         pindex->nTimeMax =
             (pindex->pprev ? std::max(pindex->pprev->nTimeMax, pindex->nTime)
                            : pindex->nTime);
         // We can link the chain of blocks for which we've received transactions
         // at some point. Pruned nodes may have deleted the block.
         if (pindex->nTx > 0) {
             if (pindex->pprev) {
                 if (pindex->pprev->nChainTx) {
                     pindex->nChainTx = pindex->pprev->nChainTx + pindex->nTx;
                 } else {
                     pindex->nChainTx = 0;
                     mapBlocksUnlinked.insert(
                         std::make_pair(pindex->pprev, pindex));
                 }
             } else {
                 pindex->nChainTx = pindex->nTx;
             }
         }
         if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) &&
             (pindex->nChainTx || pindex->pprev == nullptr)) {
             setBlockIndexCandidates.insert(pindex);
         }
         if (pindex->nStatus & BLOCK_FAILED_MASK &&
             (!pindexBestInvalid ||
              pindex->nChainWork > pindexBestInvalid->nChainWork)) {
             pindexBestInvalid = pindex;
         }
         if (pindex->pprev) {
             pindex->BuildSkip();
         }
         if (pindex->IsValid(BLOCK_VALID_TREE) &&
             (pindexBestHeader == nullptr ||
              CBlockIndexWorkComparator()(pindexBestHeader, pindex))) {
             pindexBestHeader = pindex;
         }
     }
 
     // Load block file info
     pblocktree->ReadLastBlockFile(nLastBlockFile);
     vinfoBlockFile.resize(nLastBlockFile + 1);
     LogPrintf("%s: last block file = %i\n", __func__, nLastBlockFile);
     for (int nFile = 0; nFile <= nLastBlockFile; nFile++) {
         pblocktree->ReadBlockFileInfo(nFile, vinfoBlockFile[nFile]);
     }
     LogPrintf("%s: last block file info: %s\n", __func__,
               vinfoBlockFile[nLastBlockFile].ToString());
     for (int nFile = nLastBlockFile + 1; true; nFile++) {
         CBlockFileInfo info;
         if (pblocktree->ReadBlockFileInfo(nFile, info)) {
             vinfoBlockFile.push_back(info);
         } else {
             break;
         }
     }
 
     // Check presence of blk files
     LogPrintf("Checking all blk files are present...\n");
     std::set<int> setBlkDataFiles;
     for (const std::pair<uint256, CBlockIndex *> &item : mapBlockIndex) {
         CBlockIndex *pindex = item.second;
         if (pindex->nStatus & BLOCK_HAVE_DATA) {
             setBlkDataFiles.insert(pindex->nFile);
         }
     }
     for (std::set<int>::iterator it = setBlkDataFiles.begin();
          it != setBlkDataFiles.end(); it++) {
         CDiskBlockPos pos(*it, 0);
         if (CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION)
                 .IsNull()) {
             return false;
         }
     }
 
     // Check whether we have ever pruned block & undo files
     pblocktree->ReadFlag("prunedblockfiles", fHavePruned);
     if (fHavePruned) {
         LogPrintf(
             "LoadBlockIndexDB(): Block files have previously been pruned\n");
     }
 
     // Check whether we need to continue reindexing
     bool fReindexing = false;
     pblocktree->ReadReindexing(fReindexing);
     fReindex |= fReindexing;
 
     // Check whether we have a transaction index
     pblocktree->ReadFlag("txindex", fTxIndex);
     LogPrintf("%s: transaction index %s\n", __func__,
               fTxIndex ? "enabled" : "disabled");
 
     // Load pointer to end of best chain
     BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
     if (it == mapBlockIndex.end()) {
         return true;
     }
     chainActive.SetTip(it->second);
 
     PruneBlockIndexCandidates();
 
     LogPrintf(
         "%s: hashBestChain=%s height=%d date=%s progress=%f\n", __func__,
         chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(),
         DateTimeStrFormat("%Y-%m-%d %H:%M:%S",
                           chainActive.Tip()->GetBlockTime()),
         GuessVerificationProgress(chainparams.TxData(), chainActive.Tip()));
 
     return true;
 }
 
 CVerifyDB::CVerifyDB() {
     uiInterface.ShowProgress(_("Verifying blocks..."), 0);
 }
 
 CVerifyDB::~CVerifyDB() {
     uiInterface.ShowProgress("", 100);
 }
 
 bool CVerifyDB::VerifyDB(const Config &config, const CChainParams &chainparams,
                          CCoinsView *coinsview, int nCheckLevel,
                          int nCheckDepth) {
     LOCK(cs_main);
     if (chainActive.Tip() == nullptr || chainActive.Tip()->pprev == nullptr) {
         return true;
     }
 
     // Verify blocks in the best chain
     if (nCheckDepth <= 0) {
         // suffices until the year 19000
         nCheckDepth = 1000000000;
     }
     if (nCheckDepth > chainActive.Height()) {
         nCheckDepth = chainActive.Height();
     }
     nCheckLevel = std::max(0, std::min(4, nCheckLevel));
     LogPrintf("Verifying last %i blocks at level %i\n", nCheckDepth,
               nCheckLevel);
     CCoinsViewCache coins(coinsview);
     CBlockIndex *pindexState = chainActive.Tip();
     CBlockIndex *pindexFailure = nullptr;
     int nGoodTransactions = 0;
     CValidationState state;
     int reportDone = 0;
     LogPrintf("[0%%]...");
     for (CBlockIndex *pindex = chainActive.Tip(); pindex && pindex->pprev;
          pindex = pindex->pprev) {
         boost::this_thread::interruption_point();
         int percentageDone = std::max(
             1, std::min(
                    99,
                    (int)(((double)(chainActive.Height() - pindex->nHeight)) /
                          (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))));
 
         if (reportDone < percentageDone / 10) {
             // report every 10% step
             LogPrintf("[%d%%]...", percentageDone);
             reportDone = percentageDone / 10;
         }
 
         uiInterface.ShowProgress(_("Verifying blocks..."), percentageDone);
         if (pindex->nHeight < chainActive.Height() - nCheckDepth) {
             break;
         }
 
         if (fPruneMode && !(pindex->nStatus & BLOCK_HAVE_DATA)) {
             // If pruning, only go back as far as we have data.
             LogPrintf("VerifyDB(): block verification stopping at height %d "
                       "(pruning, no data)\n",
                       pindex->nHeight);
             break;
         }
         CBlock block;
 
         // check level 0: read from disk
         if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus())) {
             return error(
                 "VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s",
                 pindex->nHeight, pindex->GetBlockHash().ToString());
         }
 
         // check level 1: verify block validity
         if (nCheckLevel >= 1 &&
             !CheckBlock(config, block, state, chainparams.GetConsensus())) {
             return error("%s: *** found bad block at %d, hash=%s (%s)\n",
                          __func__, pindex->nHeight,
                          pindex->GetBlockHash().ToString(),
                          FormatStateMessage(state));
         }
 
         // check level 2: verify undo validity
         if (nCheckLevel >= 2 && pindex) {
             CBlockUndo undo;
             CDiskBlockPos pos = pindex->GetUndoPos();
             if (!pos.IsNull()) {
                 if (!UndoReadFromDisk(undo, pos,
                                       pindex->pprev->GetBlockHash())) {
                     return error(
                         "VerifyDB(): *** found bad undo data at %d, hash=%s\n",
                         pindex->nHeight, pindex->GetBlockHash().ToString());
                 }
             }
         }
 
         // check level 3: check for inconsistencies during memory-only
         // disconnect of tip blocks
         if (nCheckLevel >= 3 && pindex == pindexState &&
             (coins.DynamicMemoryUsage() + pcoinsTip->DynamicMemoryUsage()) <=
                 nCoinCacheUsage) {
             DisconnectResult res = DisconnectBlock(block, pindex, coins);
             if (res == DISCONNECT_FAILED) {
                 return error("VerifyDB(): *** irrecoverable inconsistency in "
                              "block data at %d, hash=%s",
                              pindex->nHeight,
                              pindex->GetBlockHash().ToString());
             }
             pindexState = pindex->pprev;
             if (res == DISCONNECT_UNCLEAN) {
                 nGoodTransactions = 0;
                 pindexFailure = pindex;
             } else {
                 nGoodTransactions += block.vtx.size();
             }
         }
 
         if (ShutdownRequested()) {
             return true;
         }
     }
 
     if (pindexFailure) {
         return error("VerifyDB(): *** coin database inconsistencies found "
                      "(last %i blocks, %i good transactions before that)\n",
                      chainActive.Height() - pindexFailure->nHeight + 1,
                      nGoodTransactions);
     }
 
     // check level 4: try reconnecting blocks
     if (nCheckLevel >= 4) {
         CBlockIndex *pindex = pindexState;
         while (pindex != chainActive.Tip()) {
             boost::this_thread::interruption_point();
             uiInterface.ShowProgress(
                 _("Verifying blocks..."),
                 std::max(
                     1, std::min(99, 100 - (int)(((double)(chainActive.Height() -
                                                           pindex->nHeight)) /
                                                 (double)nCheckDepth * 50))));
             pindex = chainActive.Next(pindex);
             CBlock block;
             if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus())) {
                 return error(
                     "VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s",
                     pindex->nHeight, pindex->GetBlockHash().ToString());
             }
             if (!ConnectBlock(config, block, state, pindex, coins,
                               chainparams)) {
                 return error(
                     "VerifyDB(): *** found unconnectable block at %d, hash=%s",
                     pindex->nHeight, pindex->GetBlockHash().ToString());
             }
         }
     }
 
     LogPrintf("[DONE].\n");
     LogPrintf("No coin database inconsistencies in last %i blocks (%i "
               "transactions)\n",
               chainActive.Height() - pindexState->nHeight, nGoodTransactions);
 
     return true;
 }
 
 bool RewindBlockIndex(const Config &config, const CChainParams &params) {
     LOCK(cs_main);
 
     int nHeight = chainActive.Height() + 1;
 
     // nHeight is now the height of the first insufficiently-validated block, or
     // tipheight + 1
     CValidationState state;
     CBlockIndex *pindex = chainActive.Tip();
     while (chainActive.Height() >= nHeight) {
         if (fPruneMode && !(chainActive.Tip()->nStatus & BLOCK_HAVE_DATA)) {
             // If pruning, don't try rewinding past the HAVE_DATA point; since
             // older blocks can't be served anyway, there's no need to walk
             // further, and trying to DisconnectTip() will fail (and require a
             // needless reindex/redownload of the blockchain).
             break;
         }
         if (!DisconnectTip(config, state, true)) {
             return error(
                 "RewindBlockIndex: unable to disconnect block at height %i",
                 pindex->nHeight);
         }
         // Occasionally flush state to disk.
         if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) {
             return false;
         }
     }
 
     // Reduce validity flag and have-data flags.
     // We do this after actual disconnecting, otherwise we'll end up writing the
     // lack of data to disk before writing the chainstate, resulting in a
     // failure to continue if interrupted.
     for (BlockMap::iterator it = mapBlockIndex.begin();
          it != mapBlockIndex.end(); it++) {
         CBlockIndex *pindexIter = it->second;
 
         if (pindexIter->IsValid(BLOCK_VALID_TRANSACTIONS) &&
             pindexIter->nChainTx) {
             setBlockIndexCandidates.insert(pindexIter);
         }
     }
 
     PruneBlockIndexCandidates();
 
     CheckBlockIndex(params.GetConsensus());
 
     if (!FlushStateToDisk(state, FLUSH_STATE_ALWAYS)) {
         return false;
     }
 
     return true;
 }
 
 // May NOT be used after any connections are up as much of the peer-processing
 // logic assumes a consistent block index state
 void UnloadBlockIndex() {
     LOCK(cs_main);
     setBlockIndexCandidates.clear();
     chainActive.SetTip(nullptr);
     pindexBestInvalid = nullptr;
     pindexBestHeader = nullptr;
     mempool.clear();
     mapBlocksUnlinked.clear();
     vinfoBlockFile.clear();
     nLastBlockFile = 0;
     nBlockSequenceId = 1;
     setDirtyBlockIndex.clear();
     setDirtyFileInfo.clear();
     versionbitscache.Clear();
     for (int b = 0; b < VERSIONBITS_NUM_BITS; b++) {
         warningcache[b].clear();
     }
 
     for (BlockMap::value_type &entry : mapBlockIndex) {
         delete entry.second;
     }
     mapBlockIndex.clear();
     fHavePruned = false;
 }
 
 bool LoadBlockIndex(const CChainParams &chainparams) {
     // Load block index from databases
     if (!fReindex && !LoadBlockIndexDB(chainparams)) {
         return false;
     }
     return true;
 }
 
 bool InitBlockIndex(const Config &config) {
     LOCK(cs_main);
 
     // Check whether we're already initialized
     if (chainActive.Genesis() != nullptr) {
         return true;
     }
 
     // Use the provided setting for -txindex in the new database
     fTxIndex = GetBoolArg("-txindex", DEFAULT_TXINDEX);
     pblocktree->WriteFlag("txindex", fTxIndex);
     LogPrintf("Initializing databases...\n");
 
     // Only add the genesis block if not reindexing (in which case we reuse the
     // one already on disk)
     if (!fReindex) {
         try {
             const CChainParams &chainparams = config.GetChainParams();
             CBlock &block = const_cast<CBlock &>(chainparams.GenesisBlock());
             // Start new block file
             unsigned int nBlockSize =
                 ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
             CDiskBlockPos blockPos;
             CValidationState state;
             if (!FindBlockPos(state, blockPos, nBlockSize + 8, 0,
                               block.GetBlockTime())) {
                 return error("LoadBlockIndex(): FindBlockPos failed");
             }
             if (!WriteBlockToDisk(block, blockPos,
                                   chainparams.MessageStart())) {
                 return error(
                     "LoadBlockIndex(): writing genesis block to disk failed");
             }
             CBlockIndex *pindex = AddToBlockIndex(block);
             if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) {
                 return error("LoadBlockIndex(): genesis block not accepted");
             }
             // Force a chainstate write so that when we VerifyDB in a moment, it
             // doesn't check stale data
             return FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
         } catch (const std::runtime_error &e) {
             return error(
                 "LoadBlockIndex(): failed to initialize block database: %s",
                 e.what());
         }
     }
 
     return true;
 }
 
 bool LoadExternalBlockFile(const Config &config, FILE *fileIn,
                            CDiskBlockPos *dbp) {
     // Map of disk positions for blocks with unknown parent (only used for
     // reindex)
     static std::multimap<uint256, CDiskBlockPos> mapBlocksUnknownParent;
     int64_t nStart = GetTimeMillis();
 
     const CChainParams &chainparams = config.GetChainParams();
 
     int nLoaded = 0;
     try {
         // This takes over fileIn and calls fclose() on it in the CBufferedFile
         // destructor. Make sure we have at least 2*MAX_TX_SIZE space in there
         // so any transaction can fit in the buffer.
         CBufferedFile blkdat(fileIn, 2 * MAX_TX_SIZE, MAX_TX_SIZE + 8, SER_DISK,
                              CLIENT_VERSION);
         uint64_t nRewind = blkdat.GetPos();
         while (!blkdat.eof()) {
             boost::this_thread::interruption_point();
 
             blkdat.SetPos(nRewind);
             // Start one byte further next time, in case of failure.
             nRewind++;
             // Remove former limit.
             blkdat.SetLimit();
             unsigned int nSize = 0;
             try {
                 // Locate a header.
-                unsigned char buf[CMessageHeader::MESSAGE_START_SIZE];
+                uint8_t buf[CMessageHeader::MESSAGE_START_SIZE];
                 blkdat.FindByte(chainparams.MessageStart()[0]);
                 nRewind = blkdat.GetPos() + 1;
                 blkdat >> FLATDATA(buf);
                 if (memcmp(buf, chainparams.MessageStart(),
                            CMessageHeader::MESSAGE_START_SIZE)) {
                     continue;
                 }
                 // Read size.
                 blkdat >> nSize;
                 if (nSize < 80) {
                     continue;
                 }
             } catch (const std::exception &) {
                 // No valid block header found; don't complain.
                 break;
             }
             try {
                 // read block
                 uint64_t nBlockPos = blkdat.GetPos();
                 if (dbp) {
                     dbp->nPos = nBlockPos;
                 }
                 blkdat.SetLimit(nBlockPos + nSize);
                 blkdat.SetPos(nBlockPos);
                 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
                 CBlock &block = *pblock;
                 blkdat >> block;
                 nRewind = blkdat.GetPos();
 
                 // detect out of order blocks, and store them for later
                 uint256 hash = block.GetHash();
                 if (hash != chainparams.GetConsensus().hashGenesisBlock &&
                     mapBlockIndex.find(block.hashPrevBlock) ==
                         mapBlockIndex.end()) {
                     LogPrint("reindex",
                              "%s: Out of order block %s, parent %s not known\n",
                              __func__, hash.ToString(),
                              block.hashPrevBlock.ToString());
                     if (dbp) {
                         mapBlocksUnknownParent.insert(
                             std::make_pair(block.hashPrevBlock, *dbp));
                     }
                     continue;
                 }
 
                 // process in case the block isn't known yet
                 if (mapBlockIndex.count(hash) == 0 ||
                     (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) {
                     LOCK(cs_main);
                     CValidationState state;
                     if (AcceptBlock(config, pblock, state, nullptr, true, dbp,
                                     nullptr)) {
                         nLoaded++;
                     }
                     if (state.IsError()) {
                         break;
                     }
                 } else if (hash !=
                                chainparams.GetConsensus().hashGenesisBlock &&
                            mapBlockIndex[hash]->nHeight % 1000 == 0) {
                     LogPrint(
                         "reindex",
                         "Block Import: already had block %s at height %d\n",
                         hash.ToString(), mapBlockIndex[hash]->nHeight);
                 }
 
                 // Activate the genesis block so normal node progress can
                 // continue
                 if (hash == chainparams.GetConsensus().hashGenesisBlock) {
                     CValidationState state;
                     if (!ActivateBestChain(config, state)) {
                         break;
                     }
                 }
 
                 NotifyHeaderTip();
 
                 // Recursively process earlier encountered successors of this
                 // block
                 std::deque<uint256> queue;
                 queue.push_back(hash);
                 while (!queue.empty()) {
                     uint256 head = queue.front();
                     queue.pop_front();
                     std::pair<std::multimap<uint256, CDiskBlockPos>::iterator,
                               std::multimap<uint256, CDiskBlockPos>::iterator>
                         range = mapBlocksUnknownParent.equal_range(head);
                     while (range.first != range.second) {
                         std::multimap<uint256, CDiskBlockPos>::iterator it =
                             range.first;
                         std::shared_ptr<CBlock> pblockrecursive =
                             std::make_shared<CBlock>();
                         if (ReadBlockFromDisk(*pblockrecursive, it->second,
                                               chainparams.GetConsensus())) {
                             LogPrint(
                                 "reindex",
                                 "%s: Processing out of order child %s of %s\n",
                                 __func__, pblockrecursive->GetHash().ToString(),
                                 head.ToString());
                             LOCK(cs_main);
                             CValidationState dummy;
                             if (AcceptBlock(config, pblockrecursive, dummy,
                                             nullptr, true, &it->second,
                                             nullptr)) {
                                 nLoaded++;
                                 queue.push_back(pblockrecursive->GetHash());
                             }
                         }
                         range.first++;
                         mapBlocksUnknownParent.erase(it);
                         NotifyHeaderTip();
                     }
                 }
             } catch (const std::exception &e) {
                 LogPrintf("%s: Deserialize or I/O error - %s\n", __func__,
                           e.what());
             }
         }
     } catch (const std::runtime_error &e) {
         AbortNode(std::string("System error: ") + e.what());
     }
     if (nLoaded > 0) {
         LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded,
                   GetTimeMillis() - nStart);
     }
     return nLoaded > 0;
 }
 
 static void CheckBlockIndex(const Consensus::Params &consensusParams) {
     if (!fCheckBlockIndex) {
         return;
     }
 
     LOCK(cs_main);
 
     // During a reindex, we read the genesis block and call CheckBlockIndex
     // before ActivateBestChain, so we have the genesis block in mapBlockIndex
     // but no active chain. (A few of the tests when iterating the block tree
     // require that chainActive has been initialized.)
     if (chainActive.Height() < 0) {
         assert(mapBlockIndex.size() <= 1);
         return;
     }
 
     // Build forward-pointing map of the entire block tree.
     std::multimap<CBlockIndex *, CBlockIndex *> forward;
     for (BlockMap::iterator it = mapBlockIndex.begin();
          it != mapBlockIndex.end(); it++) {
         forward.insert(std::make_pair(it->second->pprev, it->second));
     }
 
     assert(forward.size() == mapBlockIndex.size());
 
     std::pair<std::multimap<CBlockIndex *, CBlockIndex *>::iterator,
               std::multimap<CBlockIndex *, CBlockIndex *>::iterator>
         rangeGenesis = forward.equal_range(nullptr);
     CBlockIndex *pindex = rangeGenesis.first->second;
     rangeGenesis.first++;
     // There is only one index entry with parent nullptr.
     assert(rangeGenesis.first == rangeGenesis.second);
 
     // Iterate over the entire block tree, using depth-first search.
     // Along the way, remember whether there are blocks on the path from genesis
     // block being explored which are the first to have certain properties.
     size_t nNodes = 0;
     int nHeight = 0;
     // Oldest ancestor of pindex which is invalid.
     CBlockIndex *pindexFirstInvalid = nullptr;
     // Oldest ancestor of pindex which does not have BLOCK_HAVE_DATA.
     CBlockIndex *pindexFirstMissing = nullptr;
     // Oldest ancestor of pindex for which nTx == 0.
     CBlockIndex *pindexFirstNeverProcessed = nullptr;
     // Oldest ancestor of pindex which does not have BLOCK_VALID_TREE
     // (regardless of being valid or not).
     CBlockIndex *pindexFirstNotTreeValid = nullptr;
     // Oldest ancestor of pindex which does not have BLOCK_VALID_TRANSACTIONS
     // (regardless of being valid or not).
     CBlockIndex *pindexFirstNotTransactionsValid = nullptr;
     // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN
     // (regardless of being valid or not).
     CBlockIndex *pindexFirstNotChainValid = nullptr;
     // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS
     // (regardless of being valid or not).
     CBlockIndex *pindexFirstNotScriptsValid = nullptr;
     while (pindex != nullptr) {
         nNodes++;
         if (pindexFirstInvalid == nullptr &&
             pindex->nStatus & BLOCK_FAILED_VALID) {
             pindexFirstInvalid = pindex;
         }
         if (pindexFirstMissing == nullptr &&
             !(pindex->nStatus & BLOCK_HAVE_DATA)) {
             pindexFirstMissing = pindex;
         }
         if (pindexFirstNeverProcessed == nullptr && pindex->nTx == 0) {
             pindexFirstNeverProcessed = pindex;
         }
         if (pindex->pprev != nullptr && pindexFirstNotTreeValid == nullptr &&
             (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TREE) {
             pindexFirstNotTreeValid = pindex;
         }
         if (pindex->pprev != nullptr &&
             pindexFirstNotTransactionsValid == nullptr &&
             (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TRANSACTIONS) {
             pindexFirstNotTransactionsValid = pindex;
         }
         if (pindex->pprev != nullptr && pindexFirstNotChainValid == nullptr &&
             (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_CHAIN) {
             pindexFirstNotChainValid = pindex;
         }
         if (pindex->pprev != nullptr && pindexFirstNotScriptsValid == nullptr &&
             (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS) {
             pindexFirstNotScriptsValid = pindex;
         }
 
         // Begin: actual consistency checks.
         if (pindex->pprev == nullptr) {
             // Genesis block checks.
             // Genesis block's hash must match.
             assert(pindex->GetBlockHash() == consensusParams.hashGenesisBlock);
             // The current active chain's genesis block must be this block.
             assert(pindex == chainActive.Genesis());
         }
         if (pindex->nChainTx == 0) {
             // nSequenceId can't be set positive for blocks that aren't linked
             // (negative is used for preciousblock)
             assert(pindex->nSequenceId <= 0);
         }
         // VALID_TRANSACTIONS is equivalent to nTx > 0 for all nodes (whether or
         // not pruning has occurred). HAVE_DATA is only equivalent to nTx > 0
         // (or VALID_TRANSACTIONS) if no pruning has occurred.
         if (!fHavePruned) {
             // If we've never pruned, then HAVE_DATA should be equivalent to nTx
             // > 0
             assert(!(pindex->nStatus & BLOCK_HAVE_DATA) == (pindex->nTx == 0));
             assert(pindexFirstMissing == pindexFirstNeverProcessed);
         } else {
             // If we have pruned, then we can only say that HAVE_DATA implies
             // nTx > 0
             if (pindex->nStatus & BLOCK_HAVE_DATA) assert(pindex->nTx > 0);
         }
         if (pindex->nStatus & BLOCK_HAVE_UNDO) {
             assert(pindex->nStatus & BLOCK_HAVE_DATA);
         }
         // This is pruning-independent.
         assert(((pindex->nStatus & BLOCK_VALID_MASK) >=
                 BLOCK_VALID_TRANSACTIONS) == (pindex->nTx > 0));
         // All parents having had data (at some point) is equivalent to all
         // parents being VALID_TRANSACTIONS, which is equivalent to nChainTx
         // being set.
         // nChainTx != 0 is used to signal that all parent blocks have been
         // processed (but may have been pruned).
         assert((pindexFirstNeverProcessed != nullptr) ==
                (pindex->nChainTx == 0));
         assert((pindexFirstNotTransactionsValid != nullptr) ==
                (pindex->nChainTx == 0));
         // nHeight must be consistent.
         assert(pindex->nHeight == nHeight);
         // For every block except the genesis block, the chainwork must be
         // larger than the parent's.
         assert(pindex->pprev == nullptr ||
                pindex->nChainWork >= pindex->pprev->nChainWork);
         // The pskip pointer must point back for all but the first 2 blocks.
         assert(nHeight < 2 ||
                (pindex->pskip && (pindex->pskip->nHeight < nHeight)));
         // All mapBlockIndex entries must at least be TREE valid
         assert(pindexFirstNotTreeValid == nullptr);
         if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TREE) {
             // TREE valid implies all parents are TREE valid
             assert(pindexFirstNotTreeValid == nullptr);
         }
         if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_CHAIN) {
             // CHAIN valid implies all parents are CHAIN valid
             assert(pindexFirstNotChainValid == nullptr);
         }
         if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_SCRIPTS) {
             // SCRIPTS valid implies all parents are SCRIPTS valid
             assert(pindexFirstNotScriptsValid == nullptr);
         }
         if (pindexFirstInvalid == nullptr) {
             // Checks for not-invalid blocks.
             // The failed mask cannot be set for blocks without invalid parents.
             assert((pindex->nStatus & BLOCK_FAILED_MASK) == 0);
         }
         if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) &&
             pindexFirstNeverProcessed == nullptr) {
             if (pindexFirstInvalid == nullptr) {
                 // If this block sorts at least as good as the current tip and
                 // is valid and we have all data for its parents, it must be in
                 // setBlockIndexCandidates. chainActive.Tip() must also be there
                 // even if some data has been pruned.
                 if (pindexFirstMissing == nullptr ||
                     pindex == chainActive.Tip()) {
                     assert(setBlockIndexCandidates.count(pindex));
                 }
                 // If some parent is missing, then it could be that this block
                 // was in setBlockIndexCandidates but had to be removed because
                 // of the missing data. In this case it must be in
                 // mapBlocksUnlinked -- see test below.
             }
         } else {
             // If this block sorts worse than the current tip or some ancestor's
             // block has never been seen, it cannot be in
             // setBlockIndexCandidates.
             assert(setBlockIndexCandidates.count(pindex) == 0);
         }
         // Check whether this block is in mapBlocksUnlinked.
         std::pair<std::multimap<CBlockIndex *, CBlockIndex *>::iterator,
                   std::multimap<CBlockIndex *, CBlockIndex *>::iterator>
             rangeUnlinked = mapBlocksUnlinked.equal_range(pindex->pprev);
         bool foundInUnlinked = false;
         while (rangeUnlinked.first != rangeUnlinked.second) {
             assert(rangeUnlinked.first->first == pindex->pprev);
             if (rangeUnlinked.first->second == pindex) {
                 foundInUnlinked = true;
                 break;
             }
             rangeUnlinked.first++;
         }
         if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) &&
             pindexFirstNeverProcessed != nullptr &&
             pindexFirstInvalid == nullptr) {
             // If this block has block data available, some parent was never
             // received, and has no invalid parents, it must be in
             // mapBlocksUnlinked.
             assert(foundInUnlinked);
         }
         if (!(pindex->nStatus & BLOCK_HAVE_DATA)) {
             // Can't be in mapBlocksUnlinked if we don't HAVE_DATA
             assert(!foundInUnlinked);
         }
         if (pindexFirstMissing == nullptr) {
             // We aren't missing data for any parent -- cannot be in
             // mapBlocksUnlinked.
             assert(!foundInUnlinked);
         }
         if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) &&
             pindexFirstNeverProcessed == nullptr &&
             pindexFirstMissing != nullptr) {
             // We HAVE_DATA for this block, have received data for all parents
             // at some point, but we're currently missing data for some parent.
             // We must have pruned.
             assert(fHavePruned);
             // This block may have entered mapBlocksUnlinked if:
             //  - it has a descendant that at some point had more work than the
             //    tip, and
             //  - we tried switching to that descendant but were missing
             //    data for some intermediate block between chainActive and the
             //    tip.
             // So if this block is itself better than chainActive.Tip() and it
             // wasn't in
             // setBlockIndexCandidates, then it must be in mapBlocksUnlinked.
             if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) &&
                 setBlockIndexCandidates.count(pindex) == 0) {
                 if (pindexFirstInvalid == nullptr) {
                     assert(foundInUnlinked);
                 }
             }
         }
         // assert(pindex->GetBlockHash() == pindex->GetBlockHeader().GetHash());
         // // Perhaps too slow
         // End: actual consistency checks.
 
         // Try descending into the first subnode.
         std::pair<std::multimap<CBlockIndex *, CBlockIndex *>::iterator,
                   std::multimap<CBlockIndex *, CBlockIndex *>::iterator>
             range = forward.equal_range(pindex);
         if (range.first != range.second) {
             // A subnode was found.
             pindex = range.first->second;
             nHeight++;
             continue;
         }
         // This is a leaf node. Move upwards until we reach a node of which we
         // have not yet visited the last child.
         while (pindex) {
             // We are going to either move to a parent or a sibling of pindex.
             // If pindex was the first with a certain property, unset the
             // corresponding variable.
             if (pindex == pindexFirstInvalid) {
                 pindexFirstInvalid = nullptr;
             }
             if (pindex == pindexFirstMissing) {
                 pindexFirstMissing = nullptr;
             }
             if (pindex == pindexFirstNeverProcessed) {
                 pindexFirstNeverProcessed = nullptr;
             }
             if (pindex == pindexFirstNotTreeValid) {
                 pindexFirstNotTreeValid = nullptr;
             }
             if (pindex == pindexFirstNotTransactionsValid) {
                 pindexFirstNotTransactionsValid = nullptr;
             }
             if (pindex == pindexFirstNotChainValid) {
                 pindexFirstNotChainValid = nullptr;
             }
             if (pindex == pindexFirstNotScriptsValid) {
                 pindexFirstNotScriptsValid = nullptr;
             }
             // Find our parent.
             CBlockIndex *pindexPar = pindex->pprev;
             // Find which child we just visited.
             std::pair<std::multimap<CBlockIndex *, CBlockIndex *>::iterator,
                       std::multimap<CBlockIndex *, CBlockIndex *>::iterator>
                 rangePar = forward.equal_range(pindexPar);
             while (rangePar.first->second != pindex) {
                 // Our parent must have at least the node we're coming from as
                 // child.
                 assert(rangePar.first != rangePar.second);
                 rangePar.first++;
             }
             // Proceed to the next one.
             rangePar.first++;
             if (rangePar.first != rangePar.second) {
                 // Move to the sibling.
                 pindex = rangePar.first->second;
                 break;
             } else {
                 // Move up further.
                 pindex = pindexPar;
                 nHeight--;
                 continue;
             }
         }
     }
 
     // Check that we actually traversed the entire map.
     assert(nNodes == forward.size());
 }
 
 std::string CBlockFileInfo::ToString() const {
     return strprintf(
         "CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)",
         nBlocks, nSize, nHeightFirst, nHeightLast,
         DateTimeStrFormat("%Y-%m-%d", nTimeFirst),
         DateTimeStrFormat("%Y-%m-%d", nTimeLast));
 }
 
 CBlockFileInfo *GetBlockFileInfo(size_t n) {
     return &vinfoBlockFile.at(n);
 }
 
 ThresholdState VersionBitsTipState(const Consensus::Params &params,
                                    Consensus::DeploymentPos pos) {
     LOCK(cs_main);
     return VersionBitsState(chainActive.Tip(), params, pos, versionbitscache);
 }
 
 int VersionBitsTipStateSinceHeight(const Consensus::Params &params,
                                    Consensus::DeploymentPos pos) {
     LOCK(cs_main);
     return VersionBitsStateSinceHeight(chainActive.Tip(), params, pos,
                                        versionbitscache);
 }
 
 static const uint64_t MEMPOOL_DUMP_VERSION = 1;
 
 bool LoadMempool(const Config &config) {
     int64_t nExpiryTimeout =
         GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60;
     FILE *filestr =
         fopen((GetDataDir() / "mempool.dat").string().c_str(), "rb");
     CAutoFile file(filestr, SER_DISK, CLIENT_VERSION);
     if (file.IsNull()) {
         LogPrintf(
             "Failed to open mempool file from disk. Continuing anyway.\n");
         return false;
     }
 
     int64_t count = 0;
     int64_t skipped = 0;
     int64_t failed = 0;
     int64_t nNow = GetTime();
 
     try {
         uint64_t version;
         file >> version;
         if (version != MEMPOOL_DUMP_VERSION) {
             return false;
         }
         uint64_t num;
         file >> num;
         double prioritydummy = 0;
         while (num--) {
             CTransactionRef tx;
             int64_t nTime;
             int64_t nFeeDelta;
             file >> tx;
             file >> nTime;
             file >> nFeeDelta;
 
             CAmount amountdelta = nFeeDelta;
             if (amountdelta) {
                 mempool.PrioritiseTransaction(tx->GetId(),
                                               tx->GetId().ToString(),
                                               prioritydummy, amountdelta);
             }
             CValidationState state;
             if (nTime + nExpiryTimeout > nNow) {
                 LOCK(cs_main);
                 AcceptToMemoryPoolWithTime(config, mempool, state, tx, true,
                                            nullptr, nTime);
                 if (state.IsValid()) {
                     ++count;
                 } else {
                     ++failed;
                 }
             } else {
                 ++skipped;
             }
             if (ShutdownRequested()) return false;
         }
         std::map<uint256, CAmount> mapDeltas;
         file >> mapDeltas;
 
         for (const auto &i : mapDeltas) {
             mempool.PrioritiseTransaction(i.first, i.first.ToString(),
                                           prioritydummy, i.second);
         }
     } catch (const std::exception &e) {
         LogPrintf("Failed to deserialize mempool data on disk: %s. Continuing "
                   "anyway.\n",
                   e.what());
         return false;
     }
 
     LogPrintf("Imported mempool transactions from disk: %i successes, %i "
               "failed, %i expired\n",
               count, failed, skipped);
     return true;
 }
 
 void DumpMempool(void) {
     int64_t start = GetTimeMicros();
 
     std::map<uint256, CAmount> mapDeltas;
     std::vector<TxMempoolInfo> vinfo;
 
     {
         LOCK(mempool.cs);
         for (const auto &i : mempool.mapDeltas) {
             mapDeltas[i.first] = i.second.second;
         }
         vinfo = mempool.infoAll();
     }
 
     int64_t mid = GetTimeMicros();
 
     try {
         FILE *filestr =
             fopen((GetDataDir() / "mempool.dat.new").string().c_str(), "wb");
         if (!filestr) {
             return;
         }
 
         CAutoFile file(filestr, SER_DISK, CLIENT_VERSION);
 
         uint64_t version = MEMPOOL_DUMP_VERSION;
         file << version;
 
         file << (uint64_t)vinfo.size();
         for (const auto &i : vinfo) {
             file << *(i.tx);
             file << (int64_t)i.nTime;
             file << (int64_t)i.nFeeDelta;
             mapDeltas.erase(i.tx->GetId());
         }
 
         file << mapDeltas;
         FileCommit(file.Get());
         file.fclose();
         RenameOver(GetDataDir() / "mempool.dat.new",
                    GetDataDir() / "mempool.dat");
         int64_t last = GetTimeMicros();
         LogPrintf("Dumped mempool: %gs to copy, %gs to dump\n",
                   (mid - start) * 0.000001, (last - mid) * 0.000001);
     } catch (const std::exception &e) {
         LogPrintf("Failed to dump mempool: %s. Continuing anyway.\n", e.what());
     }
 }
 
 //! Guess how far we are in the verification process at the given block index
 double GuessVerificationProgress(const ChainTxData &data, CBlockIndex *pindex) {
     if (pindex == nullptr) return 0.0;
 
     int64_t nNow = time(nullptr);
 
     double fTxTotal;
 
     if (pindex->nChainTx <= data.nTxCount) {
         fTxTotal = data.nTxCount + (nNow - data.nTime) * data.dTxRate;
     } else {
         fTxTotal =
             pindex->nChainTx + (nNow - pindex->GetBlockTime()) * data.dTxRate;
     }
 
     return pindex->nChainTx / fTxTotal;
 }
 
 class CMainCleanup {
 public:
     CMainCleanup() {}
     ~CMainCleanup() {
         // block headers
         BlockMap::iterator it1 = mapBlockIndex.begin();
         for (; it1 != mapBlockIndex.end(); it1++)
             delete (*it1).second;
         mapBlockIndex.clear();
     }
 } instance_of_cmaincleanup;
diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp
index ca0a54524..a691031ee 100644
--- a/src/wallet/crypter.cpp
+++ b/src/wallet/crypter.cpp
@@ -1,283 +1,280 @@
 // Copyright (c) 2009-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.
 
 #include "crypter.h"
 
 #include "crypto/aes.h"
 #include "crypto/sha512.h"
 #include "script/script.h"
 #include "script/standard.h"
 #include "util.h"
 
 #include <string>
 #include <vector>
 
-int CCrypter::BytesToKeySHA512AES(const std::vector<unsigned char> &chSalt,
+int CCrypter::BytesToKeySHA512AES(const std::vector<uint8_t> &chSalt,
                                   const SecureString &strKeyData, int count,
-                                  unsigned char *key, unsigned char *iv) const {
+                                  uint8_t *key, uint8_t *iv) const {
     // This mimics the behavior of openssl's EVP_BytesToKey with an aes256cbc
     // cipher and sha512 message digest. Because sha512's output size (64b) is
     // greater than the aes256 block size (16b) + aes256 key size (32b), there's
     // no need to process more than once (D_0).
     if (!count || !key || !iv) return 0;
 
-    unsigned char buf[CSHA512::OUTPUT_SIZE];
+    uint8_t buf[CSHA512::OUTPUT_SIZE];
     CSHA512 di;
 
-    di.Write((const unsigned char *)strKeyData.c_str(), strKeyData.size());
+    di.Write((const uint8_t *)strKeyData.c_str(), strKeyData.size());
     if (chSalt.size()) di.Write(&chSalt[0], chSalt.size());
     di.Finalize(buf);
 
     for (int i = 0; i != count - 1; i++)
         di.Reset().Write(buf, sizeof(buf)).Finalize(buf);
 
     memcpy(key, buf, WALLET_CRYPTO_KEY_SIZE);
     memcpy(iv, buf + WALLET_CRYPTO_KEY_SIZE, WALLET_CRYPTO_IV_SIZE);
     memory_cleanse(buf, sizeof(buf));
     return WALLET_CRYPTO_KEY_SIZE;
 }
 
 bool CCrypter::SetKeyFromPassphrase(const SecureString &strKeyData,
-                                    const std::vector<unsigned char> &chSalt,
+                                    const std::vector<uint8_t> &chSalt,
                                     const unsigned int nRounds,
                                     const unsigned int nDerivationMethod) {
     if (nRounds < 1 || chSalt.size() != WALLET_CRYPTO_SALT_SIZE) return false;
 
     int i = 0;
     if (nDerivationMethod == 0)
         i = BytesToKeySHA512AES(chSalt, strKeyData, nRounds, vchKey.data(),
                                 vchIV.data());
 
     if (i != (int)WALLET_CRYPTO_KEY_SIZE) {
         memory_cleanse(vchKey.data(), vchKey.size());
         memory_cleanse(vchIV.data(), vchIV.size());
         return false;
     }
 
     fKeySet = true;
     return true;
 }
 
 bool CCrypter::SetKey(const CKeyingMaterial &chNewKey,
-                      const std::vector<unsigned char> &chNewIV) {
+                      const std::vector<uint8_t> &chNewIV) {
     if (chNewKey.size() != WALLET_CRYPTO_KEY_SIZE ||
         chNewIV.size() != WALLET_CRYPTO_IV_SIZE)
         return false;
 
     memcpy(vchKey.data(), chNewKey.data(), chNewKey.size());
     memcpy(vchIV.data(), chNewIV.data(), chNewIV.size());
 
     fKeySet = true;
     return true;
 }
 
 bool CCrypter::Encrypt(const CKeyingMaterial &vchPlaintext,
-                       std::vector<unsigned char> &vchCiphertext) const {
+                       std::vector<uint8_t> &vchCiphertext) const {
     if (!fKeySet) return false;
 
     // max ciphertext len for a n bytes of plaintext is
     // n + AES_BLOCKSIZE bytes
     vchCiphertext.resize(vchPlaintext.size() + AES_BLOCKSIZE);
 
     AES256CBCEncrypt enc(vchKey.data(), vchIV.data(), true);
     size_t nLen =
         enc.Encrypt(&vchPlaintext[0], vchPlaintext.size(), &vchCiphertext[0]);
     if (nLen < vchPlaintext.size()) return false;
     vchCiphertext.resize(nLen);
 
     return true;
 }
 
-bool CCrypter::Decrypt(const std::vector<unsigned char> &vchCiphertext,
+bool CCrypter::Decrypt(const std::vector<uint8_t> &vchCiphertext,
                        CKeyingMaterial &vchPlaintext) const {
     if (!fKeySet) return false;
 
     // plaintext will always be equal to or lesser than length of ciphertext
     int nLen = vchCiphertext.size();
 
     vchPlaintext.resize(nLen);
 
     AES256CBCDecrypt dec(vchKey.data(), vchIV.data(), true);
     nLen =
         dec.Decrypt(&vchCiphertext[0], vchCiphertext.size(), &vchPlaintext[0]);
     if (nLen == 0) return false;
     vchPlaintext.resize(nLen);
     return true;
 }
 
 static bool EncryptSecret(const CKeyingMaterial &vMasterKey,
                           const CKeyingMaterial &vchPlaintext,
                           const uint256 &nIV,
-                          std::vector<unsigned char> &vchCiphertext) {
+                          std::vector<uint8_t> &vchCiphertext) {
     CCrypter cKeyCrypter;
-    std::vector<unsigned char> chIV(WALLET_CRYPTO_IV_SIZE);
+    std::vector<uint8_t> chIV(WALLET_CRYPTO_IV_SIZE);
     memcpy(&chIV[0], &nIV, WALLET_CRYPTO_IV_SIZE);
     if (!cKeyCrypter.SetKey(vMasterKey, chIV)) return false;
     return cKeyCrypter.Encrypt(*((const CKeyingMaterial *)&vchPlaintext),
                                vchCiphertext);
 }
 
 static bool DecryptSecret(const CKeyingMaterial &vMasterKey,
-                          const std::vector<unsigned char> &vchCiphertext,
+                          const std::vector<uint8_t> &vchCiphertext,
                           const uint256 &nIV, CKeyingMaterial &vchPlaintext) {
     CCrypter cKeyCrypter;
-    std::vector<unsigned char> chIV(WALLET_CRYPTO_IV_SIZE);
+    std::vector<uint8_t> chIV(WALLET_CRYPTO_IV_SIZE);
     memcpy(&chIV[0], &nIV, WALLET_CRYPTO_IV_SIZE);
     if (!cKeyCrypter.SetKey(vMasterKey, chIV)) return false;
     return cKeyCrypter.Decrypt(vchCiphertext,
                                *((CKeyingMaterial *)&vchPlaintext));
 }
 
 static bool DecryptKey(const CKeyingMaterial &vMasterKey,
-                       const std::vector<unsigned char> &vchCryptedSecret,
+                       const std::vector<uint8_t> &vchCryptedSecret,
                        const CPubKey &vchPubKey, CKey &key) {
     CKeyingMaterial vchSecret;
     if (!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(),
                        vchSecret))
         return false;
 
     if (vchSecret.size() != 32) return false;
 
     key.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
     return key.VerifyPubKey(vchPubKey);
 }
 
 bool CCryptoKeyStore::SetCrypted() {
     LOCK(cs_KeyStore);
     if (fUseCrypto) return true;
     if (!mapKeys.empty()) return false;
     fUseCrypto = true;
     return true;
 }
 
 bool CCryptoKeyStore::Lock() {
     if (!SetCrypted()) return false;
 
     {
         LOCK(cs_KeyStore);
         vMasterKey.clear();
     }
 
     NotifyStatusChanged(this);
     return true;
 }
 
 bool CCryptoKeyStore::Unlock(const CKeyingMaterial &vMasterKeyIn) {
     {
         LOCK(cs_KeyStore);
         if (!SetCrypted()) return false;
 
         bool keyPass = false;
         bool keyFail = false;
         CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
         for (; mi != mapCryptedKeys.end(); ++mi) {
             const CPubKey &vchPubKey = (*mi).second.first;
-            const std::vector<unsigned char> &vchCryptedSecret =
-                (*mi).second.second;
+            const std::vector<uint8_t> &vchCryptedSecret = (*mi).second.second;
             CKey key;
             if (!DecryptKey(vMasterKeyIn, vchCryptedSecret, vchPubKey, key)) {
                 keyFail = true;
                 break;
             }
             keyPass = true;
             if (fDecryptionThoroughlyChecked) break;
         }
         if (keyPass && keyFail) {
             LogPrintf("The wallet is probably corrupted: Some keys decrypt but "
                       "not all.\n");
             assert(false);
         }
         if (keyFail || !keyPass) return false;
         vMasterKey = vMasterKeyIn;
         fDecryptionThoroughlyChecked = true;
     }
     NotifyStatusChanged(this);
     return true;
 }
 
 bool CCryptoKeyStore::AddKeyPubKey(const CKey &key, const CPubKey &pubkey) {
     {
         LOCK(cs_KeyStore);
         if (!IsCrypted()) return CBasicKeyStore::AddKeyPubKey(key, pubkey);
 
         if (IsLocked()) return false;
 
-        std::vector<unsigned char> vchCryptedSecret;
+        std::vector<uint8_t> vchCryptedSecret;
         CKeyingMaterial vchSecret(key.begin(), key.end());
         if (!EncryptSecret(vMasterKey, vchSecret, pubkey.GetHash(),
                            vchCryptedSecret))
             return false;
 
         if (!AddCryptedKey(pubkey, vchCryptedSecret)) return false;
     }
     return true;
 }
 
 bool CCryptoKeyStore::AddCryptedKey(
-    const CPubKey &vchPubKey,
-    const std::vector<unsigned char> &vchCryptedSecret) {
+    const CPubKey &vchPubKey, const std::vector<uint8_t> &vchCryptedSecret) {
     {
         LOCK(cs_KeyStore);
         if (!SetCrypted()) return false;
 
         mapCryptedKeys[vchPubKey.GetID()] =
             make_pair(vchPubKey, vchCryptedSecret);
     }
     return true;
 }
 
 bool CCryptoKeyStore::GetKey(const CKeyID &address, CKey &keyOut) const {
     {
         LOCK(cs_KeyStore);
         if (!IsCrypted()) return CBasicKeyStore::GetKey(address, keyOut);
 
         CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
         if (mi != mapCryptedKeys.end()) {
             const CPubKey &vchPubKey = (*mi).second.first;
-            const std::vector<unsigned char> &vchCryptedSecret =
-                (*mi).second.second;
+            const std::vector<uint8_t> &vchCryptedSecret = (*mi).second.second;
             return DecryptKey(vMasterKey, vchCryptedSecret, vchPubKey, keyOut);
         }
     }
     return false;
 }
 
 bool CCryptoKeyStore::GetPubKey(const CKeyID &address,
                                 CPubKey &vchPubKeyOut) const {
     {
         LOCK(cs_KeyStore);
         if (!IsCrypted())
             return CBasicKeyStore::GetPubKey(address, vchPubKeyOut);
 
         CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
         if (mi != mapCryptedKeys.end()) {
             vchPubKeyOut = (*mi).second.first;
             return true;
         }
         // Check for watch-only pubkeys
         return CBasicKeyStore::GetPubKey(address, vchPubKeyOut);
     }
     return false;
 }
 
 bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial &vMasterKeyIn) {
     {
         LOCK(cs_KeyStore);
         if (!mapCryptedKeys.empty() || IsCrypted()) return false;
 
         fUseCrypto = true;
         for (KeyMap::value_type &mKey : mapKeys) {
             const CKey &key = mKey.second;
             CPubKey vchPubKey = key.GetPubKey();
             CKeyingMaterial vchSecret(key.begin(), key.end());
-            std::vector<unsigned char> vchCryptedSecret;
+            std::vector<uint8_t> vchCryptedSecret;
             if (!EncryptSecret(vMasterKeyIn, vchSecret, vchPubKey.GetHash(),
                                vchCryptedSecret))
                 return false;
             if (!AddCryptedKey(vchPubKey, vchCryptedSecret)) return false;
         }
         mapKeys.clear();
     }
     return true;
 }
diff --git a/src/wallet/crypter.h b/src/wallet/crypter.h
index 36f8ef2f9..38e61acd1 100644
--- a/src/wallet/crypter.h
+++ b/src/wallet/crypter.h
@@ -1,191 +1,189 @@
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_WALLET_CRYPTER_H
 #define BITCOIN_WALLET_CRYPTER_H
 
 #include "keystore.h"
 #include "serialize.h"
 #include "support/allocators/secure.h"
 
 class uint256;
 
 const unsigned int WALLET_CRYPTO_KEY_SIZE = 32;
 const unsigned int WALLET_CRYPTO_SALT_SIZE = 8;
 const unsigned int WALLET_CRYPTO_IV_SIZE = 16;
 
 /**
  * Private key encryption is done based on a CMasterKey, which holds a salt and
  * random encryption key.
  *
  * CMasterKeys are encrypted using AES-256-CBC using a key derived using
  * derivation method nDerivationMethod (0 == EVP_sha512()) and derivation
  * iterations nDeriveIterations. vchOtherDerivationParameters is provided for
  * alternative algorithms which may require more parameters (such as scrypt).
  *
  * Wallet Private Keys are then encrypted using AES-256-CBC with the
  * double-sha256 of the public key as the IV, and the master key's key as the
  * encryption key (see keystore.[ch]).
  */
 
 /** Master key for wallet encryption */
 class CMasterKey {
 public:
-    std::vector<unsigned char> vchCryptedKey;
-    std::vector<unsigned char> vchSalt;
+    std::vector<uint8_t> vchCryptedKey;
+    std::vector<uint8_t> vchSalt;
     //! 0 = EVP_sha512()
     //! 1 = scrypt()
     unsigned int nDerivationMethod;
     unsigned int nDeriveIterations;
     //! Use this for more parameters to key derivation, such as the various
     //! parameters to scrypt
-    std::vector<unsigned char> vchOtherDerivationParameters;
+    std::vector<uint8_t> vchOtherDerivationParameters;
 
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
     inline void SerializationOp(Stream &s, Operation ser_action) {
         READWRITE(vchCryptedKey);
         READWRITE(vchSalt);
         READWRITE(nDerivationMethod);
         READWRITE(nDeriveIterations);
         READWRITE(vchOtherDerivationParameters);
     }
 
     CMasterKey() {
         // 25000 rounds is just under 0.1 seconds on a 1.86 GHz Pentium M
         // ie slightly lower than the lowest hardware we need bother supporting
         nDeriveIterations = 25000;
         nDerivationMethod = 0;
-        vchOtherDerivationParameters = std::vector<unsigned char>(0);
+        vchOtherDerivationParameters = std::vector<uint8_t>(0);
     }
 };
 
-typedef std::vector<unsigned char, secure_allocator<unsigned char>>
-    CKeyingMaterial;
+typedef std::vector<uint8_t, secure_allocator<uint8_t>> CKeyingMaterial;
 
 namespace wallet_crypto {
 class TestCrypter;
 }
 
 /** Encryption/decryption context with key information */
 class CCrypter {
     // for test access to chKey/chIV
     friend class wallet_crypto::TestCrypter;
 
 private:
-    std::vector<unsigned char, secure_allocator<unsigned char>> vchKey;
-    std::vector<unsigned char, secure_allocator<unsigned char>> vchIV;
+    std::vector<uint8_t, secure_allocator<uint8_t>> vchKey;
+    std::vector<uint8_t, secure_allocator<uint8_t>> vchIV;
     bool fKeySet;
 
-    int BytesToKeySHA512AES(const std::vector<unsigned char> &chSalt,
+    int BytesToKeySHA512AES(const std::vector<uint8_t> &chSalt,
                             const SecureString &strKeyData, int count,
-                            unsigned char *key, unsigned char *iv) const;
+                            uint8_t *key, uint8_t *iv) const;
 
 public:
     bool SetKeyFromPassphrase(const SecureString &strKeyData,
-                              const std::vector<unsigned char> &chSalt,
+                              const std::vector<uint8_t> &chSalt,
                               const unsigned int nRounds,
                               const unsigned int nDerivationMethod);
     bool Encrypt(const CKeyingMaterial &vchPlaintext,
-                 std::vector<unsigned char> &vchCiphertext) const;
-    bool Decrypt(const std::vector<unsigned char> &vchCiphertext,
+                 std::vector<uint8_t> &vchCiphertext) const;
+    bool Decrypt(const std::vector<uint8_t> &vchCiphertext,
                  CKeyingMaterial &vchPlaintext) const;
     bool SetKey(const CKeyingMaterial &chNewKey,
-                const std::vector<unsigned char> &chNewIV);
+                const std::vector<uint8_t> &chNewIV);
 
     void CleanKey() {
         memory_cleanse(vchKey.data(), vchKey.size());
         memory_cleanse(vchIV.data(), vchIV.size());
         fKeySet = false;
     }
 
     CCrypter() {
         fKeySet = false;
         vchKey.resize(WALLET_CRYPTO_KEY_SIZE);
         vchIV.resize(WALLET_CRYPTO_IV_SIZE);
     }
 
     ~CCrypter() { CleanKey(); }
 };
 
 /**
  * Keystore which keeps the private keys encrypted.
  * It derives from the basic key store, which is used if no encryption is
  * active.
  */
 class CCryptoKeyStore : public CBasicKeyStore {
 private:
     CryptedKeyMap mapCryptedKeys;
 
     CKeyingMaterial vMasterKey;
 
     //! if fUseCrypto is true, mapKeys must be empty
     //! if fUseCrypto is false, vMasterKey must be empty
     bool fUseCrypto;
 
     //! keeps track of whether Unlock has run a thorough check before
     bool fDecryptionThoroughlyChecked;
 
 protected:
     bool SetCrypted();
 
     //! will encrypt previously unencrypted keys
     bool EncryptKeys(CKeyingMaterial &vMasterKeyIn);
 
     bool Unlock(const CKeyingMaterial &vMasterKeyIn);
 
 public:
     CCryptoKeyStore()
         : fUseCrypto(false), fDecryptionThoroughlyChecked(false) {}
 
     bool IsCrypted() const { return fUseCrypto; }
 
     bool IsLocked() const {
         if (!IsCrypted()) return false;
         bool result;
         {
             LOCK(cs_KeyStore);
             result = vMasterKey.empty();
         }
         return result;
     }
 
     bool Lock();
 
-    virtual bool
-    AddCryptedKey(const CPubKey &vchPubKey,
-                  const std::vector<unsigned char> &vchCryptedSecret);
+    virtual bool AddCryptedKey(const CPubKey &vchPubKey,
+                               const std::vector<uint8_t> &vchCryptedSecret);
     bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey);
     bool HaveKey(const CKeyID &address) const {
         {
             LOCK(cs_KeyStore);
             if (!IsCrypted()) return CBasicKeyStore::HaveKey(address);
             return mapCryptedKeys.count(address) > 0;
         }
         return false;
     }
     bool GetKey(const CKeyID &address, CKey &keyOut) const;
     bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const;
     void GetKeys(std::set<CKeyID> &setAddress) const {
         if (!IsCrypted()) {
             CBasicKeyStore::GetKeys(setAddress);
             return;
         }
         setAddress.clear();
         CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
         while (mi != mapCryptedKeys.end()) {
             setAddress.insert((*mi).first);
             mi++;
         }
     }
 
     /**
      * Wallet status (encrypted, locked) changed.
      * Note: Called without locks held.
      */
     boost::signals2::signal<void(CCryptoKeyStore *wallet)> NotifyStatusChanged;
 };
 
 #endif // BITCOIN_WALLET_CRYPTER_H
diff --git a/src/wallet/db.h b/src/wallet/db.h
index 01400589d..395ec49df 100644
--- a/src/wallet/db.h
+++ b/src/wallet/db.h
@@ -1,287 +1,286 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_WALLET_DB_H
 #define BITCOIN_WALLET_DB_H
 
 #include "clientversion.h"
 #include "serialize.h"
 #include "streams.h"
 #include "sync.h"
 #include "version.h"
 
 #include <map>
 #include <string>
 #include <vector>
 
 #include <boost/filesystem/path.hpp>
 
 #include <db_cxx.h>
 
 static const unsigned int DEFAULT_WALLET_DBLOGSIZE = 100;
 static const bool DEFAULT_WALLET_PRIVDB = true;
 
 class CDBEnv {
 private:
     bool fDbEnvInit;
     bool fMockDb;
     // Don't change into boost::filesystem::path, as that can result in
     // shutdown problems/crashes caused by a static initialized internal
     // pointer.
     std::string strPath;
 
     void EnvShutdown();
 
 public:
     mutable CCriticalSection cs_db;
     DbEnv *dbenv;
     std::map<std::string, int> mapFileUseCount;
     std::map<std::string, Db *> mapDb;
 
     CDBEnv();
     ~CDBEnv();
     void Reset();
 
     void MakeMock();
     bool IsMock() { return fMockDb; }
 
     /**
      * Verify that database file strFile is OK. If it is not, call the callback
      * to try to recover.
      * This must be called BEFORE strFile is opened.
      * Returns true if strFile is OK.
      */
     enum VerifyResult { VERIFY_OK, RECOVER_OK, RECOVER_FAIL };
     VerifyResult Verify(const std::string &strFile,
                         bool (*recoverFunc)(CDBEnv &dbenv,
                                             const std::string &strFile));
     /**
      * Salvage data from a file that Verify says is bad.
      * fAggressive sets the DB_AGGRESSIVE flag (see berkeley DB->verify() method
      * documentation).
      * Appends binary key/value pairs to vResult, returns true if successful.
      * NOTE: reads the entire database into memory, so cannot be used
      * for huge databases.
      */
-    typedef std::pair<std::vector<unsigned char>, std::vector<unsigned char>>
-        KeyValPair;
+    typedef std::pair<std::vector<uint8_t>, std::vector<uint8_t>> KeyValPair;
     bool Salvage(const std::string &strFile, bool fAggressive,
                  std::vector<KeyValPair> &vResult);
 
     bool Open(const boost::filesystem::path &path);
     void Close();
     void Flush(bool fShutdown);
     void CheckpointLSN(const std::string &strFile);
 
     void CloseDb(const std::string &strFile);
     bool RemoveDb(const std::string &strFile);
 
     DbTxn *TxnBegin(int flags = DB_TXN_WRITE_NOSYNC) {
         DbTxn *ptxn = nullptr;
         int ret = dbenv->txn_begin(nullptr, &ptxn, flags);
         if (!ptxn || ret != 0) return nullptr;
         return ptxn;
     }
 };
 
 extern CDBEnv bitdb;
 
 /** RAII class that provides access to a Berkeley database */
 class CDB {
 protected:
     Db *pdb;
     std::string strFile;
     DbTxn *activeTxn;
     bool fReadOnly;
     bool fFlushOnClose;
 
     explicit CDB(const std::string &strFilename, const char *pszMode = "r+",
                  bool fFlushOnCloseIn = true);
     ~CDB() { Close(); }
 
 public:
     void Flush();
     void Close();
 
 private:
     CDB(const CDB &);
     void operator=(const CDB &);
 
 protected:
     template <typename K, typename T> bool Read(const K &key, T &value) {
         if (!pdb) return false;
 
         // Key
         CDataStream ssKey(SER_DISK, CLIENT_VERSION);
         ssKey.reserve(1000);
         ssKey << key;
         Dbt datKey(ssKey.data(), ssKey.size());
 
         // Read
         Dbt datValue;
         datValue.set_flags(DB_DBT_MALLOC);
         int ret = pdb->get(activeTxn, &datKey, &datValue, 0);
         memset(datKey.get_data(), 0, datKey.get_size());
         if (datValue.get_data() == nullptr) return false;
 
         // Unserialize value
         try {
             CDataStream ssValue((char *)datValue.get_data(),
                                 (char *)datValue.get_data() +
                                     datValue.get_size(),
                                 SER_DISK, CLIENT_VERSION);
             ssValue >> value;
         } catch (const std::exception &) {
             return false;
         }
 
         // Clear and free memory
         memset(datValue.get_data(), 0, datValue.get_size());
         free(datValue.get_data());
         return (ret == 0);
     }
 
     template <typename K, typename T>
     bool Write(const K &key, const T &value, bool fOverwrite = true) {
         if (!pdb) return false;
         if (fReadOnly) assert(!"Write called on database in read-only mode");
 
         // Key
         CDataStream ssKey(SER_DISK, CLIENT_VERSION);
         ssKey.reserve(1000);
         ssKey << key;
         Dbt datKey(ssKey.data(), ssKey.size());
 
         // Value
         CDataStream ssValue(SER_DISK, CLIENT_VERSION);
         ssValue.reserve(10000);
         ssValue << value;
         Dbt datValue(ssValue.data(), ssValue.size());
 
         // Write
         int ret = pdb->put(activeTxn, &datKey, &datValue,
                            (fOverwrite ? 0 : DB_NOOVERWRITE));
 
         // Clear memory in case it was a private key
         memset(datKey.get_data(), 0, datKey.get_size());
         memset(datValue.get_data(), 0, datValue.get_size());
         return (ret == 0);
     }
 
     template <typename K> bool Erase(const K &key) {
         if (!pdb) return false;
         if (fReadOnly) assert(!"Erase called on database in read-only mode");
 
         // Key
         CDataStream ssKey(SER_DISK, CLIENT_VERSION);
         ssKey.reserve(1000);
         ssKey << key;
         Dbt datKey(ssKey.data(), ssKey.size());
 
         // Erase
         int ret = pdb->del(activeTxn, &datKey, 0);
 
         // Clear memory
         memset(datKey.get_data(), 0, datKey.get_size());
         return (ret == 0 || ret == DB_NOTFOUND);
     }
 
     template <typename K> bool Exists(const K &key) {
         if (!pdb) return false;
 
         // Key
         CDataStream ssKey(SER_DISK, CLIENT_VERSION);
         ssKey.reserve(1000);
         ssKey << key;
         Dbt datKey(ssKey.data(), ssKey.size());
 
         // Exists
         int ret = pdb->exists(activeTxn, &datKey, 0);
 
         // Clear memory
         memset(datKey.get_data(), 0, datKey.get_size());
         return (ret == 0);
     }
 
     Dbc *GetCursor() {
         if (!pdb) return nullptr;
         Dbc *pcursor = nullptr;
         int ret = pdb->cursor(nullptr, &pcursor, 0);
         if (ret != 0) return nullptr;
         return pcursor;
     }
 
     int ReadAtCursor(Dbc *pcursor, CDataStream &ssKey, CDataStream &ssValue,
                      bool setRange = false) {
         // Read at cursor
         Dbt datKey;
         unsigned int fFlags = DB_NEXT;
         if (setRange) {
             datKey.set_data(ssKey.data());
             datKey.set_size(ssKey.size());
             fFlags = DB_SET_RANGE;
         }
         Dbt datValue;
         datKey.set_flags(DB_DBT_MALLOC);
         datValue.set_flags(DB_DBT_MALLOC);
         int ret = pcursor->get(&datKey, &datValue, fFlags);
         if (ret != 0)
             return ret;
         else if (datKey.get_data() == nullptr || datValue.get_data() == nullptr)
             return 99999;
 
         // Convert to streams
         ssKey.SetType(SER_DISK);
         ssKey.clear();
         ssKey.write((char *)datKey.get_data(), datKey.get_size());
         ssValue.SetType(SER_DISK);
         ssValue.clear();
         ssValue.write((char *)datValue.get_data(), datValue.get_size());
 
         // Clear and free memory
         memset(datKey.get_data(), 0, datKey.get_size());
         memset(datValue.get_data(), 0, datValue.get_size());
         free(datKey.get_data());
         free(datValue.get_data());
         return 0;
     }
 
 public:
     bool TxnBegin() {
         if (!pdb || activeTxn) return false;
         DbTxn *ptxn = bitdb.TxnBegin();
         if (!ptxn) return false;
         activeTxn = ptxn;
         return true;
     }
 
     bool TxnCommit() {
         if (!pdb || !activeTxn) return false;
         int ret = activeTxn->commit(0);
         activeTxn = nullptr;
         return (ret == 0);
     }
 
     bool TxnAbort() {
         if (!pdb || !activeTxn) return false;
         int ret = activeTxn->abort();
         activeTxn = nullptr;
         return (ret == 0);
     }
 
     bool ReadVersion(int &nVersion) {
         nVersion = 0;
         return Read(std::string("version"), nVersion);
     }
 
     bool WriteVersion(int nVersion) {
         return Write(std::string("version"), nVersion);
     }
 
     static bool Rewrite(const std::string &strFile,
                         const char *pszSkip = nullptr);
 };
 
 #endif // BITCOIN_WALLET_DB_H
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp
index 34b907fe6..cbe93d848 100644
--- a/src/wallet/rpcdump.cpp
+++ b/src/wallet/rpcdump.cpp
@@ -1,1254 +1,1254 @@
 // Copyright (c) 2009-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.
 
 #include "base58.h"
 #include "chain.h"
 #include "core_io.h"
 #include "init.h"
 #include "merkleblock.h"
 #include "rpc/server.h"
 #include "script/script.h"
 #include "script/standard.h"
 #include "sync.h"
 #include "util.h"
 #include "utiltime.h"
 #include "validation.h"
 #include "wallet.h"
 
 #include <cstdint>
 #include <fstream>
 
 #include <boost/algorithm/string.hpp>
 #include <boost/date_time/posix_time/posix_time.hpp>
 
 #include <univalue.h>
 
 #include <boost/assign/list_of.hpp>
 
 void EnsureWalletIsUnlocked();
 bool EnsureWalletIsAvailable(bool avoidException);
 
 static std::string EncodeDumpTime(int64_t nTime) {
     return DateTimeStrFormat("%Y-%m-%dT%H:%M:%SZ", nTime);
 }
 
 static int64_t DecodeDumpTime(const std::string &str) {
     static const boost::posix_time::ptime epoch =
         boost::posix_time::from_time_t(0);
     static const std::locale loc(
         std::locale::classic(),
         new boost::posix_time::time_input_facet("%Y-%m-%dT%H:%M:%SZ"));
     std::istringstream iss(str);
     iss.imbue(loc);
     boost::posix_time::ptime ptime(boost::date_time::not_a_date_time);
     iss >> ptime;
     if (ptime.is_not_a_date_time()) return 0;
     return (ptime - epoch).total_seconds();
 }
 
 static std::string EncodeDumpString(const std::string &str) {
     std::stringstream ret;
-    for (unsigned char c : str) {
+    for (uint8_t c : str) {
         if (c <= 32 || c >= 128 || c == '%') {
             ret << '%' << HexStr(&c, &c + 1);
         } else {
             ret << c;
         }
     }
     return ret.str();
 }
 
 std::string DecodeDumpString(const std::string &str) {
     std::stringstream ret;
     for (unsigned int pos = 0; pos < str.length(); pos++) {
-        unsigned char c = str[pos];
+        uint8_t c = str[pos];
         if (c == '%' && pos + 2 < str.length()) {
             c = (((str[pos + 1] >> 6) * 9 + ((str[pos + 1] - '0') & 15)) << 4) |
                 ((str[pos + 2] >> 6) * 9 + ((str[pos + 2] - '0') & 15));
             pos += 2;
         }
         ret << c;
     }
     return ret.str();
 }
 
 UniValue importprivkey(const Config &config, const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue;
 
     if (request.fHelp || request.params.size() < 1 || request.params.size() > 3)
         throw std::runtime_error(
             "importprivkey \"bitcoinprivkey\" ( \"label\" ) ( rescan )\n"
             "\nAdds a private key (as returned by dumpprivkey) to your "
             "wallet.\n"
             "\nArguments:\n"
             "1. \"bitcoinprivkey\"   (string, required) The private key (see "
             "dumpprivkey)\n"
             "2. \"label\"            (string, optional, default=\"\") An "
             "optional label\n"
             "3. rescan               (boolean, optional, default=true) Rescan "
             "the wallet for transactions\n"
             "\nNote: This call can take minutes to complete if rescan is "
             "true.\n"
             "\nExamples:\n"
             "\nDump a private key\n" +
             HelpExampleCli("dumpprivkey", "\"myaddress\"") +
             "\nImport the private key with rescan\n" +
             HelpExampleCli("importprivkey", "\"mykey\"") +
             "\nImport using a label and without rescan\n" +
             HelpExampleCli("importprivkey", "\"mykey\" \"testing\" false") +
             "\nImport using default blank label and without rescan\n" +
             HelpExampleCli("importprivkey", "\"mykey\" \"\" false") +
             "\nAs a JSON-RPC call\n" +
             HelpExampleRpc("importprivkey", "\"mykey\", \"testing\", false"));
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     EnsureWalletIsUnlocked();
 
     std::string strSecret = request.params[0].get_str();
     std::string strLabel = "";
     if (request.params.size() > 1) strLabel = request.params[1].get_str();
 
     // Whether to perform rescan after import
     bool fRescan = true;
     if (request.params.size() > 2) fRescan = request.params[2].get_bool();
 
     if (fRescan && fPruneMode)
         throw JSONRPCError(RPC_WALLET_ERROR,
                            "Rescan is disabled in pruned mode");
 
     CBitcoinSecret vchSecret;
     bool fGood = vchSecret.SetString(strSecret);
 
     if (!fGood)
         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                            "Invalid private key encoding");
 
     CKey key = vchSecret.GetKey();
     if (!key.IsValid())
         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                            "Private key outside allowed range");
 
     CPubKey pubkey = key.GetPubKey();
     assert(key.VerifyPubKey(pubkey));
     CKeyID vchAddress = pubkey.GetID();
     {
         pwalletMain->MarkDirty();
         pwalletMain->SetAddressBook(vchAddress, strLabel, "receive");
 
         // Don't throw error in case a key is already there
         if (pwalletMain->HaveKey(vchAddress)) return NullUniValue;
 
         pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = 1;
 
         if (!pwalletMain->AddKeyPubKey(key, pubkey))
             throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet");
 
         // whenever a key is imported, we need to scan the whole chain
         pwalletMain->UpdateTimeFirstKey(1);
 
         if (fRescan) {
             pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true);
         }
     }
 
     return NullUniValue;
 }
 
 void ImportAddress(const CBitcoinAddress &address, const std::string &strLabel);
 void ImportScript(const CScript &script, const std::string &strLabel,
                   bool isRedeemScript) {
     if (!isRedeemScript && ::IsMine(*pwalletMain, script) == ISMINE_SPENDABLE)
         throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the "
                                              "private key for this address or "
                                              "script");
 
     pwalletMain->MarkDirty();
 
     if (!pwalletMain->HaveWatchOnly(script) &&
         !pwalletMain->AddWatchOnly(script, 0 /* nCreateTime */))
         throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
 
     if (isRedeemScript) {
         if (!pwalletMain->HaveCScript(script) &&
             !pwalletMain->AddCScript(script))
             throw JSONRPCError(RPC_WALLET_ERROR,
                                "Error adding p2sh redeemScript to wallet");
         ImportAddress(CBitcoinAddress(CScriptID(script)), strLabel);
     } else {
         CTxDestination destination;
         if (ExtractDestination(script, destination)) {
             pwalletMain->SetAddressBook(destination, strLabel, "receive");
         }
     }
 }
 
 void ImportAddress(const CBitcoinAddress &address,
                    const std::string &strLabel) {
     CScript script = GetScriptForDestination(address.Get());
     ImportScript(script, strLabel, false);
     // add to address book or update label
     if (address.IsValid())
         pwalletMain->SetAddressBook(address.Get(), strLabel, "receive");
 }
 
 UniValue importaddress(const Config &config, const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue;
 
     if (request.fHelp || request.params.size() < 1 || request.params.size() > 4)
         throw std::runtime_error(
             "importaddress \"address\" ( \"label\" rescan p2sh )\n"
             "\nAdds a script (in hex) or address that can be watched as if it "
             "were in your wallet but cannot be used to spend.\n"
             "\nArguments:\n"
             "1. \"script\"           (string, required) The hex-encoded script "
             "(or address)\n"
             "2. \"label\"            (string, optional, default=\"\") An "
             "optional label\n"
             "3. rescan               (boolean, optional, default=true) Rescan "
             "the wallet for transactions\n"
             "4. p2sh                 (boolean, optional, default=false) Add "
             "the P2SH version of the script as well\n"
             "\nNote: This call can take minutes to complete if rescan is "
             "true.\n"
             "If you have the full public key, you should call importpubkey "
             "instead of this.\n"
             "\nNote: If you import a non-standard raw script in hex form, "
             "outputs sending to it will be treated\n"
             "as change, and not show up in many RPCs.\n"
             "\nExamples:\n"
             "\nImport a script with rescan\n" +
             HelpExampleCli("importaddress", "\"myscript\"") +
             "\nImport using a label without rescan\n" +
             HelpExampleCli("importaddress", "\"myscript\" \"testing\" false") +
             "\nAs a JSON-RPC call\n" +
             HelpExampleRpc("importaddress",
                            "\"myscript\", \"testing\", false"));
 
     std::string strLabel = "";
     if (request.params.size() > 1) strLabel = request.params[1].get_str();
 
     // Whether to perform rescan after import
     bool fRescan = true;
     if (request.params.size() > 2) fRescan = request.params[2].get_bool();
 
     if (fRescan && fPruneMode)
         throw JSONRPCError(RPC_WALLET_ERROR,
                            "Rescan is disabled in pruned mode");
 
     // Whether to import a p2sh version, too
     bool fP2SH = false;
     if (request.params.size() > 3) fP2SH = request.params[3].get_bool();
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     CBitcoinAddress address(request.params[0].get_str());
     if (address.IsValid()) {
         if (fP2SH)
             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                                "Cannot use the p2sh flag with an address - use "
                                "a script instead");
         ImportAddress(address, strLabel);
     } else if (IsHex(request.params[0].get_str())) {
-        std::vector<unsigned char> data(ParseHex(request.params[0].get_str()));
+        std::vector<uint8_t> data(ParseHex(request.params[0].get_str()));
         ImportScript(CScript(data.begin(), data.end()), strLabel, fP2SH);
     } else {
         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                            "Invalid Bitcoin address or script");
     }
 
     if (fRescan) {
         pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true);
         pwalletMain->ReacceptWalletTransactions();
     }
 
     return NullUniValue;
 }
 
 UniValue importprunedfunds(const Config &config,
                            const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue;
 
     if (request.fHelp || request.params.size() != 2)
         throw std::runtime_error(
             "importprunedfunds\n"
             "\nImports funds without rescan. Corresponding address or script "
             "must previously be included in wallet. Aimed towards pruned "
             "wallets. The end-user is responsible to import additional "
             "transactions that subsequently spend the imported outputs or "
             "rescan after the point in the blockchain the transaction is "
             "included.\n"
             "\nArguments:\n"
             "1. \"rawtransaction\" (string, required) A raw transaction in hex "
             "funding an already-existing address in wallet\n"
             "2. \"txoutproof\"     (string, required) The hex output from "
             "gettxoutproof that contains the transaction\n");
 
     CMutableTransaction tx;
     if (!DecodeHexTx(tx, request.params[0].get_str()))
         throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
     uint256 txid = tx.GetId();
     CWalletTx wtx(pwalletMain, MakeTransactionRef(std::move(tx)));
 
     CDataStream ssMB(ParseHexV(request.params[1], "proof"), SER_NETWORK,
                      PROTOCOL_VERSION);
     CMerkleBlock merkleBlock;
     ssMB >> merkleBlock;
 
     // Search partial merkle tree in proof for our transaction and index in
     // valid block
     std::vector<uint256> vMatch;
     std::vector<unsigned int> vIndex;
     unsigned int txnIndex = 0;
     if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) ==
         merkleBlock.header.hashMerkleRoot) {
 
         LOCK(cs_main);
 
         if (!mapBlockIndex.count(merkleBlock.header.GetHash()) ||
             !chainActive.Contains(mapBlockIndex[merkleBlock.header.GetHash()]))
             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                                "Block not found in chain");
 
         std::vector<uint256>::const_iterator it;
         if ((it = std::find(vMatch.begin(), vMatch.end(), txid)) ==
             vMatch.end()) {
             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                                "Transaction given doesn't exist in proof");
         }
 
         txnIndex = vIndex[it - vMatch.begin()];
     } else {
         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                            "Something wrong with merkleblock");
     }
 
     wtx.nIndex = txnIndex;
     wtx.hashBlock = merkleBlock.header.GetHash();
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     if (pwalletMain->IsMine(wtx)) {
         pwalletMain->AddToWallet(wtx, false);
         return NullUniValue;
     }
 
     throw JSONRPCError(
         RPC_INVALID_ADDRESS_OR_KEY,
         "No addresses in wallet correspond to included transaction");
 }
 
 UniValue removeprunedfunds(const Config &config,
                            const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue;
 
     if (request.fHelp || request.params.size() != 1)
         throw std::runtime_error(
             "removeprunedfunds \"txid\"\n"
             "\nDeletes the specified transaction from the wallet. Meant for "
             "use with pruned wallets and as a companion to importprunedfunds. "
             "This will effect wallet balances.\n"
             "\nArguments:\n"
             "1. \"txid\"           (string, required) The hex-encoded id of "
             "the transaction you are deleting\n"
             "\nExamples:\n" +
             HelpExampleCli("removeprunedfunds", "\"a8d0c0184dde994a09ec054286f1"
                                                 "ce581bebf46446a512166eae762873"
                                                 "4ea0a5\"") +
             "\nAs a JSON-RPC call\n" +
             HelpExampleRpc("removprunedfunds", "\"a8d0c0184dde994a09ec054286f1c"
                                                "e581bebf46446a512166eae7628734e"
                                                "a0a5\""));
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     uint256 hash;
     hash.SetHex(request.params[0].get_str());
     std::vector<uint256> vHash;
     vHash.push_back(hash);
     std::vector<uint256> vHashOut;
 
     if (pwalletMain->ZapSelectTx(vHash, vHashOut) != DB_LOAD_OK) {
         throw JSONRPCError(RPC_INTERNAL_ERROR,
                            "Could not properly delete the transaction.");
     }
 
     if (vHashOut.empty()) {
         throw JSONRPCError(RPC_INTERNAL_ERROR,
                            "Transaction does not exist in wallet.");
     }
 
     return NullUniValue;
 }
 
 UniValue importpubkey(const Config &config, const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue;
 
     if (request.fHelp || request.params.size() < 1 || request.params.size() > 4)
         throw std::runtime_error(
             "importpubkey \"pubkey\" ( \"label\" rescan )\n"
             "\nAdds a public key (in hex) that can be watched as if it were in "
             "your wallet but cannot be used to spend.\n"
             "\nArguments:\n"
             "1. \"pubkey\"           (string, required) The hex-encoded public "
             "key\n"
             "2. \"label\"            (string, optional, default=\"\") An "
             "optional label\n"
             "3. rescan               (boolean, optional, default=true) Rescan "
             "the wallet for transactions\n"
             "\nNote: This call can take minutes to complete if rescan is "
             "true.\n"
             "\nExamples:\n"
             "\nImport a public key with rescan\n" +
             HelpExampleCli("importpubkey", "\"mypubkey\"") +
             "\nImport using a label without rescan\n" +
             HelpExampleCli("importpubkey", "\"mypubkey\" \"testing\" false") +
             "\nAs a JSON-RPC call\n" +
             HelpExampleRpc("importpubkey", "\"mypubkey\", \"testing\", false"));
 
     std::string strLabel = "";
     if (request.params.size() > 1) strLabel = request.params[1].get_str();
 
     // Whether to perform rescan after import
     bool fRescan = true;
     if (request.params.size() > 2) fRescan = request.params[2].get_bool();
 
     if (fRescan && fPruneMode)
         throw JSONRPCError(RPC_WALLET_ERROR,
                            "Rescan is disabled in pruned mode");
 
     if (!IsHex(request.params[0].get_str()))
         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                            "Pubkey must be a hex string");
-    std::vector<unsigned char> data(ParseHex(request.params[0].get_str()));
+    std::vector<uint8_t> data(ParseHex(request.params[0].get_str()));
     CPubKey pubKey(data.begin(), data.end());
     if (!pubKey.IsFullyValid())
         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                            "Pubkey is not a valid public key");
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     ImportAddress(CBitcoinAddress(pubKey.GetID()), strLabel);
     ImportScript(GetScriptForRawPubKey(pubKey), strLabel, false);
 
     if (fRescan) {
         pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true);
         pwalletMain->ReacceptWalletTransactions();
     }
 
     return NullUniValue;
 }
 
 UniValue importwallet(const Config &config, const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue;
 
     if (request.fHelp || request.params.size() != 1)
         throw std::runtime_error(
             "importwallet \"filename\"\n"
             "\nImports keys from a wallet dump file (see dumpwallet).\n"
             "\nArguments:\n"
             "1. \"filename\"    (string, required) The wallet file\n"
             "\nExamples:\n"
             "\nDump the wallet\n" +
             HelpExampleCli("dumpwallet", "\"test\"") + "\nImport the wallet\n" +
             HelpExampleCli("importwallet", "\"test\"") +
             "\nImport using the json rpc call\n" +
             HelpExampleRpc("importwallet", "\"test\""));
 
     if (fPruneMode)
         throw JSONRPCError(RPC_WALLET_ERROR,
                            "Importing wallets is disabled in pruned mode");
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     EnsureWalletIsUnlocked();
 
     std::ifstream file;
     file.open(request.params[0].get_str().c_str(),
               std::ios::in | std::ios::ate);
     if (!file.is_open())
         throw JSONRPCError(RPC_INVALID_PARAMETER,
                            "Cannot open wallet dump file");
 
     int64_t nTimeBegin = chainActive.Tip()->GetBlockTime();
 
     bool fGood = true;
 
     int64_t nFilesize = std::max((int64_t)1, (int64_t)file.tellg());
     file.seekg(0, file.beg);
 
     pwalletMain->ShowProgress(_("Importing..."),
                               0); // show progress dialog in GUI
     while (file.good()) {
         pwalletMain->ShowProgress(
             "", std::max(1, std::min(99, (int)(((double)file.tellg() /
                                                 (double)nFilesize) *
                                                100))));
         std::string line;
         std::getline(file, line);
         if (line.empty() || line[0] == '#') continue;
 
         std::vector<std::string> vstr;
         boost::split(vstr, line, boost::is_any_of(" "));
         if (vstr.size() < 2) continue;
         CBitcoinSecret vchSecret;
         if (!vchSecret.SetString(vstr[0])) continue;
         CKey key = vchSecret.GetKey();
         CPubKey pubkey = key.GetPubKey();
         assert(key.VerifyPubKey(pubkey));
         CKeyID keyid = pubkey.GetID();
         if (pwalletMain->HaveKey(keyid)) {
             LogPrintf("Skipping import of %s (key already present)\n",
                       CBitcoinAddress(keyid).ToString());
             continue;
         }
         int64_t nTime = DecodeDumpTime(vstr[1]);
         std::string strLabel;
         bool fLabel = true;
         for (unsigned int nStr = 2; nStr < vstr.size(); nStr++) {
             if (boost::algorithm::starts_with(vstr[nStr], "#")) break;
             if (vstr[nStr] == "change=1") fLabel = false;
             if (vstr[nStr] == "reserve=1") fLabel = false;
             if (boost::algorithm::starts_with(vstr[nStr], "label=")) {
                 strLabel = DecodeDumpString(vstr[nStr].substr(6));
                 fLabel = true;
             }
         }
         LogPrintf("Importing %s...\n", CBitcoinAddress(keyid).ToString());
         if (!pwalletMain->AddKeyPubKey(key, pubkey)) {
             fGood = false;
             continue;
         }
         pwalletMain->mapKeyMetadata[keyid].nCreateTime = nTime;
         if (fLabel) pwalletMain->SetAddressBook(keyid, strLabel, "receive");
         nTimeBegin = std::min(nTimeBegin, nTime);
     }
     file.close();
     pwalletMain->ShowProgress("", 100); // hide progress dialog in GUI
 
     CBlockIndex *pindex = chainActive.Tip();
     while (pindex && pindex->pprev &&
            pindex->GetBlockTime() > nTimeBegin - 7200)
         pindex = pindex->pprev;
 
     pwalletMain->UpdateTimeFirstKey(nTimeBegin);
 
     LogPrintf("Rescanning last %i blocks\n",
               chainActive.Height() - pindex->nHeight + 1);
     pwalletMain->ScanForWalletTransactions(pindex);
     pwalletMain->MarkDirty();
 
     if (!fGood)
         throw JSONRPCError(RPC_WALLET_ERROR,
                            "Error adding some keys to wallet");
 
     return NullUniValue;
 }
 
 UniValue dumpprivkey(const Config &config, const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue;
 
     if (request.fHelp || request.params.size() != 1)
         throw std::runtime_error(
             "dumpprivkey \"address\"\n"
             "\nReveals the private key corresponding to 'address'.\n"
             "Then the importprivkey can be used with this output\n"
             "\nArguments:\n"
             "1. \"address\"   (string, required) The bitcoin address for the "
             "private key\n"
             "\nResult:\n"
             "\"key\"                (string) The private key\n"
             "\nExamples:\n" +
             HelpExampleCli("dumpprivkey", "\"myaddress\"") +
             HelpExampleCli("importprivkey", "\"mykey\"") +
             HelpExampleRpc("dumpprivkey", "\"myaddress\""));
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     EnsureWalletIsUnlocked();
 
     std::string strAddress = request.params[0].get_str();
     CBitcoinAddress address;
     if (!address.SetString(strAddress))
         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                            "Invalid Bitcoin address");
     CKeyID keyID;
     if (!address.GetKeyID(keyID))
         throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to a key");
     CKey vchSecret;
     if (!pwalletMain->GetKey(keyID, vchSecret))
         throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " +
                                                  strAddress + " is not known");
     return CBitcoinSecret(vchSecret).ToString();
 }
 
 UniValue dumpwallet(const Config &config, const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue;
 
     if (request.fHelp || request.params.size() != 1)
         throw std::runtime_error(
             "dumpwallet \"filename\"\n"
             "\nDumps all wallet keys in a human-readable format.\n"
             "\nArguments:\n"
             "1. \"filename\"    (string, required) The filename\n"
             "\nExamples:\n" +
             HelpExampleCli("dumpwallet", "\"test\"") +
             HelpExampleRpc("dumpwallet", "\"test\""));
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     EnsureWalletIsUnlocked();
 
     std::ofstream file;
     file.open(request.params[0].get_str().c_str());
     if (!file.is_open())
         throw JSONRPCError(RPC_INVALID_PARAMETER,
                            "Cannot open wallet dump file");
 
     std::map<CTxDestination, int64_t> mapKeyBirth;
     std::set<CKeyID> setKeyPool;
     pwalletMain->GetKeyBirthTimes(mapKeyBirth);
     pwalletMain->GetAllReserveKeys(setKeyPool);
 
     // sort time/key pairs
     std::vector<std::pair<int64_t, CKeyID>> vKeyBirth;
     for (const auto &entry : mapKeyBirth) {
         if (const CKeyID *keyID =
                 boost::get<CKeyID>(&entry.first)) { // set and test
             vKeyBirth.push_back(std::make_pair(entry.second, *keyID));
         }
     }
     mapKeyBirth.clear();
     std::sort(vKeyBirth.begin(), vKeyBirth.end());
 
     // produce output
     file << strprintf("# Wallet dump created by Bitcoin %s\n", CLIENT_BUILD);
     file << strprintf("# * Created on %s\n", EncodeDumpTime(GetTime()));
     file << strprintf("# * Best block at time of backup was %i (%s),\n",
                       chainActive.Height(),
                       chainActive.Tip()->GetBlockHash().ToString());
     file << strprintf("#   mined on %s\n",
                       EncodeDumpTime(chainActive.Tip()->GetBlockTime()));
     file << "\n";
 
     // add the base58check encoded extended master if the wallet uses HD
     CKeyID masterKeyID = pwalletMain->GetHDChain().masterKeyID;
     if (!masterKeyID.IsNull()) {
         CKey key;
         if (pwalletMain->GetKey(masterKeyID, key)) {
             CExtKey masterKey;
             masterKey.SetMaster(key.begin(), key.size());
 
             CBitcoinExtKey b58extkey;
             b58extkey.SetKey(masterKey);
 
             file << "# extended private masterkey: " << b58extkey.ToString()
                  << "\n\n";
         }
     }
     for (std::vector<std::pair<int64_t, CKeyID>>::const_iterator it =
              vKeyBirth.begin();
          it != vKeyBirth.end(); it++) {
         const CKeyID &keyid = it->second;
         std::string strTime = EncodeDumpTime(it->first);
         std::string strAddr = CBitcoinAddress(keyid).ToString();
         CKey key;
         if (pwalletMain->GetKey(keyid, key)) {
             file << strprintf("%s %s ", CBitcoinSecret(key).ToString(),
                               strTime);
             if (pwalletMain->mapAddressBook.count(keyid)) {
                 file << strprintf(
                     "label=%s",
                     EncodeDumpString(pwalletMain->mapAddressBook[keyid].name));
             } else if (keyid == masterKeyID) {
                 file << "hdmaster=1";
             } else if (setKeyPool.count(keyid)) {
                 file << "reserve=1";
             } else if (pwalletMain->mapKeyMetadata[keyid].hdKeypath == "m") {
                 file << "inactivehdmaster=1";
             } else {
                 file << "change=1";
             }
             file << strprintf(
                 " # addr=%s%s\n", strAddr,
                 (pwalletMain->mapKeyMetadata[keyid].hdKeypath.size() > 0
                      ? " hdkeypath=" +
                            pwalletMain->mapKeyMetadata[keyid].hdKeypath
                      : ""));
         }
     }
     file << "\n";
     file << "# End of dump\n";
     file.close();
     return NullUniValue;
 }
 
 UniValue ProcessImport(const UniValue &data, const int64_t timestamp) {
     try {
         bool success = false;
 
         // Required fields.
         const UniValue &scriptPubKey = data["scriptPubKey"];
 
         // Should have script or JSON with "address".
         if (!(scriptPubKey.getType() == UniValue::VOBJ &&
               scriptPubKey.exists("address")) &&
             !(scriptPubKey.getType() == UniValue::VSTR)) {
             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid scriptPubKey");
         }
 
         // Optional fields.
         const std::string &strRedeemScript =
             data.exists("redeemscript") ? data["redeemscript"].get_str() : "";
         const UniValue &pubKeys =
             data.exists("pubkeys") ? data["pubkeys"].get_array() : UniValue();
         const UniValue &keys =
             data.exists("keys") ? data["keys"].get_array() : UniValue();
         const bool &internal =
             data.exists("internal") ? data["internal"].get_bool() : false;
         const bool &watchOnly =
             data.exists("watchonly") ? data["watchonly"].get_bool() : false;
         const std::string &label =
             data.exists("label") && !internal ? data["label"].get_str() : "";
 
         bool isScript = scriptPubKey.getType() == UniValue::VSTR;
         bool isP2SH = strRedeemScript.length() > 0;
         const std::string &output = isScript
                                         ? scriptPubKey.get_str()
                                         : scriptPubKey["address"].get_str();
 
         // Parse the output.
         CScript script;
         CBitcoinAddress address;
 
         if (!isScript) {
             address = CBitcoinAddress(output);
             if (!address.IsValid()) {
                 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                                    "Invalid address");
             }
             script = GetScriptForDestination(address.Get());
         } else {
             if (!IsHex(output)) {
                 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                                    "Invalid scriptPubKey");
             }
 
-            std::vector<unsigned char> vData(ParseHex(output));
+            std::vector<uint8_t> vData(ParseHex(output));
             script = CScript(vData.begin(), vData.end());
         }
 
         // Watchonly and private keys
         if (watchOnly && keys.size()) {
             throw JSONRPCError(
                 RPC_INVALID_PARAMETER,
                 "Incompatibility found between watchonly and keys");
         }
 
         // Internal + Label
         if (internal && data.exists("label")) {
             throw JSONRPCError(
                 RPC_INVALID_PARAMETER,
                 "Incompatibility found between internal and label");
         }
 
         // Not having Internal + Script
         if (!internal && isScript) {
             throw JSONRPCError(RPC_INVALID_PARAMETER,
                                "Internal must be set for hex scriptPubKey");
         }
 
         // Keys / PubKeys size check.
         if (!isP2SH &&
             (keys.size() > 1 || pubKeys.size() > 1)) { // Address / scriptPubKey
             throw JSONRPCError(RPC_INVALID_PARAMETER,
                                "More than private key given for one address");
         }
 
         // Invalid P2SH redeemScript
         if (isP2SH && !IsHex(strRedeemScript)) {
             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                                "Invalid redeem script");
         }
 
         // Process. //
 
         // P2SH
         if (isP2SH) {
             // Import redeem script.
-            std::vector<unsigned char> vData(ParseHex(strRedeemScript));
+            std::vector<uint8_t> vData(ParseHex(strRedeemScript));
             CScript redeemScript = CScript(vData.begin(), vData.end());
 
             // Invalid P2SH address
             if (!script.IsPayToScriptHash()) {
                 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                                    "Invalid P2SH address / script");
             }
 
             pwalletMain->MarkDirty();
 
             if (!pwalletMain->HaveWatchOnly(redeemScript) &&
                 !pwalletMain->AddWatchOnly(redeemScript, timestamp)) {
                 throw JSONRPCError(RPC_WALLET_ERROR,
                                    "Error adding address to wallet");
             }
 
             if (!pwalletMain->HaveCScript(redeemScript) &&
                 !pwalletMain->AddCScript(redeemScript)) {
                 throw JSONRPCError(RPC_WALLET_ERROR,
                                    "Error adding p2sh redeemScript to wallet");
             }
 
             CBitcoinAddress redeemAddress =
                 CBitcoinAddress(CScriptID(redeemScript));
             CScript redeemDestination =
                 GetScriptForDestination(redeemAddress.Get());
 
             if (::IsMine(*pwalletMain, redeemDestination) == ISMINE_SPENDABLE) {
                 throw JSONRPCError(RPC_WALLET_ERROR,
                                    "The wallet already contains the private "
                                    "key for this address or script");
             }
 
             pwalletMain->MarkDirty();
 
             if (!pwalletMain->HaveWatchOnly(redeemDestination) &&
                 !pwalletMain->AddWatchOnly(redeemDestination, timestamp)) {
                 throw JSONRPCError(RPC_WALLET_ERROR,
                                    "Error adding address to wallet");
             }
 
             // add to address book or update label
             if (address.IsValid()) {
                 pwalletMain->SetAddressBook(address.Get(), label, "receive");
             }
 
             // Import private keys.
             if (keys.size()) {
                 for (size_t i = 0; i < keys.size(); i++) {
                     const std::string &privkey = keys[i].get_str();
 
                     CBitcoinSecret vchSecret;
                     bool fGood = vchSecret.SetString(privkey);
 
                     if (!fGood) {
                         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                                            "Invalid private key encoding");
                     }
 
                     CKey key = vchSecret.GetKey();
 
                     if (!key.IsValid()) {
                         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                                            "Private key outside allowed range");
                     }
 
                     CPubKey pubkey = key.GetPubKey();
                     assert(key.VerifyPubKey(pubkey));
 
                     CKeyID vchAddress = pubkey.GetID();
                     pwalletMain->MarkDirty();
                     pwalletMain->SetAddressBook(vchAddress, label, "receive");
 
                     if (pwalletMain->HaveKey(vchAddress)) {
                         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                                            "Already have this key");
                     }
 
                     pwalletMain->mapKeyMetadata[vchAddress].nCreateTime =
                         timestamp;
 
                     if (!pwalletMain->AddKeyPubKey(key, pubkey)) {
                         throw JSONRPCError(RPC_WALLET_ERROR,
                                            "Error adding key to wallet");
                     }
 
                     pwalletMain->UpdateTimeFirstKey(timestamp);
                 }
             }
 
             success = true;
         } else {
             // Import public keys.
             if (pubKeys.size() && keys.size() == 0) {
                 const std::string &strPubKey = pubKeys[0].get_str();
 
                 if (!IsHex(strPubKey)) {
                     throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                                        "Pubkey must be a hex string");
                 }
 
-                std::vector<unsigned char> vData(ParseHex(strPubKey));
+                std::vector<uint8_t> vData(ParseHex(strPubKey));
                 CPubKey pubKey(vData.begin(), vData.end());
 
                 if (!pubKey.IsFullyValid()) {
                     throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                                        "Pubkey is not a valid public key");
                 }
 
                 CBitcoinAddress pubKeyAddress = CBitcoinAddress(pubKey.GetID());
 
                 // Consistency check.
                 if (!isScript && !(pubKeyAddress.Get() == address.Get())) {
                     throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                                        "Consistency check failed");
                 }
 
                 // Consistency check.
                 if (isScript) {
                     CBitcoinAddress scriptAddress;
                     CTxDestination destination;
 
                     if (ExtractDestination(script, destination)) {
                         scriptAddress = CBitcoinAddress(destination);
                         if (!(scriptAddress.Get() == pubKeyAddress.Get())) {
                             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                                                "Consistency check failed");
                         }
                     }
                 }
 
                 CScript pubKeyScript =
                     GetScriptForDestination(pubKeyAddress.Get());
 
                 if (::IsMine(*pwalletMain, pubKeyScript) == ISMINE_SPENDABLE) {
                     throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already "
                                                          "contains the private "
                                                          "key for this address "
                                                          "or script");
                 }
 
                 pwalletMain->MarkDirty();
 
                 if (!pwalletMain->HaveWatchOnly(pubKeyScript) &&
                     !pwalletMain->AddWatchOnly(pubKeyScript, timestamp)) {
                     throw JSONRPCError(RPC_WALLET_ERROR,
                                        "Error adding address to wallet");
                 }
 
                 // add to address book or update label
                 if (pubKeyAddress.IsValid()) {
                     pwalletMain->SetAddressBook(pubKeyAddress.Get(), label,
                                                 "receive");
                 }
 
                 // TODO Is this necessary?
                 CScript scriptRawPubKey = GetScriptForRawPubKey(pubKey);
 
                 if (::IsMine(*pwalletMain, scriptRawPubKey) ==
                     ISMINE_SPENDABLE) {
                     throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already "
                                                          "contains the private "
                                                          "key for this address "
                                                          "or script");
                 }
 
                 pwalletMain->MarkDirty();
 
                 if (!pwalletMain->HaveWatchOnly(scriptRawPubKey) &&
                     !pwalletMain->AddWatchOnly(scriptRawPubKey, timestamp)) {
                     throw JSONRPCError(RPC_WALLET_ERROR,
                                        "Error adding address to wallet");
                 }
 
                 success = true;
             }
 
             // Import private keys.
             if (keys.size()) {
                 const std::string &strPrivkey = keys[0].get_str();
 
                 // Checks.
                 CBitcoinSecret vchSecret;
                 bool fGood = vchSecret.SetString(strPrivkey);
 
                 if (!fGood) {
                     throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                                        "Invalid private key encoding");
                 }
 
                 CKey key = vchSecret.GetKey();
                 if (!key.IsValid()) {
                     throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                                        "Private key outside allowed range");
                 }
 
                 CPubKey pubKey = key.GetPubKey();
                 assert(key.VerifyPubKey(pubKey));
 
                 CBitcoinAddress pubKeyAddress = CBitcoinAddress(pubKey.GetID());
 
                 // Consistency check.
                 if (!isScript && !(pubKeyAddress.Get() == address.Get())) {
                     throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                                        "Consistency check failed");
                 }
 
                 // Consistency check.
                 if (isScript) {
                     CBitcoinAddress scriptAddress;
                     CTxDestination destination;
 
                     if (ExtractDestination(script, destination)) {
                         scriptAddress = CBitcoinAddress(destination);
                         if (!(scriptAddress.Get() == pubKeyAddress.Get())) {
                             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                                                "Consistency check failed");
                         }
                     }
                 }
 
                 CKeyID vchAddress = pubKey.GetID();
                 pwalletMain->MarkDirty();
                 pwalletMain->SetAddressBook(vchAddress, label, "receive");
 
                 if (pwalletMain->HaveKey(vchAddress)) {
                     return false;
                 }
 
                 pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = timestamp;
 
                 if (!pwalletMain->AddKeyPubKey(key, pubKey)) {
                     throw JSONRPCError(RPC_WALLET_ERROR,
                                        "Error adding key to wallet");
                 }
 
                 pwalletMain->UpdateTimeFirstKey(timestamp);
 
                 success = true;
             }
 
             // Import scriptPubKey only.
             if (pubKeys.size() == 0 && keys.size() == 0) {
                 if (::IsMine(*pwalletMain, script) == ISMINE_SPENDABLE) {
                     throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already "
                                                          "contains the private "
                                                          "key for this address "
                                                          "or script");
                 }
 
                 pwalletMain->MarkDirty();
 
                 if (!pwalletMain->HaveWatchOnly(script) &&
                     !pwalletMain->AddWatchOnly(script, timestamp)) {
                     throw JSONRPCError(RPC_WALLET_ERROR,
                                        "Error adding address to wallet");
                 }
 
                 if (scriptPubKey.getType() == UniValue::VOBJ) {
                     // add to address book or update label
                     if (address.IsValid()) {
                         pwalletMain->SetAddressBook(address.Get(), label,
                                                     "receive");
                     }
                 }
 
                 success = true;
             }
         }
 
         UniValue result = UniValue(UniValue::VOBJ);
         result.pushKV("success", UniValue(success));
         return result;
     } catch (const UniValue &e) {
         UniValue result = UniValue(UniValue::VOBJ);
         result.pushKV("success", UniValue(false));
         result.pushKV("error", e);
         return result;
     } catch (...) {
         UniValue result = UniValue(UniValue::VOBJ);
         result.pushKV("success", UniValue(false));
         result.pushKV("error",
                       JSONRPCError(RPC_MISC_ERROR, "Missing required fields"));
         return result;
     }
 }
 
 int64_t GetImportTimestamp(const UniValue &data, int64_t now) {
     if (data.exists("timestamp")) {
         const UniValue &timestamp = data["timestamp"];
         if (timestamp.isNum()) {
             return timestamp.get_int64();
         } else if (timestamp.isStr() && timestamp.get_str() == "now") {
             return now;
         }
         throw JSONRPCError(RPC_TYPE_ERROR,
                            strprintf("Expected number or \"now\" timestamp "
                                      "value for key. got type %s",
                                      uvTypeName(timestamp.type())));
     }
     throw JSONRPCError(RPC_TYPE_ERROR,
                        "Missing required timestamp field for key");
 }
 
 UniValue importmulti(const Config &config, const JSONRPCRequest &mainRequest) {
     // clang-format off
     if (mainRequest.fHelp || mainRequest.params.size() < 1 || mainRequest.params.size() > 2)
         throw std::runtime_error(
             "importmulti \"requests\" \"options\"\n\n"
             "Import addresses/scripts (with private or public keys, redeem script (P2SH)), rescanning all addresses in one-shot-only (rescan can be disabled via options).\n\n"
             "Arguments:\n"
             "1. requests     (array, required) Data to be imported\n"
             "  [     (array of json objects)\n"
             "    {\n"
             "      \"scriptPubKey\": \"<script>\" | { \"address\":\"<address>\" }, (string / json, required) Type of scriptPubKey (string for script, json for address)\n"
             "      \"timestamp\": timestamp | \"now\"                        , (integer / string, required) Creation time of the key in seconds since epoch (Jan 1 1970 GMT),\n"
             "                                                              or the string \"now\" to substitute the current synced blockchain time. The timestamp of the oldest\n"
             "                                                              key will determine how far back blockchain rescans need to begin for missing wallet transactions.\n"
             "                                                              \"now\" can be specified to bypass scanning, for keys which are known to never have been used, and\n"
             "                                                              0 can be specified to scan the entire blockchain. Blocks up to 2 hours before the earliest key\n"
             "                                                              creation time of all keys being imported by the importmulti call will be scanned.\n"
             "      \"redeemscript\": \"<script>\"                            , (string, optional) Allowed only if the scriptPubKey is a P2SH address or a P2SH scriptPubKey\n"
             "      \"pubkeys\": [\"<pubKey>\", ... ]                         , (array, optional) Array of strings giving pubkeys that must occur in the output or redeemscript\n"
             "      \"keys\": [\"<key>\", ... ]                               , (array, optional) Array of strings giving private keys whose corresponding public keys must occur in the output or redeemscript\n"
             "      \"internal\": <true>                                    , (boolean, optional, default: false) Stating whether matching outputs should be be treated as not incoming payments\n"
             "      \"watchonly\": <true>                                   , (boolean, optional, default: false) Stating whether matching outputs should be considered watched even when they're not spendable, only allowed if keys are empty\n"
             "      \"label\": <label>                                      , (string, optional, default: '') Label to assign to the address (aka account name, for now), only allowed with internal=false\n"
             "    }\n"
             "  ,...\n"
             "  ]\n"
             "2. options                 (json, optional)\n"
             "  {\n"
             "     \"rescan\": <false>,         (boolean, optional, default: true) Stating if should rescan the blockchain after all imports\n"
             "  }\n"
             "\nExamples:\n" +
             HelpExampleCli("importmulti", "'[{ \"scriptPubKey\": { \"address\": \"<my address>\" }, \"timestamp\":1455191478 }, "
                                           "{ \"scriptPubKey\": { \"address\": \"<my 2nd address>\" }, \"label\": \"example 2\", \"timestamp\": 1455191480 }]'") +
             HelpExampleCli("importmulti", "'[{ \"scriptPubKey\": { \"address\": \"<my address>\" }, \"timestamp\":1455191478 }]' '{ \"rescan\": false}'") +
 
             "\nResponse is an array with the same size as the input that has the execution result :\n"
             "  [{ \"success\": true } , { \"success\": false, \"error\": { \"code\": -1, \"message\": \"Internal Server Error\"} }, ... ]\n");
 
     // clang-format on
     if (!EnsureWalletIsAvailable(mainRequest.fHelp)) {
         return NullUniValue;
     }
 
     RPCTypeCheck(mainRequest.params,
                  boost::assign::list_of(UniValue::VARR)(UniValue::VOBJ));
 
     const UniValue &requests = mainRequest.params[0];
 
     // Default options
     bool fRescan = true;
 
     if (mainRequest.params.size() > 1) {
         const UniValue &options = mainRequest.params[1];
 
         if (options.exists("rescan")) {
             fRescan = options["rescan"].get_bool();
         }
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
     EnsureWalletIsUnlocked();
 
     // Verify all timestamps are present before importing any keys.
     const int64_t now =
         chainActive.Tip() ? chainActive.Tip()->GetMedianTimePast() : 0;
     for (const UniValue &data : requests.getValues()) {
         GetImportTimestamp(data, now);
     }
 
     bool fRunScan = false;
     const int64_t minimumTimestamp = 1;
     int64_t nLowestTimestamp = 0;
 
     if (fRescan && chainActive.Tip()) {
         nLowestTimestamp = chainActive.Tip()->GetBlockTime();
     } else {
         fRescan = false;
     }
 
     UniValue response(UniValue::VARR);
 
     for (const UniValue &data : requests.getValues()) {
         const int64_t timestamp =
             std::max(GetImportTimestamp(data, now), minimumTimestamp);
         const UniValue result = ProcessImport(data, timestamp);
         response.push_back(result);
 
         if (!fRescan) {
             continue;
         }
 
         // If at least one request was successful then allow rescan.
         if (result["success"].get_bool()) {
             fRunScan = true;
         }
 
         // Get the lowest timestamp.
         if (timestamp < nLowestTimestamp) {
             nLowestTimestamp = timestamp;
         }
     }
 
     if (fRescan && fRunScan && requests.size()) {
         CBlockIndex *pindex =
             nLowestTimestamp > minimumTimestamp
                 ? chainActive.FindEarliestAtLeast(
                       std::max<int64_t>(nLowestTimestamp - 7200, 0))
                 : chainActive.Genesis();
         CBlockIndex *scannedRange = nullptr;
         if (pindex) {
             scannedRange = pwalletMain->ScanForWalletTransactions(pindex, true);
             pwalletMain->ReacceptWalletTransactions();
         }
 
         if (!scannedRange || scannedRange->nHeight > pindex->nHeight) {
             std::vector<UniValue> results = response.getValues();
             response.clear();
             response.setArray();
             size_t i = 0;
             for (const UniValue &request : requests.getValues()) {
                 // If key creation date is within the successfully scanned
                 // range, or if the import result already has an error set, let
                 // the result stand unmodified. Otherwise replace the result
                 // with an error message.
                 if (GetImportTimestamp(request, now) - 7200 >=
                         scannedRange->GetBlockTimeMax() ||
                     results.at(i).exists("error")) {
                     response.push_back(results.at(i));
                 } else {
                     UniValue result = UniValue(UniValue::VOBJ);
                     result.pushKV("success", UniValue(false));
                     result.pushKV(
                         "error",
                         JSONRPCError(
                             RPC_MISC_ERROR,
                             strprintf("Failed to rescan before time %d, "
                                       "transactions may be missing.",
                                       scannedRange->GetBlockTimeMax())));
                     response.push_back(std::move(result));
                 }
                 ++i;
             }
         }
     }
 
     return response;
 }
 
 // clang-format off
 static const CRPCCommand commands[] = {
     //  category            name                        actor (function)          okSafeMode
     //  ------------------- ------------------------    ----------------------    ----------
     { "wallet",             "dumpprivkey",              dumpprivkey,              true,   {"address"}  },
     { "wallet",             "dumpwallet",               dumpwallet,               true,   {"filename"} },
     { "wallet",             "importmulti",              importmulti,              true,   {"requests","options"} },
     { "wallet",             "importprivkey",            importprivkey,            true,   {"privkey","label","rescan"} },
     { "wallet",             "importwallet",             importwallet,             true,   {"filename"} },
     { "wallet",             "importaddress",            importaddress,            true,   {"address","label","rescan","p2sh"} },
     { "wallet",             "importprunedfunds",        importprunedfunds,        true,   {"rawtransaction","txoutproof"} },
     { "wallet",             "importpubkey",             importpubkey,             true,   {"pubkey","label","rescan"} },
     { "wallet",             "removeprunedfunds",        removeprunedfunds,        true,   {"txid"} },
 };
 // clang-format on
 
 void RegisterDumpRPCCommands(CRPCTable &t) {
     if (GetBoolArg("-disablewallet", false)) return;
 
     for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
         t.appendCommand(commands[vcidx].name, &commands[vcidx]);
 }
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index 5856ee648..c94d8efc8 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -1,3400 +1,3400 @@
 // Copyright (c) 2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #include "amount.h"
 #include "base58.h"
 #include "chain.h"
 #include "chainparams.h" // for GetConsensus.
 #include "config.h"
 #include "consensus/validation.h"
 #include "core_io.h"
 #include "init.h"
 #include "net.h"
 #include "rpc/misc.h"
 #include "rpc/server.h"
 #include "timedata.h"
 #include "util.h"
 #include "utilmoneystr.h"
 #include "validation.h"
 #include "wallet.h"
 #include "walletdb.h"
 
 #include <cstdint>
 
 #include <boost/assign/list_of.hpp>
 
 #include <univalue.h>
 
 int64_t nWalletUnlockTime;
 static CCriticalSection cs_nWalletUnlockTime;
 
 std::string HelpRequiringPassphrase() {
     return pwalletMain && pwalletMain->IsCrypted()
                ? "\nRequires wallet passphrase to be set with walletpassphrase "
                  "call."
                : "";
 }
 
 bool EnsureWalletIsAvailable(bool avoidException) {
     if (pwalletMain) {
         return true;
     }
 
     if (avoidException) {
         return false;
     }
 
     throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
 }
 
 void EnsureWalletIsUnlocked() {
     if (pwalletMain->IsLocked()) {
         throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the "
                                                      "wallet passphrase with "
                                                      "walletpassphrase first.");
     }
 }
 
 void WalletTxToJSON(const CWalletTx &wtx, UniValue &entry) {
     int confirms = wtx.GetDepthInMainChain();
     entry.push_back(Pair("confirmations", confirms));
     if (wtx.IsCoinBase()) {
         entry.push_back(Pair("generated", true));
     }
     if (confirms > 0) {
         entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex()));
         entry.push_back(Pair("blockindex", wtx.nIndex));
         entry.push_back(
             Pair("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime()));
     } else {
         entry.push_back(Pair("trusted", wtx.IsTrusted()));
     }
     uint256 hash = wtx.GetId();
     entry.push_back(Pair("txid", hash.GetHex()));
     UniValue conflicts(UniValue::VARR);
     for (const uint256 &conflict : wtx.GetConflicts()) {
         conflicts.push_back(conflict.GetHex());
     }
     entry.push_back(Pair("walletconflicts", conflicts));
     entry.push_back(Pair("time", wtx.GetTxTime()));
     entry.push_back(Pair("timereceived", (int64_t)wtx.nTimeReceived));
 
     for (const std::pair<std::string, std::string> &item : wtx.mapValue) {
         entry.push_back(Pair(item.first, item.second));
     }
 }
 
 std::string AccountFromValue(const UniValue &value) {
     std::string strAccount = value.get_str();
     if (strAccount == "*") {
         throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME,
                            "Invalid account name");
     }
     return strAccount;
 }
 
 static UniValue getnewaddress(const Config &config,
                               const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() > 1) {
         throw std::runtime_error(
             "getnewaddress ( \"account\" )\n"
             "\nReturns a new Bitcoin address for receiving payments.\n"
             "If 'account' is specified (DEPRECATED), it is added to the "
             "address book \n"
             "so payments received with the address will be credited to "
             "'account'.\n"
             "\nArguments:\n"
             "1. \"account\"        (string, optional) DEPRECATED. The account "
             "name for the address to be linked to. If not provided, the "
             "default account \"\" is used. It can also be set to the empty "
             "string \"\" to represent the default account. The account does "
             "not need to exist, it will be created if there is no account by "
             "the given name.\n"
             "\nResult:\n"
             "\"address\"    (string) The new bitcoin address\n"
             "\nExamples:\n" +
             HelpExampleCli("getnewaddress", "") +
             HelpExampleRpc("getnewaddress", ""));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     // Parse the account first so we don't generate a key if there's an error
     std::string strAccount;
     if (request.params.size() > 0) {
         strAccount = AccountFromValue(request.params[0]);
     }
 
     if (!pwalletMain->IsLocked()) {
         pwalletMain->TopUpKeyPool();
     }
 
     // Generate a new key that is added to wallet
     CPubKey newKey;
     if (!pwalletMain->GetKeyFromPool(newKey)) {
         throw JSONRPCError(
             RPC_WALLET_KEYPOOL_RAN_OUT,
             "Error: Keypool ran out, please call keypoolrefill first");
     }
     CKeyID keyID = newKey.GetID();
 
     pwalletMain->SetAddressBook(keyID, strAccount, "receive");
 
     return CBitcoinAddress(keyID).ToString();
 }
 
 CBitcoinAddress GetAccountAddress(std::string strAccount,
                                   bool bForceNew = false) {
     CPubKey pubKey;
     if (!pwalletMain->GetAccountPubkey(pubKey, strAccount, bForceNew)) {
         throw JSONRPCError(
             RPC_WALLET_KEYPOOL_RAN_OUT,
             "Error: Keypool ran out, please call keypoolrefill first");
     }
 
     return CBitcoinAddress(pubKey.GetID());
 }
 
 static UniValue getaccountaddress(const Config &config,
                                   const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() != 1) {
         throw std::runtime_error(
             "getaccountaddress \"account\"\n"
             "\nDEPRECATED. Returns the current Bitcoin address for receiving "
             "payments to this account.\n"
             "\nArguments:\n"
             "1. \"account\"       (string, required) The account name for the "
             "address. It can also be set to the empty string \"\" to represent "
             "the default account. The account does not need to exist, it will "
             "be created and a new address created  if there is no account by "
             "the given name.\n"
             "\nResult:\n"
             "\"address\"          (string) The account bitcoin address\n"
             "\nExamples:\n" +
             HelpExampleCli("getaccountaddress", "") +
             HelpExampleCli("getaccountaddress", "\"\"") +
             HelpExampleCli("getaccountaddress", "\"myaccount\"") +
             HelpExampleRpc("getaccountaddress", "\"myaccount\""));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     // Parse the account first so we don't generate a key if there's an error
     std::string strAccount = AccountFromValue(request.params[0]);
 
     UniValue ret(UniValue::VSTR);
 
     ret = GetAccountAddress(strAccount).ToString();
     return ret;
 }
 
 static UniValue getrawchangeaddress(const Config &config,
                                     const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() > 1) {
         throw std::runtime_error(
             "getrawchangeaddress\n"
             "\nReturns a new Bitcoin address, for receiving change.\n"
             "This is for use with raw transactions, NOT normal use.\n"
             "\nResult:\n"
             "\"address\"    (string) The address\n"
             "\nExamples:\n" +
             HelpExampleCli("getrawchangeaddress", "") +
             HelpExampleRpc("getrawchangeaddress", ""));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     if (!pwalletMain->IsLocked()) {
         pwalletMain->TopUpKeyPool();
     }
 
     CReserveKey reservekey(pwalletMain);
     CPubKey vchPubKey;
     if (!reservekey.GetReservedKey(vchPubKey)) {
         throw JSONRPCError(
             RPC_WALLET_KEYPOOL_RAN_OUT,
             "Error: Keypool ran out, please call keypoolrefill first");
     }
 
     reservekey.KeepKey();
 
     CKeyID keyID = vchPubKey.GetID();
 
     return CBitcoinAddress(keyID).ToString();
 }
 
 static UniValue setaccount(const Config &config,
                            const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() < 1 ||
         request.params.size() > 2) {
         throw std::runtime_error(
             "setaccount \"address\" \"account\"\n"
             "\nDEPRECATED. Sets the account associated with the given "
             "address.\n"
             "\nArguments:\n"
             "1. \"address\"         (string, required) The bitcoin address to "
             "be associated with an account.\n"
             "2. \"account\"         (string, required) The account to assign "
             "the address to.\n"
             "\nExamples:\n" +
             HelpExampleCli("setaccount",
                            "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"tabby\"") +
             HelpExampleRpc(
                 "setaccount",
                 "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"tabby\""));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     CBitcoinAddress address(request.params[0].get_str());
     if (!address.IsValid()) {
         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                            "Invalid Bitcoin address");
     }
 
     std::string strAccount;
     if (request.params.size() > 1) {
         strAccount = AccountFromValue(request.params[1]);
     }
 
     // Only add the account if the address is yours.
     if (IsMine(*pwalletMain, address.Get())) {
         // Detect when changing the account of an address that is the 'unused
         // current key' of another account:
         if (pwalletMain->mapAddressBook.count(address.Get())) {
             std::string strOldAccount =
                 pwalletMain->mapAddressBook[address.Get()].name;
             if (address == GetAccountAddress(strOldAccount)) {
                 GetAccountAddress(strOldAccount, true);
             }
         }
         pwalletMain->SetAddressBook(address.Get(), strAccount, "receive");
     } else {
         throw JSONRPCError(RPC_MISC_ERROR,
                            "setaccount can only be used with own address");
     }
 
     return NullUniValue;
 }
 
 static UniValue getaccount(const Config &config,
                            const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() != 1) {
         throw std::runtime_error(
             "getaccount \"address\"\n"
             "\nDEPRECATED. Returns the account associated with the given "
             "address.\n"
             "\nArguments:\n"
             "1. \"address\"         (string, required) The bitcoin address for "
             "account lookup.\n"
             "\nResult:\n"
             "\"accountname\"        (string) the account address\n"
             "\nExamples:\n" +
             HelpExampleCli("getaccount",
                            "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"") +
             HelpExampleRpc("getaccount",
                            "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\""));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     CBitcoinAddress address(request.params[0].get_str());
     if (!address.IsValid()) {
         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                            "Invalid Bitcoin address");
     }
 
     std::string strAccount;
     std::map<CTxDestination, CAddressBookData>::iterator mi =
         pwalletMain->mapAddressBook.find(address.Get());
     if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.name.empty()) {
         strAccount = (*mi).second.name;
     }
 
     return strAccount;
 }
 
 static UniValue getaddressesbyaccount(const Config &config,
                                       const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() != 1) {
         throw std::runtime_error(
             "getaddressesbyaccount \"account\"\n"
             "\nDEPRECATED. Returns the list of addresses for the given "
             "account.\n"
             "\nArguments:\n"
             "1. \"account\"        (string, required) The account name.\n"
             "\nResult:\n"
             "[                     (json array of string)\n"
             "  \"address\"         (string) a bitcoin address associated with "
             "the given account\n"
             "  ,...\n"
             "]\n"
             "\nExamples:\n" +
             HelpExampleCli("getaddressesbyaccount", "\"tabby\"") +
             HelpExampleRpc("getaddressesbyaccount", "\"tabby\""));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     std::string strAccount = AccountFromValue(request.params[0]);
 
     // Find all addresses that have the given account
     UniValue ret(UniValue::VARR);
     for (const std::pair<CBitcoinAddress, CAddressBookData> &item :
          pwalletMain->mapAddressBook) {
         const CBitcoinAddress &address = item.first;
         const std::string &strName = item.second.name;
         if (strName == strAccount) ret.push_back(address.ToString());
     }
 
     return ret;
 }
 
 static void SendMoney(const CTxDestination &address, CAmount nValue,
                       bool fSubtractFeeFromAmount, CWalletTx &wtxNew) {
     CAmount curBalance = pwalletMain->GetBalance();
 
     // Check amount
     if (nValue <= 0) {
         throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount");
     }
 
     if (nValue > curBalance) {
         throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds");
     }
 
     if (pwalletMain->GetBroadcastTransactions() && !g_connman) {
         throw JSONRPCError(
             RPC_CLIENT_P2P_DISABLED,
             "Error: Peer-to-peer functionality missing or disabled");
     }
 
     // Parse Bitcoin address
     CScript scriptPubKey = GetScriptForDestination(address);
 
     // Create and send the transaction
     CReserveKey reservekey(pwalletMain);
     CAmount nFeeRequired;
     std::string strError;
     std::vector<CRecipient> vecSend;
     int nChangePosRet = -1;
     CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount};
     vecSend.push_back(recipient);
     if (!pwalletMain->CreateTransaction(vecSend, wtxNew, reservekey,
                                         nFeeRequired, nChangePosRet,
                                         strError)) {
         if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance) {
             strError = strprintf("Error: This transaction requires a "
                                  "transaction fee of at least %s",
                                  FormatMoney(nFeeRequired));
         }
         throw JSONRPCError(RPC_WALLET_ERROR, strError);
     }
     CValidationState state;
     if (!pwalletMain->CommitTransaction(wtxNew, reservekey, g_connman.get(),
                                         state)) {
         strError =
             strprintf("Error: The transaction was rejected! Reason given: %s",
                       state.GetRejectReason());
         throw JSONRPCError(RPC_WALLET_ERROR, strError);
     }
 }
 
 static UniValue sendtoaddress(const Config &config,
                               const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() < 2 ||
         request.params.size() > 5) {
         throw std::runtime_error(
             "sendtoaddress \"address\" amount ( \"comment\" \"comment_to\" "
             "subtractfeefromamount )\n"
             "\nSend an amount to a given address.\n" +
             HelpRequiringPassphrase() + "\nArguments:\n"
                                         "1. \"address\"            (string, "
                                         "required) The bitcoin address to send "
                                         "to.\n"
                                         "2. \"amount\"             (numeric or "
                                         "string, required) The amount in " +
             CURRENCY_UNIT +
             " to send. eg 0.1\n"
             "3. \"comment\"            (string, optional) A comment used to "
             "store what the transaction is for. \n"
             "                             This is not part of the transaction, "
             "just kept in your wallet.\n"
             "4. \"comment_to\"         (string, optional) A comment to store "
             "the name of the person or organization \n"
             "                             to which you're sending the "
             "transaction. This is not part of the \n"
             "                             transaction, just kept in your "
             "wallet.\n"
             "5. subtractfeefromamount  (boolean, optional, default=false) The "
             "fee will be deducted from the amount being sent.\n"
             "                             The recipient will receive less "
             "bitcoins than you enter in the amount field.\n"
             "\nResult:\n"
             "\"txid\"                  (string) The transaction id.\n"
             "\nExamples:\n" +
             HelpExampleCli("sendtoaddress",
                            "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1") +
             HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvay"
                                             "dd\" 0.1 \"donation\" \"seans "
                                             "outpost\"") +
             HelpExampleCli(
                 "sendtoaddress",
                 "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"\" \"\" true") +
             HelpExampleRpc("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvay"
                                             "dd\", 0.1, \"donation\", \"seans "
                                             "outpost\""));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     CBitcoinAddress address(request.params[0].get_str());
     if (!address.IsValid()) {
         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                            "Invalid Bitcoin address");
     }
 
     // Amount
     CAmount nAmount = AmountFromValue(request.params[1]);
     if (nAmount <= 0) {
         throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
     }
 
     // Wallet comments
     CWalletTx wtx;
     if (request.params.size() > 2 && !request.params[2].isNull() &&
         !request.params[2].get_str().empty()) {
         wtx.mapValue["comment"] = request.params[2].get_str();
     }
     if (request.params.size() > 3 && !request.params[3].isNull() &&
         !request.params[3].get_str().empty()) {
         wtx.mapValue["to"] = request.params[3].get_str();
     }
 
     bool fSubtractFeeFromAmount = false;
     if (request.params.size() > 4) {
         fSubtractFeeFromAmount = request.params[4].get_bool();
     }
 
     EnsureWalletIsUnlocked();
 
     SendMoney(address.Get(), nAmount, fSubtractFeeFromAmount, wtx);
 
     return wtx.GetId().GetHex();
 }
 
 static UniValue listaddressgroupings(const Config &config,
                                      const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp) {
         throw std::runtime_error(
             "listaddressgroupings\n"
             "\nLists groups of addresses which have had their common "
             "ownership\n"
             "made public by common use as inputs or as the resulting change\n"
             "in past transactions\n"
             "\nResult:\n"
             "[\n"
             "  [\n"
             "    [\n"
             "      \"address\",            (string) The bitcoin address\n"
             "      amount,                 (numeric) The amount in " +
             CURRENCY_UNIT + "\n"
                             "      \"account\"             (string, optional) "
                             "DEPRECATED. The account\n"
                             "    ]\n"
                             "    ,...\n"
                             "  ]\n"
                             "  ,...\n"
                             "]\n"
                             "\nExamples:\n" +
             HelpExampleCli("listaddressgroupings", "") +
             HelpExampleRpc("listaddressgroupings", ""));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     UniValue jsonGroupings(UniValue::VARR);
     std::map<CTxDestination, CAmount> balances =
         pwalletMain->GetAddressBalances();
     for (std::set<CTxDestination> grouping :
          pwalletMain->GetAddressGroupings()) {
         UniValue jsonGrouping(UniValue::VARR);
         for (CTxDestination address : grouping) {
             UniValue addressInfo(UniValue::VARR);
             addressInfo.push_back(CBitcoinAddress(address).ToString());
             addressInfo.push_back(ValueFromAmount(balances[address]));
 
             if (pwalletMain->mapAddressBook.find(
                     CBitcoinAddress(address).Get()) !=
                 pwalletMain->mapAddressBook.end()) {
                 addressInfo.push_back(pwalletMain->mapAddressBook
                                           .find(CBitcoinAddress(address).Get())
                                           ->second.name);
             }
             jsonGrouping.push_back(addressInfo);
         }
         jsonGroupings.push_back(jsonGrouping);
     }
 
     return jsonGroupings;
 }
 
 static UniValue signmessage(const Config &config,
                             const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() != 2) {
         throw std::runtime_error(
             "signmessage \"address\" \"message\"\n"
             "\nSign a message with the private key of an address" +
             HelpRequiringPassphrase() +
             "\n"
             "\nArguments:\n"
             "1. \"address\"         (string, required) The bitcoin address to "
             "use for the private key.\n"
             "2. \"message\"         (string, required) The message to create a "
             "signature of.\n"
             "\nResult:\n"
             "\"signature\"          (string) The signature of the message "
             "encoded in base 64\n"
             "\nExamples:\n"
             "\nUnlock the wallet for 30 seconds\n" +
             HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
             "\nCreate the signature\n" +
             HelpExampleCli(
                 "signmessage",
                 "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") +
             "\nVerify the signature\n" +
             HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4"
                                             "XX\" \"signature\" \"my "
                                             "message\"") +
             "\nAs json rpc\n" +
             HelpExampleRpc(
                 "signmessage",
                 "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"my message\""));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     EnsureWalletIsUnlocked();
 
     std::string strAddress = request.params[0].get_str();
     std::string strMessage = request.params[1].get_str();
 
     CBitcoinAddress addr(strAddress);
     if (!addr.IsValid()) {
         throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
     }
 
     CKeyID keyID;
     if (!addr.GetKeyID(keyID)) {
         throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
     }
 
     CKey key;
     if (!pwalletMain->GetKey(keyID, key)) {
         throw JSONRPCError(RPC_WALLET_ERROR, "Private key not available");
     }
 
     CHashWriter ss(SER_GETHASH, 0);
     ss << strMessageMagic;
     ss << strMessage;
 
-    std::vector<unsigned char> vchSig;
+    std::vector<uint8_t> vchSig;
     if (!key.SignCompact(ss.GetHash(), vchSig)) {
         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed");
     }
 
     return EncodeBase64(&vchSig[0], vchSig.size());
 }
 
 static UniValue getreceivedbyaddress(const Config &config,
                                      const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() < 1 ||
         request.params.size() > 2) {
         throw std::runtime_error(
             "getreceivedbyaddress \"address\" ( minconf )\n"
             "\nReturns the total amount received by the given address in "
             "transactions with at least minconf confirmations.\n"
             "\nArguments:\n"
             "1. \"address\"         (string, required) The bitcoin address for "
             "transactions.\n"
             "2. minconf             (numeric, optional, default=1) Only "
             "include transactions confirmed at least this many times.\n"
             "\nResult:\n"
             "amount   (numeric) The total amount in " +
             CURRENCY_UNIT +
             " received at this address.\n"
             "\nExamples:\n"
             "\nThe amount from transactions with at least 1 confirmation\n" +
             HelpExampleCli("getreceivedbyaddress",
                            "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"") +
             "\nThe amount including unconfirmed transactions, zero "
             "confirmations\n" +
             HelpExampleCli("getreceivedbyaddress",
                            "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" 0") +
             "\nThe amount with at least 6 confirmation, very safe\n" +
             HelpExampleCli("getreceivedbyaddress",
                            "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" 6") +
             "\nAs a json rpc call\n" +
             HelpExampleRpc("getreceivedbyaddress",
                            "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", 6"));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     // Bitcoin address
     CBitcoinAddress address = CBitcoinAddress(request.params[0].get_str());
     if (!address.IsValid()) {
         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                            "Invalid Bitcoin address");
     }
 
     CScript scriptPubKey = GetScriptForDestination(address.Get());
     if (!IsMine(*pwalletMain, scriptPubKey)) {
         return ValueFromAmount(0);
     }
 
     // Minimum confirmations
     int nMinDepth = 1;
     if (request.params.size() > 1) {
         nMinDepth = request.params[1].get_int();
     }
 
     // Tally
     CAmount nAmount = 0;
     for (std::map<uint256, CWalletTx>::iterator it =
              pwalletMain->mapWallet.begin();
          it != pwalletMain->mapWallet.end(); ++it) {
         const CWalletTx &wtx = (*it).second;
 
         CValidationState state;
         if (wtx.IsCoinBase() ||
             !ContextualCheckTransactionForCurrentBlock(
                 config, *wtx.tx, state,
                 config.GetChainParams().GetConsensus())) {
             continue;
         }
 
         for (const CTxOut &txout : wtx.tx->vout) {
             if (txout.scriptPubKey == scriptPubKey) {
                 if (wtx.GetDepthInMainChain() >= nMinDepth) {
                     nAmount += txout.nValue;
                 }
             }
         }
     }
 
     return ValueFromAmount(nAmount);
 }
 
 static UniValue getreceivedbyaccount(const Config &config,
                                      const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() < 1 ||
         request.params.size() > 2) {
         throw std::runtime_error(
             "getreceivedbyaccount \"account\" ( minconf )\n"
             "\nDEPRECATED. Returns the total amount received by addresses with "
             "<account> in transactions with at least [minconf] confirmations.\n"
             "\nArguments:\n"
             "1. \"account\"      (string, required) The selected account, may "
             "be the default account using \"\".\n"
             "2. minconf          (numeric, optional, default=1) Only include "
             "transactions confirmed at least this many times.\n"
             "\nResult:\n"
             "amount              (numeric) The total amount in " +
             CURRENCY_UNIT + " received for this account.\n"
                             "\nExamples:\n"
                             "\nAmount received by the default account with at "
                             "least 1 confirmation\n" +
             HelpExampleCli("getreceivedbyaccount", "\"\"") +
             "\nAmount received at the tabby account including unconfirmed "
             "amounts with zero confirmations\n" +
             HelpExampleCli("getreceivedbyaccount", "\"tabby\" 0") +
             "\nThe amount with at least 6 confirmation, very safe\n" +
             HelpExampleCli("getreceivedbyaccount", "\"tabby\" 6") +
             "\nAs a json rpc call\n" +
             HelpExampleRpc("getreceivedbyaccount", "\"tabby\", 6"));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     // Minimum confirmations
     int nMinDepth = 1;
     if (request.params.size() > 1) {
         nMinDepth = request.params[1].get_int();
     }
 
     // Get the set of pub keys assigned to account
     std::string strAccount = AccountFromValue(request.params[0]);
     std::set<CTxDestination> setAddress =
         pwalletMain->GetAccountAddresses(strAccount);
 
     // Tally
     CAmount nAmount = 0;
     for (std::map<uint256, CWalletTx>::iterator it =
              pwalletMain->mapWallet.begin();
          it != pwalletMain->mapWallet.end(); ++it) {
         const CWalletTx &wtx = (*it).second;
         CValidationState state;
         if (wtx.IsCoinBase() ||
             !ContextualCheckTransactionForCurrentBlock(
                 config, *wtx.tx, state,
                 config.GetChainParams().GetConsensus())) {
             continue;
         }
 
         for (const CTxOut &txout : wtx.tx->vout) {
             CTxDestination address;
             if (ExtractDestination(txout.scriptPubKey, address) &&
                 IsMine(*pwalletMain, address) && setAddress.count(address)) {
                 if (wtx.GetDepthInMainChain() >= nMinDepth) {
                     nAmount += txout.nValue;
                 }
             }
         }
     }
 
     return ValueFromAmount(nAmount);
 }
 
 static UniValue getbalance(const Config &config,
                            const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() > 3) {
         throw std::runtime_error(
             "getbalance ( \"account\" minconf include_watchonly )\n"
             "\nIf account is not specified, returns the server's total "
             "available balance.\n"
             "If account is specified (DEPRECATED), returns the balance in the "
             "account.\n"
             "Note that the account \"\" is not the same as leaving the "
             "parameter out.\n"
             "The server total may be different to the balance in the default "
             "\"\" account.\n"
             "\nArguments:\n"
             "1. \"account\"         (string, optional) DEPRECATED. The account "
             "string may be given as a\n"
             "                     specific account name to find the balance "
             "associated with wallet keys in\n"
             "                     a named account, or as the empty string "
             "(\"\") to find the balance\n"
             "                     associated with wallet keys not in any named "
             "account, or as \"*\" to find\n"
             "                     the balance associated with all wallet keys "
             "regardless of account.\n"
             "                     When this option is specified, it calculates "
             "the balance in a different\n"
             "                     way than when it is not specified, and which "
             "can count spends twice when\n"
             "                     there are conflicting pending transactions "
             "temporarily resulting in low\n"
             "                     or even negative balances.\n"
             "                     In general, account balance calculation is "
             "not considered reliable and\n"
             "                     has resulted in confusing outcomes, so it is "
             "recommended to avoid passing\n"
             "                     this argument.\n"
             "2. minconf           (numeric, optional, default=1) Only include "
             "transactions confirmed at least this many times.\n"
             "3. include_watchonly (bool, optional, default=false) Also include "
             "balance in watch-only addresses (see 'importaddress')\n"
             "\nResult:\n"
             "amount              (numeric) The total amount in " +
             CURRENCY_UNIT + " received for this account.\n"
                             "\nExamples:\n"
                             "\nThe total amount in the wallet\n" +
             HelpExampleCli("getbalance", "") +
             "\nThe total amount in the wallet at least 5 blocks confirmed\n" +
             HelpExampleCli("getbalance", "\"*\" 6") + "\nAs a json rpc call\n" +
             HelpExampleRpc("getbalance", "\"*\", 6"));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     if (request.params.size() == 0) {
         return ValueFromAmount(pwalletMain->GetBalance());
     }
 
     int nMinDepth = 1;
     if (request.params.size() > 1) {
         nMinDepth = request.params[1].get_int();
     }
 
     isminefilter filter = ISMINE_SPENDABLE;
     if (request.params.size() > 2 && request.params[2].get_bool()) {
         filter = filter | ISMINE_WATCH_ONLY;
     }
 
     if (request.params[0].get_str() == "*") {
         // Calculate total balance in a very different way from GetBalance().
         // The biggest difference is that GetBalance() sums up all unspent
         // TxOuts paying to the wallet, while this sums up both spent and
         // unspent TxOuts paying to the wallet, and then subtracts the values of
         // TxIns spending from the wallet. This also has fewer restrictions on
         // which unconfirmed transactions are considered trusted.
         CAmount nBalance = 0;
         for (std::map<uint256, CWalletTx>::iterator it =
                  pwalletMain->mapWallet.begin();
              it != pwalletMain->mapWallet.end(); ++it) {
             const CWalletTx &wtx = (*it).second;
             CValidationState state;
             if (!ContextualCheckTransactionForCurrentBlock(
                     config, wtx, state,
                     config.GetChainParams().GetConsensus()) ||
                 wtx.GetBlocksToMaturity() > 0 ||
                 wtx.GetDepthInMainChain() < 0) {
                 continue;
             }
 
             CAmount allFee;
             std::string strSentAccount;
             std::list<COutputEntry> listReceived;
             std::list<COutputEntry> listSent;
             wtx.GetAmounts(listReceived, listSent, allFee, strSentAccount,
                            filter);
             if (wtx.GetDepthInMainChain() >= nMinDepth) {
                 for (const COutputEntry &r : listReceived) {
                     nBalance += r.amount;
                 }
             }
             for (const COutputEntry &s : listSent) {
                 nBalance -= s.amount;
             }
             nBalance -= allFee;
         }
         return ValueFromAmount(nBalance);
     }
 
     std::string strAccount = AccountFromValue(request.params[0]);
 
     CAmount nBalance =
         pwalletMain->GetAccountBalance(strAccount, nMinDepth, filter);
 
     return ValueFromAmount(nBalance);
 }
 
 static UniValue getunconfirmedbalance(const Config &config,
                                       const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() > 0) {
         throw std::runtime_error(
             "getunconfirmedbalance\n"
             "Returns the server's total unconfirmed balance\n");
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     return ValueFromAmount(pwalletMain->GetUnconfirmedBalance());
 }
 
 static UniValue movecmd(const Config &config, const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() < 3 ||
         request.params.size() > 5) {
         throw std::runtime_error(
             "move \"fromaccount\" \"toaccount\" amount ( minconf \"comment\" "
             ")\n"
             "\nDEPRECATED. Move a specified amount from one account in your "
             "wallet to another.\n"
             "\nArguments:\n"
             "1. \"fromaccount\"   (string, required) The name of the account "
             "to move funds from. May be the default account using \"\".\n"
             "2. \"toaccount\"     (string, required) The name of the account "
             "to move funds to. May be the default account using \"\".\n"
             "3. amount            (numeric) Quantity of " +
             CURRENCY_UNIT +
             " to move between accounts.\n"
             "4. (dummy)           (numeric, optional) Ignored. Remains for "
             "backward compatibility.\n"
             "5. \"comment\"       (string, optional) An optional comment, "
             "stored in the wallet only.\n"
             "\nResult:\n"
             "true|false           (boolean) true if successful.\n"
             "\nExamples:\n"
             "\nMove 0.01 " +
             CURRENCY_UNIT +
             " from the default account to the account named tabby\n" +
             HelpExampleCli("move", "\"\" \"tabby\" 0.01") + "\nMove 0.01 " +
             CURRENCY_UNIT + " timotei to akiko with a comment and funds have 6 "
                             "confirmations\n" +
             HelpExampleCli("move",
                            "\"timotei\" \"akiko\" 0.01 6 \"happy birthday!\"") +
             "\nAs a json rpc call\n" +
             HelpExampleRpc(
                 "move",
                 "\"timotei\", \"akiko\", 0.01, 6, \"happy birthday!\""));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     std::string strFrom = AccountFromValue(request.params[0]);
     std::string strTo = AccountFromValue(request.params[1]);
     CAmount nAmount = AmountFromValue(request.params[2]);
     if (nAmount <= 0) {
         throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
     }
     if (request.params.size() > 3) {
         // Unused parameter, used to be nMinDepth, keep type-checking it though
         (void)request.params[3].get_int();
     }
 
     std::string strComment;
     if (request.params.size() > 4) {
         strComment = request.params[4].get_str();
     }
     if (!pwalletMain->AccountMove(strFrom, strTo, nAmount, strComment)) {
         throw JSONRPCError(RPC_DATABASE_ERROR, "database error");
     }
 
     return true;
 }
 
 static UniValue sendfrom(const Config &config, const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() < 3 ||
         request.params.size() > 6) {
         throw std::runtime_error(
             "sendfrom \"fromaccount\" \"toaddress\" amount ( minconf "
             "\"comment\" \"comment_to\" )\n"
             "\nDEPRECATED (use sendtoaddress). Sent an amount from an account "
             "to a bitcoin address." +
             HelpRequiringPassphrase() +
             "\n"
             "\nArguments:\n"
             "1. \"fromaccount\"       (string, required) The name of the "
             "account to send funds from. May be the default account using "
             "\"\".\n"
             "                       Specifying an account does not influence "
             "coin selection, but it does associate the newly created\n"
             "                       transaction with the account, so the "
             "account's balance computation and transaction history can "
             "reflect\n"
             "                       the spend.\n"
             "2. \"toaddress\"         (string, required) The bitcoin address "
             "to send funds to.\n"
             "3. amount                (numeric or string, required) The amount "
             "in " +
             CURRENCY_UNIT +
             " (transaction fee is added on top).\n"
             "4. minconf               (numeric, optional, default=1) Only use "
             "funds with at least this many confirmations.\n"
             "5. \"comment\"           (string, optional) A comment used to "
             "store what the transaction is for. \n"
             "                                     This is not part of the "
             "transaction, just kept in your wallet.\n"
             "6. \"comment_to\"        (string, optional) An optional comment "
             "to store the name of the person or organization \n"
             "                                     to which you're sending the "
             "transaction. This is not part of the transaction, \n"
             "                                     it is just kept in your "
             "wallet.\n"
             "\nResult:\n"
             "\"txid\"                 (string) The transaction id.\n"
             "\nExamples:\n"
             "\nSend 0.01 " +
             CURRENCY_UNIT + " from the default account to the address, must "
                             "have at least 1 confirmation\n" +
             HelpExampleCli("sendfrom",
                            "\"\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01") +
             "\nSend 0.01 from the tabby account to the given address, funds "
             "must have at least 6 confirmations\n" +
             HelpExampleCli("sendfrom",
                            "\"tabby\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" "
                            "0.01 6 \"donation\" \"seans outpost\"") +
             "\nAs a json rpc call\n" +
             HelpExampleRpc("sendfrom",
                            "\"tabby\", \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", "
                            "0.01, 6, \"donation\", \"seans outpost\""));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     std::string strAccount = AccountFromValue(request.params[0]);
     CBitcoinAddress address(request.params[1].get_str());
     if (!address.IsValid()) {
         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                            "Invalid Bitcoin address");
     }
 
     CAmount nAmount = AmountFromValue(request.params[2]);
     if (nAmount <= 0) {
         throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
     }
 
     int nMinDepth = 1;
     if (request.params.size() > 3) {
         nMinDepth = request.params[3].get_int();
     }
 
     CWalletTx wtx;
     wtx.strFromAccount = strAccount;
     if (request.params.size() > 4 && !request.params[4].isNull() &&
         !request.params[4].get_str().empty()) {
         wtx.mapValue["comment"] = request.params[4].get_str();
     }
 
     if (request.params.size() > 5 && !request.params[5].isNull() &&
         !request.params[5].get_str().empty()) {
         wtx.mapValue["to"] = request.params[5].get_str();
     }
 
     EnsureWalletIsUnlocked();
 
     // Check funds
     CAmount nBalance =
         pwalletMain->GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE);
     if (nAmount > nBalance) {
         throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS,
                            "Account has insufficient funds");
     }
 
     SendMoney(address.Get(), nAmount, false, wtx);
 
     return wtx.GetId().GetHex();
 }
 
 static UniValue sendmany(const Config &config, const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() < 2 ||
         request.params.size() > 5) {
         throw std::runtime_error(
             "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf "
             "\"comment\" [\"address\",...] )\n"
             "\nSend multiple times. Amounts are double-precision floating "
             "point numbers." +
             HelpRequiringPassphrase() +
             "\n"
             "\nArguments:\n"
             "1. \"fromaccount\"         (string, required) DEPRECATED. The "
             "account to send the funds from. Should be \"\" for the default "
             "account\n"
             "2. \"amounts\"             (string, required) A json object with "
             "addresses and amounts\n"
             "    {\n"
             "      \"address\":amount   (numeric or string) The bitcoin "
             "address is the key, the numeric amount (can be string) in " +
             CURRENCY_UNIT +
             " is the value\n"
             "      ,...\n"
             "    }\n"
             "3. minconf                 (numeric, optional, default=1) Only "
             "use the balance confirmed at least this many times.\n"
             "4. \"comment\"             (string, optional) A comment\n"
             "5. subtractfeefrom         (array, optional) A json array with "
             "addresses.\n"
             "                           The fee will be equally deducted from "
             "the amount of each selected address.\n"
             "                           Those recipients will receive less "
             "bitcoins than you enter in their corresponding amount field.\n"
             "                           If no addresses are specified here, "
             "the sender pays the fee.\n"
             "    [\n"
             "      \"address\"          (string) Subtract fee from this "
             "address\n"
             "      ,...\n"
             "    ]\n"
             "\nResult:\n"
             "\"txid\"                   (string) The transaction id for the "
             "send. Only 1 transaction is created regardless of \n"
             "                                    the number of addresses.\n"
             "\nExamples:\n"
             "\nSend two amounts to two different addresses:\n" +
             HelpExampleCli("sendmany",
                            "\"\" "
                            "\"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,"
                            "\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}"
                            "\"") +
             "\nSend two amounts to two different addresses setting the "
             "confirmation and comment:\n" +
             HelpExampleCli("sendmany",
                            "\"\" "
                            "\"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,"
                            "\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" "
                            "6 \"testing\"") +
             "\nSend two amounts to two different addresses, subtract fee from "
             "amount:\n" +
             HelpExampleCli("sendmany",
                            "\"\" "
                            "\"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,"
                            "\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" "
                            "1 \"\" "
                            "\"[\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\","
                            "\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\"]\"") +
             "\nAs a json rpc call\n" +
             HelpExampleRpc("sendmany",
                            "\"\", "
                            "\"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,"
                            "\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\","
                            " 6, \"testing\""));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     if (pwalletMain->GetBroadcastTransactions() && !g_connman) {
         throw JSONRPCError(
             RPC_CLIENT_P2P_DISABLED,
             "Error: Peer-to-peer functionality missing or disabled");
     }
 
     std::string strAccount = AccountFromValue(request.params[0]);
     UniValue sendTo = request.params[1].get_obj();
     int nMinDepth = 1;
     if (request.params.size() > 2) {
         nMinDepth = request.params[2].get_int();
     }
 
     CWalletTx wtx;
     wtx.strFromAccount = strAccount;
     if (request.params.size() > 3 && !request.params[3].isNull() &&
         !request.params[3].get_str().empty()) {
         wtx.mapValue["comment"] = request.params[3].get_str();
     }
 
     UniValue subtractFeeFromAmount(UniValue::VARR);
     if (request.params.size() > 4) {
         subtractFeeFromAmount = request.params[4].get_array();
     }
 
     std::set<CBitcoinAddress> setAddress;
     std::vector<CRecipient> vecSend;
 
     CAmount totalAmount = 0;
     std::vector<std::string> keys = sendTo.getKeys();
     for (const std::string &name_ : keys) {
         CBitcoinAddress address(name_);
         if (!address.IsValid()) {
             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                                std::string("Invalid Bitcoin address: ") +
                                    name_);
         }
 
         if (setAddress.count(address)) {
             throw JSONRPCError(
                 RPC_INVALID_PARAMETER,
                 std::string("Invalid parameter, duplicated address: ") + name_);
         }
         setAddress.insert(address);
 
         CScript scriptPubKey = GetScriptForDestination(address.Get());
         CAmount nAmount = AmountFromValue(sendTo[name_]);
         if (nAmount <= 0) {
             throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
         }
         totalAmount += nAmount;
 
         bool fSubtractFeeFromAmount = false;
         for (unsigned int idx = 0; idx < subtractFeeFromAmount.size(); idx++) {
             const UniValue &addr = subtractFeeFromAmount[idx];
             if (addr.get_str() == name_) {
                 fSubtractFeeFromAmount = true;
             }
         }
 
         CRecipient recipient = {scriptPubKey, nAmount, fSubtractFeeFromAmount};
         vecSend.push_back(recipient);
     }
 
     EnsureWalletIsUnlocked();
 
     // Check funds
     CAmount nBalance =
         pwalletMain->GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE);
     if (totalAmount > nBalance) {
         throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS,
                            "Account has insufficient funds");
     }
 
     // Send
     CReserveKey keyChange(pwalletMain);
     CAmount nFeeRequired = 0;
     int nChangePosRet = -1;
     std::string strFailReason;
     bool fCreated = pwalletMain->CreateTransaction(
         vecSend, wtx, keyChange, nFeeRequired, nChangePosRet, strFailReason);
     if (!fCreated) {
         throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
     }
     CValidationState state;
     if (!pwalletMain->CommitTransaction(wtx, keyChange, g_connman.get(),
                                         state)) {
         strFailReason = strprintf("Transaction commit failed:: %s",
                                   state.GetRejectReason());
         throw JSONRPCError(RPC_WALLET_ERROR, strFailReason);
     }
 
     return wtx.GetId().GetHex();
 }
 
 static UniValue addmultisigaddress(const Config &config,
                                    const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() < 2 ||
         request.params.size() > 3) {
         std::string msg =
             "addmultisigaddress nrequired [\"key\",...] ( \"account\" )\n"
             "\nAdd a nrequired-to-sign multisignature address to the wallet.\n"
             "Each key is a Bitcoin address or hex-encoded public key.\n"
             "If 'account' is specified (DEPRECATED), assign address to that "
             "account.\n"
 
             "\nArguments:\n"
             "1. nrequired        (numeric, required) The number of required "
             "signatures out of the n keys or addresses.\n"
             "2. \"keys\"         (string, required) A json array of bitcoin "
             "addresses or hex-encoded public keys\n"
             "     [\n"
             "       \"address\"  (string) bitcoin address or hex-encoded "
             "public key\n"
             "       ...,\n"
             "     ]\n"
             "3. \"account\"      (string, optional) DEPRECATED. An account to "
             "assign the addresses to.\n"
 
             "\nResult:\n"
             "\"address\"         (string) A bitcoin address associated with "
             "the keys.\n"
 
             "\nExamples:\n"
             "\nAdd a multisig address from 2 addresses\n" +
             HelpExampleCli("addmultisigaddress",
                            "2 "
                            "\"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\","
                            "\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") +
             "\nAs json rpc call\n" +
             HelpExampleRpc("addmultisigaddress",
                            "2, "
                            "\"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\","
                            "\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"");
         throw std::runtime_error(msg);
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     std::string strAccount;
     if (request.params.size() > 2) {
         strAccount = AccountFromValue(request.params[2]);
     }
 
     // Construct using pay-to-script-hash:
     CScript inner = createmultisig_redeemScript(request.params);
     CScriptID innerID(inner);
     pwalletMain->AddCScript(inner);
 
     pwalletMain->SetAddressBook(innerID, strAccount, "send");
     return CBitcoinAddress(innerID).ToString();
 }
 
 struct tallyitem {
     CAmount nAmount;
     int nConf;
     std::vector<uint256> txids;
     bool fIsWatchonly;
     tallyitem() {
         nAmount = 0;
         nConf = std::numeric_limits<int>::max();
         fIsWatchonly = false;
     }
 };
 
 static UniValue ListReceived(const Config &config, const UniValue &params,
                              bool fByAccounts) {
     // Minimum confirmations
     int nMinDepth = 1;
     if (params.size() > 0) {
         nMinDepth = params[0].get_int();
     }
 
     // Whether to include empty accounts
     bool fIncludeEmpty = false;
     if (params.size() > 1) {
         fIncludeEmpty = params[1].get_bool();
     }
 
     isminefilter filter = ISMINE_SPENDABLE;
     if (params.size() > 2 && params[2].get_bool())
         filter = filter | ISMINE_WATCH_ONLY;
 
     // Tally
     std::map<CBitcoinAddress, tallyitem> mapTally;
     for (std::map<uint256, CWalletTx>::iterator it =
              pwalletMain->mapWallet.begin();
          it != pwalletMain->mapWallet.end(); ++it) {
         const CWalletTx &wtx = (*it).second;
 
         CValidationState state;
         if (wtx.IsCoinBase() ||
             !ContextualCheckTransactionForCurrentBlock(
                 config, *wtx.tx, state,
                 config.GetChainParams().GetConsensus())) {
             continue;
         }
 
         int nDepth = wtx.GetDepthInMainChain();
         if (nDepth < nMinDepth) {
             continue;
         }
 
         for (const CTxOut &txout : wtx.tx->vout) {
             CTxDestination address;
             if (!ExtractDestination(txout.scriptPubKey, address)) {
                 continue;
             }
 
             isminefilter mine = IsMine(*pwalletMain, address);
             if (!(mine & filter)) {
                 continue;
             }
 
             tallyitem &item = mapTally[address];
             item.nAmount += txout.nValue;
             item.nConf = std::min(item.nConf, nDepth);
             item.txids.push_back(wtx.GetId());
             if (mine & ISMINE_WATCH_ONLY) {
                 item.fIsWatchonly = true;
             }
         }
     }
 
     // Reply
     UniValue ret(UniValue::VARR);
     std::map<std::string, tallyitem> mapAccountTally;
     for (const std::pair<CBitcoinAddress, CAddressBookData> &item :
          pwalletMain->mapAddressBook) {
         const CBitcoinAddress &address = item.first;
         const std::string &strAccount = item.second.name;
         std::map<CBitcoinAddress, tallyitem>::iterator it =
             mapTally.find(address);
         if (it == mapTally.end() && !fIncludeEmpty) {
             continue;
         }
 
         CAmount nAmount = 0;
         int nConf = std::numeric_limits<int>::max();
         bool fIsWatchonly = false;
         if (it != mapTally.end()) {
             nAmount = (*it).second.nAmount;
             nConf = (*it).second.nConf;
             fIsWatchonly = (*it).second.fIsWatchonly;
         }
 
         if (fByAccounts) {
             tallyitem &_item = mapAccountTally[strAccount];
             _item.nAmount += nAmount;
             _item.nConf = std::min(_item.nConf, nConf);
             _item.fIsWatchonly = fIsWatchonly;
         } else {
             UniValue obj(UniValue::VOBJ);
             if (fIsWatchonly) {
                 obj.push_back(Pair("involvesWatchonly", true));
             }
             obj.push_back(Pair("address", address.ToString()));
             obj.push_back(Pair("account", strAccount));
             obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
             obj.push_back(
                 Pair("confirmations",
                      (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
             if (!fByAccounts) {
                 obj.push_back(Pair("label", strAccount));
             }
             UniValue transactions(UniValue::VARR);
             if (it != mapTally.end()) {
                 for (const uint256 &_item : (*it).second.txids) {
                     transactions.push_back(_item.GetHex());
                 }
             }
             obj.push_back(Pair("txids", transactions));
             ret.push_back(obj);
         }
     }
 
     if (fByAccounts) {
         for (std::map<std::string, tallyitem>::iterator it =
                  mapAccountTally.begin();
              it != mapAccountTally.end(); ++it) {
             CAmount nAmount = (*it).second.nAmount;
             int nConf = (*it).second.nConf;
             UniValue obj(UniValue::VOBJ);
             if ((*it).second.fIsWatchonly) {
                 obj.push_back(Pair("involvesWatchonly", true));
             }
             obj.push_back(Pair("account", (*it).first));
             obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
             obj.push_back(
                 Pair("confirmations",
                      (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
             ret.push_back(obj);
         }
     }
 
     return ret;
 }
 
 static UniValue listreceivedbyaddress(const Config &config,
                                       const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() > 3) {
         throw std::runtime_error(
             "listreceivedbyaddress ( minconf include_empty include_watchonly)\n"
             "\nList balances by receiving address.\n"
             "\nArguments:\n"
             "1. minconf           (numeric, optional, default=1) The minimum "
             "number of confirmations before payments are included.\n"
             "2. include_empty     (bool, optional, default=false) Whether to "
             "include addresses that haven't received any payments.\n"
             "3. include_watchonly (bool, optional, default=false) Whether to "
             "include watch-only addresses (see 'importaddress').\n"
 
             "\nResult:\n"
             "[\n"
             "  {\n"
             "    \"involvesWatchonly\" : true,        (bool) Only returned if "
             "imported addresses were involved in transaction\n"
             "    \"address\" : \"receivingaddress\",  (string) The receiving "
             "address\n"
             "    \"account\" : \"accountname\",       (string) DEPRECATED. The "
             "account of the receiving address. The default account is \"\".\n"
             "    \"amount\" : x.xxx,                  (numeric) The total "
             "amount in " +
             CURRENCY_UNIT +
             " received by the address\n"
             "    \"confirmations\" : n,               (numeric) The number of "
             "confirmations of the most recent transaction included\n"
             "    \"label\" : \"label\",               (string) A comment for "
             "the address/transaction, if any\n"
             "    \"txids\": [\n"
             "       n,                                (numeric) The ids of "
             "transactions received with the address \n"
             "       ...\n"
             "    ]\n"
             "  }\n"
             "  ,...\n"
             "]\n"
 
             "\nExamples:\n" +
             HelpExampleCli("listreceivedbyaddress", "") +
             HelpExampleCli("listreceivedbyaddress", "6 true") +
             HelpExampleRpc("listreceivedbyaddress", "6, true, true"));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     return ListReceived(config, request.params, false);
 }
 
 static UniValue listreceivedbyaccount(const Config &config,
                                       const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() > 3) {
         throw std::runtime_error(
             "listreceivedbyaccount ( minconf include_empty include_watchonly)\n"
             "\nDEPRECATED. List balances by account.\n"
             "\nArguments:\n"
             "1. minconf           (numeric, optional, default=1) The minimum "
             "number of confirmations before payments are included.\n"
             "2. include_empty     (bool, optional, default=false) Whether to "
             "include accounts that haven't received any payments.\n"
             "3. include_watchonly (bool, optional, default=false) Whether to "
             "include watch-only addresses (see 'importaddress').\n"
 
             "\nResult:\n"
             "[\n"
             "  {\n"
             "    \"involvesWatchonly\" : true,   (bool) Only returned if "
             "imported addresses were involved in transaction\n"
             "    \"account\" : \"accountname\",  (string) The account name of "
             "the receiving account\n"
             "    \"amount\" : x.xxx,             (numeric) The total amount "
             "received by addresses with this account\n"
             "    \"confirmations\" : n,          (numeric) The number of "
             "confirmations of the most recent transaction included\n"
             "    \"label\" : \"label\"           (string) A comment for the "
             "address/transaction, if any\n"
             "  }\n"
             "  ,...\n"
             "]\n"
 
             "\nExamples:\n" +
             HelpExampleCli("listreceivedbyaccount", "") +
             HelpExampleCli("listreceivedbyaccount", "6 true") +
             HelpExampleRpc("listreceivedbyaccount", "6, true, true"));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     return ListReceived(config, request.params, true);
 }
 
 static void MaybePushAddress(UniValue &entry, const CTxDestination &dest) {
     CBitcoinAddress addr;
     if (addr.Set(dest)) {
         entry.push_back(Pair("address", addr.ToString()));
     }
 }
 
 void ListTransactions(const CWalletTx &wtx, const std::string &strAccount,
                       int nMinDepth, bool fLong, UniValue &ret,
                       const isminefilter &filter) {
     CAmount nFee;
     std::string strSentAccount;
     std::list<COutputEntry> listReceived;
     std::list<COutputEntry> listSent;
 
     wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount, filter);
 
     bool fAllAccounts = (strAccount == std::string("*"));
     bool involvesWatchonly = wtx.IsFromMe(ISMINE_WATCH_ONLY);
 
     // Sent
     if ((!listSent.empty() || nFee != 0) &&
         (fAllAccounts || strAccount == strSentAccount)) {
         for (const COutputEntry &s : listSent) {
             UniValue entry(UniValue::VOBJ);
             if (involvesWatchonly ||
                 (::IsMine(*pwalletMain, s.destination) & ISMINE_WATCH_ONLY)) {
                 entry.push_back(Pair("involvesWatchonly", true));
             }
             entry.push_back(Pair("account", strSentAccount));
             MaybePushAddress(entry, s.destination);
             entry.push_back(Pair("category", "send"));
             entry.push_back(Pair("amount", ValueFromAmount(-s.amount)));
             if (pwalletMain->mapAddressBook.count(s.destination)) {
                 entry.push_back(Pair(
                     "label", pwalletMain->mapAddressBook[s.destination].name));
             }
             entry.push_back(Pair("vout", s.vout));
             entry.push_back(Pair("fee", ValueFromAmount(-nFee)));
             if (fLong) {
                 WalletTxToJSON(wtx, entry);
             }
             entry.push_back(Pair("abandoned", wtx.isAbandoned()));
             ret.push_back(entry);
         }
     }
 
     // Received
     if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth) {
         for (const COutputEntry &r : listReceived) {
             std::string account;
             if (pwalletMain->mapAddressBook.count(r.destination)) {
                 account = pwalletMain->mapAddressBook[r.destination].name;
             }
             if (fAllAccounts || (account == strAccount)) {
                 UniValue entry(UniValue::VOBJ);
                 if (involvesWatchonly ||
                     (::IsMine(*pwalletMain, r.destination) &
                      ISMINE_WATCH_ONLY)) {
                     entry.push_back(Pair("involvesWatchonly", true));
                 }
                 entry.push_back(Pair("account", account));
                 MaybePushAddress(entry, r.destination);
                 if (wtx.IsCoinBase()) {
                     if (wtx.GetDepthInMainChain() < 1) {
                         entry.push_back(Pair("category", "orphan"));
                     } else if (wtx.GetBlocksToMaturity() > 0) {
                         entry.push_back(Pair("category", "immature"));
                     } else {
                         entry.push_back(Pair("category", "generate"));
                     }
                 } else {
                     entry.push_back(Pair("category", "receive"));
                 }
                 entry.push_back(Pair("amount", ValueFromAmount(r.amount)));
                 if (pwalletMain->mapAddressBook.count(r.destination)) {
                     entry.push_back(Pair("label", account));
                 }
                 entry.push_back(Pair("vout", r.vout));
                 if (fLong) {
                     WalletTxToJSON(wtx, entry);
                 }
                 ret.push_back(entry);
             }
         }
     }
 }
 
 void AcentryToJSON(const CAccountingEntry &acentry,
                    const std::string &strAccount, UniValue &ret) {
     bool fAllAccounts = (strAccount == std::string("*"));
 
     if (fAllAccounts || acentry.strAccount == strAccount) {
         UniValue entry(UniValue::VOBJ);
         entry.push_back(Pair("account", acentry.strAccount));
         entry.push_back(Pair("category", "move"));
         entry.push_back(Pair("time", acentry.nTime));
         entry.push_back(Pair("amount", ValueFromAmount(acentry.nCreditDebit)));
         entry.push_back(Pair("otheraccount", acentry.strOtherAccount));
         entry.push_back(Pair("comment", acentry.strComment));
         ret.push_back(entry);
     }
 }
 
 static UniValue listtransactions(const Config &config,
                                  const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() > 4) {
         throw std::runtime_error(
             "listtransactions ( \"account\" count skip include_watchonly)\n"
             "\nReturns up to 'count' most recent transactions skipping the "
             "first 'from' transactions for account 'account'.\n"
             "\nArguments:\n"
             "1. \"account\"    (string, optional) DEPRECATED. The account "
             "name. Should be \"*\".\n"
             "2. count          (numeric, optional, default=10) The number of "
             "transactions to return\n"
             "3. skip           (numeric, optional, default=0) The number of "
             "transactions to skip\n"
             "4. include_watchonly (bool, optional, default=false) Include "
             "transactions to watch-only addresses (see 'importaddress')\n"
             "\nResult:\n"
             "[\n"
             "  {\n"
             "    \"account\":\"accountname\",       (string) DEPRECATED. The "
             "account name associated with the transaction. \n"
             "                                                It will be \"\" "
             "for the default account.\n"
             "    \"address\":\"address\",    (string) The bitcoin address of "
             "the transaction. Not present for \n"
             "                                                move transactions "
             "(category = move).\n"
             "    \"category\":\"send|receive|move\", (string) The transaction "
             "category. 'move' is a local (off blockchain)\n"
             "                                                transaction "
             "between accounts, and not associated with an address,\n"
             "                                                transaction id or "
             "block. 'send' and 'receive' transactions are \n"
             "                                                associated with "
             "an address, transaction id and block details\n"
             "    \"amount\": x.xxx,          (numeric) The amount in " +
             CURRENCY_UNIT +
             ". This is negative for the 'send' category, and for the\n"
             "                                         'move' category for "
             "moves outbound. It is positive for the 'receive' category,\n"
             "                                         and for the 'move' "
             "category for inbound funds.\n"
             "    \"label\": \"label\",       (string) A comment for the "
             "address/transaction, if any\n"
             "    \"vout\": n,                (numeric) the vout value\n"
             "    \"fee\": x.xxx,             (numeric) The amount of the fee "
             "in " +
             CURRENCY_UNIT +
             ". This is negative and only available for the \n"
             "                                         'send' category of "
             "transactions.\n"
             "    \"confirmations\": n,       (numeric) The number of "
             "confirmations for the transaction. Available for 'send' and \n"
             "                                         'receive' category of "
             "transactions. Negative confirmations indicate the\n"
             "                                         transaction conflicts "
             "with the block chain\n"
             "    \"trusted\": xxx,           (bool) Whether we consider the "
             "outputs of this unconfirmed transaction safe to spend.\n"
             "    \"blockhash\": \"hashvalue\", (string) The block hash "
             "containing the transaction. Available for 'send' and 'receive'\n"
             "                                          category of "
             "transactions.\n"
             "    \"blockindex\": n,          (numeric) The index of the "
             "transaction in the block that includes it. Available for 'send' "
             "and 'receive'\n"
             "                                          category of "
             "transactions.\n"
             "    \"blocktime\": xxx,         (numeric) The block time in "
             "seconds since epoch (1 Jan 1970 GMT).\n"
             "    \"txid\": \"transactionid\", (string) The transaction id. "
             "Available for 'send' and 'receive' category of transactions.\n"
             "    \"time\": xxx,              (numeric) The transaction time in "
             "seconds since epoch (midnight Jan 1 1970 GMT).\n"
             "    \"timereceived\": xxx,      (numeric) The time received in "
             "seconds since epoch (midnight Jan 1 1970 GMT). Available \n"
             "                                          for 'send' and "
             "'receive' category of transactions.\n"
             "    \"comment\": \"...\",       (string) If a comment is "
             "associated with the transaction.\n"
             "    \"otheraccount\": \"accountname\",  (string) DEPRECATED. For "
             "the 'move' category of transactions, the account the funds came \n"
             "                                          from (for receiving "
             "funds, positive amounts), or went to (for sending funds,\n"
             "                                          negative amounts).\n"
             "    \"abandoned\": xxx          (bool) 'true' if the transaction "
             "has been abandoned (inputs are respendable). Only available for "
             "the \n"
             "                                         'send' category of "
             "transactions.\n"
             "  }\n"
             "]\n"
 
             "\nExamples:\n"
             "\nList the most recent 10 transactions in the systems\n" +
             HelpExampleCli("listtransactions", "") +
             "\nList transactions 100 to 120\n" +
             HelpExampleCli("listtransactions", "\"*\" 20 100") +
             "\nAs a json rpc call\n" +
             HelpExampleRpc("listtransactions", "\"*\", 20, 100"));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     std::string strAccount = "*";
     if (request.params.size() > 0) {
         strAccount = request.params[0].get_str();
     }
 
     int nCount = 10;
     if (request.params.size() > 1) {
         nCount = request.params[1].get_int();
     }
 
     int nFrom = 0;
     if (request.params.size() > 2) {
         nFrom = request.params[2].get_int();
     }
 
     isminefilter filter = ISMINE_SPENDABLE;
     if (request.params.size() > 3 && request.params[3].get_bool()) {
         filter = filter | ISMINE_WATCH_ONLY;
     }
 
     if (nCount < 0) {
         throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count");
     }
     if (nFrom < 0) {
         throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from");
     }
     UniValue ret(UniValue::VARR);
 
     const CWallet::TxItems &txOrdered = pwalletMain->wtxOrdered;
 
     // iterate backwards until we have nCount items to return:
     for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin();
          it != txOrdered.rend(); ++it) {
         CWalletTx *const pwtx = (*it).second.first;
         if (pwtx != 0) {
             ListTransactions(*pwtx, strAccount, 0, true, ret, filter);
         }
         CAccountingEntry *const pacentry = (*it).second.second;
         if (pacentry != 0) {
             AcentryToJSON(*pacentry, strAccount, ret);
         }
 
         if ((int)ret.size() >= (nCount + nFrom)) {
             break;
         }
     }
 
     // ret is newest to oldest
 
     if (nFrom > (int)ret.size()) {
         nFrom = ret.size();
     }
     if ((nFrom + nCount) > (int)ret.size()) {
         nCount = ret.size() - nFrom;
     }
 
     std::vector<UniValue> arrTmp = ret.getValues();
 
     std::vector<UniValue>::iterator first = arrTmp.begin();
     std::advance(first, nFrom);
     std::vector<UniValue>::iterator last = arrTmp.begin();
     std::advance(last, nFrom + nCount);
 
     if (last != arrTmp.end()) {
         arrTmp.erase(last, arrTmp.end());
     }
     if (first != arrTmp.begin()) {
         arrTmp.erase(arrTmp.begin(), first);
     }
 
     // Return oldest to newest
     std::reverse(arrTmp.begin(), arrTmp.end());
 
     ret.clear();
     ret.setArray();
     ret.push_backV(arrTmp);
 
     return ret;
 }
 
 static UniValue listaccounts(const Config &config,
                              const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() > 2) {
         throw std::runtime_error(
             "listaccounts ( minconf include_watchonly)\n"
             "\nDEPRECATED. Returns Object that has account names as keys, "
             "account balances as values.\n"
             "\nArguments:\n"
             "1. minconf             (numeric, optional, default=1) Only "
             "include transactions with at least this many confirmations\n"
             "2. include_watchonly   (bool, optional, default=false) Include "
             "balances in watch-only addresses (see 'importaddress')\n"
             "\nResult:\n"
             "{                      (json object where keys are account names, "
             "and values are numeric balances\n"
             "  \"account\": x.xxx,  (numeric) The property name is the account "
             "name, and the value is the total balance for the account.\n"
             "  ...\n"
             "}\n"
             "\nExamples:\n"
             "\nList account balances where there at least 1 confirmation\n" +
             HelpExampleCli("listaccounts", "") + "\nList account balances "
                                                  "including zero confirmation "
                                                  "transactions\n" +
             HelpExampleCli("listaccounts", "0") +
             "\nList account balances for 6 or more confirmations\n" +
             HelpExampleCli("listaccounts", "6") + "\nAs json rpc call\n" +
             HelpExampleRpc("listaccounts", "6"));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     int nMinDepth = 1;
     if (request.params.size() > 0) {
         nMinDepth = request.params[0].get_int();
     }
 
     isminefilter includeWatchonly = ISMINE_SPENDABLE;
     if (request.params.size() > 1 && request.params[1].get_bool()) {
         includeWatchonly = includeWatchonly | ISMINE_WATCH_ONLY;
     }
 
     std::map<std::string, CAmount> mapAccountBalances;
     for (const std::pair<CTxDestination, CAddressBookData> &entry :
          pwalletMain->mapAddressBook) {
         // This address belongs to me
         if (IsMine(*pwalletMain, entry.first) & includeWatchonly) {
             mapAccountBalances[entry.second.name] = 0;
         }
     }
 
     for (std::map<uint256, CWalletTx>::iterator it =
              pwalletMain->mapWallet.begin();
          it != pwalletMain->mapWallet.end(); ++it) {
         const CWalletTx &wtx = (*it).second;
         CAmount nFee;
         std::string strSentAccount;
         std::list<COutputEntry> listReceived;
         std::list<COutputEntry> listSent;
         int nDepth = wtx.GetDepthInMainChain();
         if (wtx.GetBlocksToMaturity() > 0 || nDepth < 0) {
             continue;
         }
         wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount,
                        includeWatchonly);
         mapAccountBalances[strSentAccount] -= nFee;
         for (const COutputEntry &s : listSent) {
             mapAccountBalances[strSentAccount] -= s.amount;
         }
         if (nDepth >= nMinDepth) {
             for (const COutputEntry &r : listReceived) {
                 if (pwalletMain->mapAddressBook.count(r.destination)) {
                     mapAccountBalances
                         [pwalletMain->mapAddressBook[r.destination].name] +=
                         r.amount;
                 } else {
                     mapAccountBalances[""] += r.amount;
                 }
             }
         }
     }
 
     const std::list<CAccountingEntry> &acentries = pwalletMain->laccentries;
     for (const CAccountingEntry &entry : acentries) {
         mapAccountBalances[entry.strAccount] += entry.nCreditDebit;
     }
 
     UniValue ret(UniValue::VOBJ);
     for (const std::pair<std::string, CAmount> &accountBalance :
          mapAccountBalances) {
         ret.push_back(
             Pair(accountBalance.first, ValueFromAmount(accountBalance.second)));
     }
     return ret;
 }
 
 static UniValue listsinceblock(const Config &config,
                                const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp) {
         throw std::runtime_error(
             "listsinceblock ( \"blockhash\" target_confirmations "
             "include_watchonly)\n"
             "\nGet all transactions in blocks since block [blockhash], or all "
             "transactions if omitted\n"
             "\nArguments:\n"
             "1. \"blockhash\"            (string, optional) The block hash to "
             "list transactions since\n"
             "2. target_confirmations:    (numeric, optional) The confirmations "
             "required, must be 1 or more\n"
             "3. include_watchonly:       (bool, optional, default=false) "
             "Include transactions to watch-only addresses (see 'importaddress')"
             "\nResult:\n"
             "{\n"
             "  \"transactions\": [\n"
             "    \"account\":\"accountname\",       (string) DEPRECATED. The "
             "account name associated with the transaction. Will be \"\" for "
             "the default account.\n"
             "    \"address\":\"address\",    (string) The bitcoin address of "
             "the transaction. Not present for move transactions (category = "
             "move).\n"
             "    \"category\":\"send|receive\",     (string) The transaction "
             "category. 'send' has negative amounts, 'receive' has positive "
             "amounts.\n"
             "    \"amount\": x.xxx,          (numeric) The amount in " +
             CURRENCY_UNIT +
             ". This is negative for the 'send' category, and for the 'move' "
             "category for moves \n"
             "                                          outbound. It is "
             "positive for the 'receive' category, and for the 'move' category "
             "for inbound funds.\n"
             "    \"vout\" : n,               (numeric) the vout value\n"
             "    \"fee\": x.xxx,             (numeric) The amount of the fee "
             "in " +
             CURRENCY_UNIT +
             ". This is negative and only available for the 'send' category of "
             "transactions.\n"
             "    \"confirmations\": n,       (numeric) The number of "
             "confirmations for the transaction. Available for 'send' and "
             "'receive' category of transactions.\n"
             "                                          When it's < 0, it means "
             "the transaction conflicted that many blocks ago.\n"
             "    \"blockhash\": \"hashvalue\",     (string) The block hash "
             "containing the transaction. Available for 'send' and 'receive' "
             "category of transactions.\n"
             "    \"blockindex\": n,          (numeric) The index of the "
             "transaction in the block that includes it. Available for 'send' "
             "and 'receive' category of transactions.\n"
             "    \"blocktime\": xxx,         (numeric) The block time in "
             "seconds since epoch (1 Jan 1970 GMT).\n"
             "    \"txid\": \"transactionid\",  (string) The transaction id. "
             "Available for 'send' and 'receive' category of transactions.\n"
             "    \"time\": xxx,              (numeric) The transaction time in "
             "seconds since epoch (Jan 1 1970 GMT).\n"
             "    \"timereceived\": xxx,      (numeric) The time received in "
             "seconds since epoch (Jan 1 1970 GMT). Available for 'send' and "
             "'receive' category of transactions.\n"
             "    \"abandoned\": xxx,         (bool) 'true' if the transaction "
             "has been abandoned (inputs are respendable). Only available for "
             "the 'send' category of transactions.\n"
             "    \"comment\": \"...\",       (string) If a comment is "
             "associated with the transaction.\n"
             "    \"label\" : \"label\"       (string) A comment for the "
             "address/transaction, if any\n"
             "    \"to\": \"...\",            (string) If a comment to is "
             "associated with the transaction.\n"
             "  ],\n"
             "  \"lastblock\": \"lastblockhash\"     (string) The hash of the "
             "last block\n"
             "}\n"
             "\nExamples:\n" +
             HelpExampleCli("listsinceblock", "") +
             HelpExampleCli("listsinceblock", "\"000000000000000bacf66f7497b7dc4"
                                              "5ef753ee9a7d38571037cdb1a57f663ad"
                                              "\" 6") +
             HelpExampleRpc("listsinceblock", "\"000000000000000bacf66f7497b7dc4"
                                              "5ef753ee9a7d38571037cdb1a57f663ad"
                                              "\", 6"));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     const CBlockIndex *pindex = nullptr;
     int target_confirms = 1;
     isminefilter filter = ISMINE_SPENDABLE;
 
     if (request.params.size() > 0) {
         uint256 blockId;
 
         blockId.SetHex(request.params[0].get_str());
         BlockMap::iterator it = mapBlockIndex.find(blockId);
         if (it != mapBlockIndex.end()) {
             pindex = it->second;
             if (chainActive[pindex->nHeight] != pindex) {
                 // the block being asked for is a part of a deactivated chain;
                 // we don't want to depend on its perceived height in the block
                 // chain, we want to instead use the last common ancestor
                 pindex = chainActive.FindFork(pindex);
             }
         }
     }
 
     if (request.params.size() > 1) {
         target_confirms = request.params[1].get_int();
 
         if (target_confirms < 1) {
             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter");
         }
     }
 
     if (request.params.size() > 2 && request.params[2].get_bool()) {
         filter = filter | ISMINE_WATCH_ONLY;
     }
 
     int depth = pindex ? (1 + chainActive.Height() - pindex->nHeight) : -1;
 
     UniValue transactions(UniValue::VARR);
 
     for (std::map<uint256, CWalletTx>::iterator it =
              pwalletMain->mapWallet.begin();
          it != pwalletMain->mapWallet.end(); it++) {
         CWalletTx tx = (*it).second;
 
         if (depth == -1 || tx.GetDepthInMainChain() < depth) {
             ListTransactions(tx, "*", 0, true, transactions, filter);
         }
     }
 
     CBlockIndex *pblockLast =
         chainActive[chainActive.Height() + 1 - target_confirms];
     uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : uint256();
 
     UniValue ret(UniValue::VOBJ);
     ret.push_back(Pair("transactions", transactions));
     ret.push_back(Pair("lastblock", lastblock.GetHex()));
 
     return ret;
 }
 
 static UniValue gettransaction(const Config &config,
                                const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() < 1 ||
         request.params.size() > 2) {
         throw std::runtime_error(
             "gettransaction \"txid\" ( include_watchonly )\n"
             "\nGet detailed information about in-wallet transaction <txid>\n"
             "\nArguments:\n"
             "1. \"txid\"                  (string, required) The transaction "
             "id\n"
             "2. \"include_watchonly\"     (bool, optional, default=false) "
             "Whether to include watch-only addresses in balance calculation "
             "and details[]\n"
             "\nResult:\n"
             "{\n"
             "  \"amount\" : x.xxx,        (numeric) The transaction amount "
             "in " +
             CURRENCY_UNIT +
             "\n"
             "  \"fee\": x.xxx,            (numeric) The amount of the fee in " +
             CURRENCY_UNIT +
             ". This is negative and only available for the \n"
             "                              'send' category of transactions.\n"
             "  \"confirmations\" : n,     (numeric) The number of "
             "confirmations\n"
             "  \"blockhash\" : \"hash\",  (string) The block hash\n"
             "  \"blockindex\" : xx,       (numeric) The index of the "
             "transaction in the block that includes it\n"
             "  \"blocktime\" : ttt,       (numeric) The time in seconds since "
             "epoch (1 Jan 1970 GMT)\n"
             "  \"txid\" : \"transactionid\",   (string) The transaction id.\n"
             "  \"time\" : ttt,            (numeric) The transaction time in "
             "seconds since epoch (1 Jan 1970 GMT)\n"
             "  \"timereceived\" : ttt,    (numeric) The time received in "
             "seconds since epoch (1 Jan 1970 GMT)\n"
             "  \"bip125-replaceable\": \"yes|no|unknown\",  (string) Whether "
             "this transaction could be replaced due to BIP125 "
             "(replace-by-fee);\n"
             "                                                   may be unknown "
             "for unconfirmed transactions not in the mempool\n"
             "  \"details\" : [\n"
             "    {\n"
             "      \"account\" : \"accountname\",      (string) DEPRECATED. "
             "The account name involved in the transaction, can be \"\" for the "
             "default account.\n"
             "      \"address\" : \"address\",          (string) The bitcoin "
             "address involved in the transaction\n"
             "      \"category\" : \"send|receive\",    (string) The category, "
             "either 'send' or 'receive'\n"
             "      \"amount\" : x.xxx,                 (numeric) The amount "
             "in " +
             CURRENCY_UNIT + "\n"
                             "      \"label\" : \"label\",              "
                             "(string) A comment for the address/transaction, "
                             "if any\n"
                             "      \"vout\" : n,                       "
                             "(numeric) the vout value\n"
                             "      \"fee\": x.xxx,                     "
                             "(numeric) The amount of the fee in " +
             CURRENCY_UNIT +
             ". This is negative and only available for the \n"
             "                                           'send' category of "
             "transactions.\n"
             "      \"abandoned\": xxx                  (bool) 'true' if the "
             "transaction has been abandoned (inputs are respendable). Only "
             "available for the \n"
             "                                           'send' category of "
             "transactions.\n"
             "    }\n"
             "    ,...\n"
             "  ],\n"
             "  \"hex\" : \"data\"         (string) Raw data for transaction\n"
             "}\n"
 
             "\nExamples:\n" +
             HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e211"
                                              "5b9345e16c5cf302fc80e9d5fbf5d48d"
                                              "\"") +
             HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e211"
                                              "5b9345e16c5cf302fc80e9d5fbf5d48d"
                                              "\" true") +
             HelpExampleRpc("gettransaction", "\"1075db55d416d3ca199f55b6084e211"
                                              "5b9345e16c5cf302fc80e9d5fbf5d48d"
                                              "\""));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     uint256 hash;
     hash.SetHex(request.params[0].get_str());
 
     isminefilter filter = ISMINE_SPENDABLE;
     if (request.params.size() > 1 && request.params[1].get_bool()) {
         filter = filter | ISMINE_WATCH_ONLY;
     }
 
     UniValue entry(UniValue::VOBJ);
     if (!pwalletMain->mapWallet.count(hash)) {
         {
             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                                "Invalid or non-wallet transaction id");
         }
     }
 
     const CWalletTx &wtx = pwalletMain->mapWallet[hash];
 
     CAmount nCredit = wtx.GetCredit(filter);
     CAmount nDebit = wtx.GetDebit(filter);
     CAmount nNet = nCredit - nDebit;
     CAmount nFee = (wtx.IsFromMe(filter) ? wtx.tx->GetValueOut() - nDebit : 0);
 
     entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
     if (wtx.IsFromMe(filter)) {
         entry.push_back(Pair("fee", ValueFromAmount(nFee)));
     }
 
     WalletTxToJSON(wtx, entry);
 
     UniValue details(UniValue::VARR);
     ListTransactions(wtx, "*", 0, false, details, filter);
     entry.push_back(Pair("details", details));
 
     std::string strHex =
         EncodeHexTx(static_cast<CTransaction>(wtx), RPCSerializationFlags());
     entry.push_back(Pair("hex", strHex));
 
     return entry;
 }
 
 static UniValue abandontransaction(const Config &config,
                                    const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() != 1) {
         throw std::runtime_error(
             "abandontransaction \"txid\"\n"
             "\nMark in-wallet transaction <txid> as abandoned\n"
             "This will mark this transaction and all its in-wallet descendants "
             "as abandoned which will allow\n"
             "for their inputs to be respent.  It can be used to replace "
             "\"stuck\" or evicted transactions.\n"
             "It only works on transactions which are not included in a block "
             "and are not currently in the mempool.\n"
             "It has no effect on transactions which are already conflicted or "
             "abandoned.\n"
             "\nArguments:\n"
             "1. \"txid\"    (string, required) The transaction id\n"
             "\nResult:\n"
             "\nExamples:\n" +
             HelpExampleCli("abandontransaction", "\"1075db55d416d3ca199f55b6084"
                                                  "e2115b9345e16c5cf302fc80e9d5f"
                                                  "bf5d48d\"") +
             HelpExampleRpc("abandontransaction", "\"1075db55d416d3ca199f55b6084"
                                                  "e2115b9345e16c5cf302fc80e9d5f"
                                                  "bf5d48d\""));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     uint256 hash;
     hash.SetHex(request.params[0].get_str());
 
     if (!pwalletMain->mapWallet.count(hash)) {
         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                            "Invalid or non-wallet transaction id");
     }
 
     if (!pwalletMain->AbandonTransaction(hash)) {
         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                            "Transaction not eligible for abandonment");
     }
 
     return NullUniValue;
 }
 
 static UniValue backupwallet(const Config &config,
                              const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() != 1) {
         throw std::runtime_error(
             "backupwallet \"destination\"\n"
             "\nSafely copies current wallet file to destination, which can be "
             "a directory or a path with filename.\n"
             "\nArguments:\n"
             "1. \"destination\"   (string) The destination directory or file\n"
             "\nExamples:\n" +
             HelpExampleCli("backupwallet", "\"backup.dat\"") +
             HelpExampleRpc("backupwallet", "\"backup.dat\""));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     std::string strDest = request.params[0].get_str();
     if (!pwalletMain->BackupWallet(strDest)) {
         throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!");
     }
 
     return NullUniValue;
 }
 
 static UniValue keypoolrefill(const Config &config,
                               const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() > 1) {
         throw std::runtime_error(
             "keypoolrefill ( newsize )\n"
             "\nFills the keypool." +
             HelpRequiringPassphrase() +
             "\n"
             "\nArguments\n"
             "1. newsize     (numeric, optional, default=100) "
             "The new keypool size\n"
             "\nExamples:\n" +
             HelpExampleCli("keypoolrefill", "") +
             HelpExampleRpc("keypoolrefill", ""));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     // 0 is interpreted by TopUpKeyPool() as the default keypool size given by
     // -keypool
     unsigned int kpSize = 0;
     if (request.params.size() > 0) {
         if (request.params[0].get_int() < 0) {
             throw JSONRPCError(RPC_INVALID_PARAMETER,
                                "Invalid parameter, expected valid size.");
         }
         kpSize = (unsigned int)request.params[0].get_int();
     }
 
     EnsureWalletIsUnlocked();
     pwalletMain->TopUpKeyPool(kpSize);
 
     if (pwalletMain->GetKeyPoolSize() < kpSize) {
         throw JSONRPCError(RPC_WALLET_ERROR, "Error refreshing keypool.");
     }
 
     return NullUniValue;
 }
 
 static void LockWallet(CWallet *pWallet) {
     LOCK(cs_nWalletUnlockTime);
     nWalletUnlockTime = 0;
     pWallet->Lock();
 }
 
 static UniValue walletpassphrase(const Config &config,
                                  const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (pwalletMain->IsCrypted() &&
         (request.fHelp || request.params.size() != 2)) {
         throw std::runtime_error(
             "walletpassphrase \"passphrase\" timeout\n"
             "\nStores the wallet decryption key in memory for 'timeout' "
             "seconds.\n"
             "This is needed prior to performing transactions related to "
             "private keys such as sending bitcoins\n"
             "\nArguments:\n"
             "1. \"passphrase\"     (string, required) The wallet passphrase\n"
             "2. timeout            (numeric, required) The time to keep the "
             "decryption key in seconds.\n"
             "\nNote:\n"
             "Issuing the walletpassphrase command while the wallet is already "
             "unlocked will set a new unlock\n"
             "time that overrides the old one.\n"
             "\nExamples:\n"
             "\nunlock the wallet for 60 seconds\n" +
             HelpExampleCli("walletpassphrase", "\"my pass phrase\" 60") +
             "\nLock the wallet again (before 60 seconds)\n" +
             HelpExampleCli("walletlock", "") + "\nAs json rpc call\n" +
             HelpExampleRpc("walletpassphrase", "\"my pass phrase\", 60"));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     if (request.fHelp) {
         return true;
     }
     if (!pwalletMain->IsCrypted()) {
         throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE,
                            "Error: running with an unencrypted wallet, but "
                            "walletpassphrase was called.");
     }
 
     // Note that the walletpassphrase is stored in request.params[0] which is
     // not mlock()ed
     SecureString strWalletPass;
     strWalletPass.reserve(100);
     // TODO: get rid of this .c_str() by implementing
     // SecureString::operator=(std::string)
     // Alternately, find a way to make request.params[0] mlock()'d to begin
     // with.
     strWalletPass = request.params[0].get_str().c_str();
 
     if (strWalletPass.length() > 0) {
         if (!pwalletMain->Unlock(strWalletPass)) {
             throw JSONRPCError(
                 RPC_WALLET_PASSPHRASE_INCORRECT,
                 "Error: The wallet passphrase entered was incorrect.");
         }
     } else {
         throw std::runtime_error(
             "walletpassphrase <passphrase> <timeout>\n"
             "Stores the wallet decryption key in memory for "
             "<timeout> seconds.");
     }
 
     pwalletMain->TopUpKeyPool();
 
     int64_t nSleepTime = request.params[1].get_int64();
     LOCK(cs_nWalletUnlockTime);
     nWalletUnlockTime = GetTime() + nSleepTime;
     RPCRunLater("lockwallet", boost::bind(LockWallet, pwalletMain), nSleepTime);
 
     return NullUniValue;
 }
 
 static UniValue walletpassphrasechange(const Config &config,
                                        const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (pwalletMain->IsCrypted() &&
         (request.fHelp || request.params.size() != 2)) {
         throw std::runtime_error(
             "walletpassphrasechange \"oldpassphrase\" \"newpassphrase\"\n"
             "\nChanges the wallet passphrase from 'oldpassphrase' to "
             "'newpassphrase'.\n"
             "\nArguments:\n"
             "1. \"oldpassphrase\"      (string) The current passphrase\n"
             "2. \"newpassphrase\"      (string) The new passphrase\n"
             "\nExamples:\n" +
             HelpExampleCli("walletpassphrasechange",
                            "\"old one\" \"new one\"") +
             HelpExampleRpc("walletpassphrasechange",
                            "\"old one\", \"new one\""));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     if (request.fHelp) {
         return true;
     }
     if (!pwalletMain->IsCrypted()) {
         throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE,
                            "Error: running with an unencrypted wallet, but "
                            "walletpassphrasechange was called.");
     }
 
     // TODO: get rid of these .c_str() calls by implementing
     // SecureString::operator=(std::string)
     // Alternately, find a way to make request.params[0] mlock()'d to begin
     // with.
     SecureString strOldWalletPass;
     strOldWalletPass.reserve(100);
     strOldWalletPass = request.params[0].get_str().c_str();
 
     SecureString strNewWalletPass;
     strNewWalletPass.reserve(100);
     strNewWalletPass = request.params[1].get_str().c_str();
 
     if (strOldWalletPass.length() < 1 || strNewWalletPass.length() < 1) {
         throw std::runtime_error(
             "walletpassphrasechange <oldpassphrase> <newpassphrase>\n"
             "Changes the wallet passphrase from <oldpassphrase> to "
             "<newpassphrase>.");
     }
 
     if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass,
                                              strNewWalletPass)) {
         throw JSONRPCError(
             RPC_WALLET_PASSPHRASE_INCORRECT,
             "Error: The wallet passphrase entered was incorrect.");
     }
 
     return NullUniValue;
 }
 
 static UniValue walletlock(const Config &config,
                            const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (pwalletMain->IsCrypted() &&
         (request.fHelp || request.params.size() != 0)) {
         throw std::runtime_error(
             "walletlock\n"
             "\nRemoves the wallet encryption key from memory, locking the "
             "wallet.\n"
             "After calling this method, you will need to call walletpassphrase "
             "again\n"
             "before being able to call any methods which require the wallet to "
             "be unlocked.\n"
             "\nExamples:\n"
             "\nSet the passphrase for 2 minutes to perform a transaction\n" +
             HelpExampleCli("walletpassphrase", "\"my pass phrase\" 120") +
             "\nPerform a send (requires passphrase set)\n" +
             HelpExampleCli("sendtoaddress",
                            "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 1.0") +
             "\nClear the passphrase since we are done before 2 minutes is "
             "up\n" +
             HelpExampleCli("walletlock", "") + "\nAs json rpc call\n" +
             HelpExampleRpc("walletlock", ""));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     if (request.fHelp) {
         return true;
     }
     if (!pwalletMain->IsCrypted()) {
         throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE,
                            "Error: running with an unencrypted wallet, but "
                            "walletlock was called.");
     }
 
     {
         LOCK(cs_nWalletUnlockTime);
         pwalletMain->Lock();
         nWalletUnlockTime = 0;
     }
 
     return NullUniValue;
 }
 
 static UniValue encryptwallet(const Config &config,
                               const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (!pwalletMain->IsCrypted() &&
         (request.fHelp || request.params.size() != 1)) {
         throw std::runtime_error(
             "encryptwallet \"passphrase\"\n"
             "\nEncrypts the wallet with 'passphrase'. This is for first time "
             "encryption.\n"
             "After this, any calls that interact with private keys such as "
             "sending or signing \n"
             "will require the passphrase to be set prior the making these "
             "calls.\n"
             "Use the walletpassphrase call for this, and then walletlock "
             "call.\n"
             "If the wallet is already encrypted, use the "
             "walletpassphrasechange call.\n"
             "Note that this will shutdown the server.\n"
             "\nArguments:\n"
             "1. \"passphrase\"    (string) The pass phrase to encrypt the "
             "wallet with. It must be at least 1 character, but should be "
             "long.\n"
             "\nExamples:\n"
             "\nEncrypt you wallet\n" +
             HelpExampleCli("encryptwallet", "\"my pass phrase\"") +
             "\nNow set the passphrase to use the wallet, such as for signing "
             "or sending bitcoin\n" +
             HelpExampleCli("walletpassphrase", "\"my pass phrase\"") +
             "\nNow we can so something like sign\n" +
             HelpExampleCli("signmessage", "\"address\" \"test message\"") +
             "\nNow lock the wallet again by removing the passphrase\n" +
             HelpExampleCli("walletlock", "") + "\nAs a json rpc call\n" +
             HelpExampleRpc("encryptwallet", "\"my pass phrase\""));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     if (request.fHelp) {
         return true;
     }
     if (pwalletMain->IsCrypted()) {
         throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE,
                            "Error: running with an encrypted wallet, but "
                            "encryptwallet was called.");
     }
 
     // TODO: get rid of this .c_str() by implementing
     // SecureString::operator=(std::string)
     // Alternately, find a way to make request.params[0] mlock()'d to begin
     // with.
     SecureString strWalletPass;
     strWalletPass.reserve(100);
     strWalletPass = request.params[0].get_str().c_str();
 
     if (strWalletPass.length() < 1) {
         throw std::runtime_error("encryptwallet <passphrase>\n"
                                  "Encrypts the wallet with <passphrase>.");
     }
 
     if (!pwalletMain->EncryptWallet(strWalletPass)) {
         throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED,
                            "Error: Failed to encrypt the wallet.");
     }
 
     // BDB seems to have a bad habit of writing old data into
     // slack space in .dat files; that is bad if the old data is
     // unencrypted private keys. So:
     StartShutdown();
     return "wallet encrypted; Bitcoin server stopping, restart to run with "
            "encrypted wallet. The keypool has been flushed and a new HD seed "
            "was generated (if you are using HD). You need to make a new "
            "backup.";
 }
 
 static UniValue lockunspent(const Config &config,
                             const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() < 1 ||
         request.params.size() > 2) {
         throw std::runtime_error(
             "lockunspent unlock ([{\"txid\":\"txid\",\"vout\":n},...])\n"
             "\nUpdates list of temporarily unspendable outputs.\n"
             "Temporarily lock (unlock=false) or unlock (unlock=true) specified "
             "transaction outputs.\n"
             "If no transaction outputs are specified when unlocking then all "
             "current locked transaction outputs are unlocked.\n"
             "A locked transaction output will not be chosen by automatic coin "
             "selection, when spending bitcoins.\n"
             "Locks are stored in memory only. Nodes start with zero locked "
             "outputs, and the locked output list\n"
             "is always cleared (by virtue of process exit) when a node stops "
             "or fails.\n"
             "Also see the listunspent call\n"
             "\nArguments:\n"
             "1. unlock            (boolean, required) Whether to unlock (true) "
             "or lock (false) the specified transactions\n"
             "2. \"transactions\"  (string, optional) A json array of objects. "
             "Each object the txid (string) vout (numeric)\n"
             "     [           (json array of json objects)\n"
             "       {\n"
             "         \"txid\":\"id\",    (string) The transaction id\n"
             "         \"vout\": n         (numeric) The output number\n"
             "       }\n"
             "       ,...\n"
             "     ]\n"
 
             "\nResult:\n"
             "true|false    (boolean) Whether the command was successful or "
             "not\n"
 
             "\nExamples:\n"
             "\nList the unspent transactions\n" +
             HelpExampleCli("listunspent", "") +
             "\nLock an unspent transaction\n" +
             HelpExampleCli("lockunspent", "false "
                                           "\"[{\\\"txid\\\":"
                                           "\\\"a08e6907dbbd3d809776dbfc5d82e371"
                                           "b764ed838b5655e72f463568df1aadf0\\\""
                                           ",\\\"vout\\\":1}]\"") +
             "\nList the locked transactions\n" +
             HelpExampleCli("listlockunspent", "") +
             "\nUnlock the transaction again\n" +
             HelpExampleCli("lockunspent", "true "
                                           "\"[{\\\"txid\\\":"
                                           "\\\"a08e6907dbbd3d809776dbfc5d82e371"
                                           "b764ed838b5655e72f463568df1aadf0\\\""
                                           ",\\\"vout\\\":1}]\"") +
             "\nAs a json rpc call\n" +
             HelpExampleRpc("lockunspent", "false, "
                                           "\"[{\\\"txid\\\":"
                                           "\\\"a08e6907dbbd3d809776dbfc5d82e371"
                                           "b764ed838b5655e72f463568df1aadf0\\\""
                                           ",\\\"vout\\\":1}]\""));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     if (request.params.size() == 1) {
         RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VBOOL));
     } else {
         RPCTypeCheck(request.params,
                      boost::assign::list_of(UniValue::VBOOL)(UniValue::VARR));
     }
 
     bool fUnlock = request.params[0].get_bool();
 
     if (request.params.size() == 1) {
         if (fUnlock) {
             pwalletMain->UnlockAllCoins();
         }
         return true;
     }
 
     UniValue outputs = request.params[1].get_array();
     for (size_t idx = 0; idx < outputs.size(); idx++) {
         const UniValue &output = outputs[idx];
         if (!output.isObject()) {
             throw JSONRPCError(RPC_INVALID_PARAMETER,
                                "Invalid parameter, expected object");
         }
         const UniValue &o = output.get_obj();
 
         RPCTypeCheckObj(o, {
                                {"txid", UniValueType(UniValue::VSTR)},
                                {"vout", UniValueType(UniValue::VNUM)},
                            });
 
         std::string txid = find_value(o, "txid").get_str();
         if (!IsHex(txid)) {
             throw JSONRPCError(RPC_INVALID_PARAMETER,
                                "Invalid parameter, expected hex txid");
         }
 
         int nOutput = find_value(o, "vout").get_int();
         if (nOutput < 0) {
             throw JSONRPCError(RPC_INVALID_PARAMETER,
                                "Invalid parameter, vout must be positive");
         }
 
         COutPoint outpt(uint256S(txid), nOutput);
 
         if (fUnlock) {
             pwalletMain->UnlockCoin(outpt);
         } else {
             pwalletMain->LockCoin(outpt);
         }
     }
 
     return true;
 }
 
 static UniValue listlockunspent(const Config &config,
                                 const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() > 0) {
         throw std::runtime_error(
             "listlockunspent\n"
             "\nReturns list of temporarily unspendable outputs.\n"
             "See the lockunspent call to lock and unlock transactions for "
             "spending.\n"
             "\nResult:\n"
             "[\n"
             "  {\n"
             "    \"txid\" : \"transactionid\",     (string) The transaction id "
             "locked\n"
             "    \"vout\" : n                      (numeric) The vout value\n"
             "  }\n"
             "  ,...\n"
             "]\n"
             "\nExamples:\n"
             "\nList the unspent transactions\n" +
             HelpExampleCli("listunspent", "") +
             "\nLock an unspent transaction\n" +
             HelpExampleCli("lockunspent", "false "
                                           "\"[{\\\"txid\\\":"
                                           "\\\"a08e6907dbbd3d809776dbfc5d82e371"
                                           "b764ed838b5655e72f463568df1aadf0\\\""
                                           ",\\\"vout\\\":1}]\"") +
             "\nList the locked transactions\n" +
             HelpExampleCli("listlockunspent", "") +
             "\nUnlock the transaction again\n" +
             HelpExampleCli("lockunspent", "true "
                                           "\"[{\\\"txid\\\":"
                                           "\\\"a08e6907dbbd3d809776dbfc5d82e371"
                                           "b764ed838b5655e72f463568df1aadf0\\\""
                                           ",\\\"vout\\\":1}]\"") +
             "\nAs a json rpc call\n" + HelpExampleRpc("listlockunspent", ""));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     std::vector<COutPoint> vOutpts;
     pwalletMain->ListLockedCoins(vOutpts);
 
     UniValue ret(UniValue::VARR);
 
     for (COutPoint &outpt : vOutpts) {
         UniValue o(UniValue::VOBJ);
 
         o.push_back(Pair("txid", outpt.hash.GetHex()));
         o.push_back(Pair("vout", (int)outpt.n));
         ret.push_back(o);
     }
 
     return ret;
 }
 
 static UniValue settxfee(const Config &config, const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() < 1 ||
         request.params.size() > 1) {
         throw std::runtime_error(
             "settxfee amount\n"
             "\nSet the transaction fee per kB. Overwrites the paytxfee "
             "parameter.\n"
             "\nArguments:\n"
             "1. amount         (numeric or string, required) The transaction "
             "fee in " +
             CURRENCY_UNIT +
             "/kB\n"
             "\nResult\n"
             "true|false        (boolean) Returns true if successful\n"
             "\nExamples:\n" +
             HelpExampleCli("settxfee", "0.00001") +
             HelpExampleRpc("settxfee", "0.00001"));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     // Amount
     CAmount nAmount = AmountFromValue(request.params[0]);
 
     payTxFee = CFeeRate(nAmount, 1000);
     return true;
 }
 
 static UniValue getwalletinfo(const Config &config,
                               const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() != 0) {
         throw std::runtime_error(
             "getwalletinfo\n"
             "Returns an object containing various wallet state info.\n"
             "\nResult:\n"
             "{\n"
             "  \"walletversion\": xxxxx,       (numeric) the wallet version\n"
             "  \"balance\": xxxxxxx,           (numeric) the total confirmed "
             "balance of the wallet in " +
             CURRENCY_UNIT + "\n"
                             "  \"unconfirmed_balance\": xxx,   (numeric) the "
                             "total unconfirmed balance of the wallet in " +
             CURRENCY_UNIT + "\n"
                             "  \"immature_balance\": xxxxxx,   (numeric) the "
                             "total immature balance of the wallet in " +
             CURRENCY_UNIT + "\n"
                             "  \"txcount\": xxxxxxx,           (numeric) the "
                             "total number of transactions in the wallet\n"
                             "  \"keypoololdest\": xxxxxx,      (numeric) the "
                             "timestamp (seconds since Unix epoch) of the "
                             "oldest pre-generated key in the key pool\n"
                             "  \"keypoolsize\": xxxx,          (numeric) how "
                             "many new keys are pre-generated\n"
                             "  \"unlocked_until\": ttt,        (numeric) the "
                             "timestamp in seconds since epoch (midnight Jan 1 "
                             "1970 GMT) that the wallet is unlocked for "
                             "transfers, or 0 if the wallet is locked\n"
                             "  \"paytxfee\": x.xxxx,           (numeric) the "
                             "transaction fee configuration, set in " +
             CURRENCY_UNIT + "/kB\n"
                             "  \"hdmasterkeyid\": \"<hash160>\" (string) the "
                             "Hash160 of the HD master pubkey\n"
                             "}\n"
                             "\nExamples:\n" +
             HelpExampleCli("getwalletinfo", "") +
             HelpExampleRpc("getwalletinfo", ""));
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     UniValue obj(UniValue::VOBJ);
     obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
     obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
     obj.push_back(Pair("unconfirmed_balance",
                        ValueFromAmount(pwalletMain->GetUnconfirmedBalance())));
     obj.push_back(Pair("immature_balance",
                        ValueFromAmount(pwalletMain->GetImmatureBalance())));
     obj.push_back(Pair("txcount", (int)pwalletMain->mapWallet.size()));
     obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime()));
     obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
     if (pwalletMain->IsCrypted()) {
         obj.push_back(Pair("unlocked_until", nWalletUnlockTime));
     }
     obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())));
     CKeyID masterKeyID = pwalletMain->GetHDChain().masterKeyID;
     if (!masterKeyID.IsNull()) {
         obj.push_back(Pair("hdmasterkeyid", masterKeyID.GetHex()));
     }
     return obj;
 }
 
 static UniValue resendwallettransactions(const Config &config,
                                          const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() != 0) {
         throw std::runtime_error(
             "resendwallettransactions\n"
             "Immediately re-broadcast unconfirmed wallet transactions to all "
             "peers.\n"
             "Intended only for testing; the wallet code periodically "
             "re-broadcasts\n"
             "automatically.\n"
             "Returns array of transaction ids that were re-broadcast.\n");
     }
 
     if (!g_connman) {
         throw JSONRPCError(
             RPC_CLIENT_P2P_DISABLED,
             "Error: Peer-to-peer functionality missing or disabled");
     }
 
     LOCK2(cs_main, pwalletMain->cs_wallet);
 
     std::vector<uint256> txids =
         pwalletMain->ResendWalletTransactionsBefore(GetTime(), g_connman.get());
     UniValue result(UniValue::VARR);
     for (const uint256 &txid : txids) {
         result.push_back(txid.ToString());
     }
 
     return result;
 }
 
 static UniValue listunspent(const Config &config,
                             const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() > 4) {
         throw std::runtime_error(
             "listunspent ( minconf maxconf  [\"addresses\",...] "
             "[include_unsafe] )\n"
             "\nReturns array of unspent transaction outputs\n"
             "with between minconf and maxconf (inclusive) confirmations.\n"
             "Optionally filter to only include txouts paid to specified "
             "addresses.\n"
             "\nArguments:\n"
             "1. minconf          (numeric, optional, default=1) The minimum "
             "confirmations to filter\n"
             "2. maxconf          (numeric, optional, default=9999999) The "
             "maximum confirmations to filter\n"
             "3. \"addresses\"    (string) A json array of bitcoin addresses to "
             "filter\n"
             "    [\n"
             "      \"address\"   (string) bitcoin address\n"
             "      ,...\n"
             "    ]\n"
             "4. include_unsafe (bool, optional, default=true) Include outputs "
             "that are not safe to spend\n"
             "                  because they come from unconfirmed untrusted "
             "transactions or unconfirmed\n"
             "                  replacement transactions (cases where we are "
             "less sure that a conflicting\n"
             "                  transaction won't be mined).\n"
             "\nResult\n"
             "[                   (array of json object)\n"
             "  {\n"
             "    \"txid\" : \"txid\",          (string) the transaction id \n"
             "    \"vout\" : n,               (numeric) the vout value\n"
             "    \"address\" : \"address\",    (string) the bitcoin address\n"
             "    \"account\" : \"account\",    (string) DEPRECATED. The "
             "associated account, or \"\" for the default account\n"
             "    \"scriptPubKey\" : \"key\",   (string) the script key\n"
             "    \"amount\" : x.xxx,         (numeric) the transaction output "
             "amount in " +
             CURRENCY_UNIT + "\n"
                             "    \"confirmations\" : n,      (numeric) The "
                             "number of confirmations\n"
                             "    \"redeemScript\" : n        (string) The "
                             "redeemScript if scriptPubKey is P2SH\n"
                             "    \"spendable\" : xxx,        (bool) Whether we "
                             "have the private keys to spend this output\n"
                             "    \"solvable\" : xxx          (bool) Whether we "
                             "know how to spend this output, ignoring the lack "
                             "of keys\n"
                             "  }\n"
                             "  ,...\n"
                             "]\n"
 
                             "\nExamples\n" +
             HelpExampleCli("listunspent", "") +
             HelpExampleCli("listunspent",
                            "6 9999999 "
                            "\"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\","
                            "\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") +
             HelpExampleRpc("listunspent",
                            "6, 9999999 "
                            "\"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\","
                            "\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\""));
     }
 
     int nMinDepth = 1;
     if (request.params.size() > 0 && !request.params[0].isNull()) {
         RPCTypeCheckArgument(request.params[0], UniValue::VNUM);
         nMinDepth = request.params[0].get_int();
     }
 
     int nMaxDepth = 9999999;
     if (request.params.size() > 1 && !request.params[1].isNull()) {
         RPCTypeCheckArgument(request.params[1], UniValue::VNUM);
         nMaxDepth = request.params[1].get_int();
     }
 
     std::set<CBitcoinAddress> setAddress;
     if (request.params.size() > 2 && !request.params[2].isNull()) {
         RPCTypeCheckArgument(request.params[2], UniValue::VARR);
         UniValue inputs = request.params[2].get_array();
         for (size_t idx = 0; idx < inputs.size(); idx++) {
             const UniValue &input = inputs[idx];
             CBitcoinAddress address(input.get_str());
             if (!address.IsValid()) {
                 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
                                    std::string("Invalid Bitcoin address: ") +
                                        input.get_str());
             }
             if (setAddress.count(address)) {
                 throw JSONRPCError(
                     RPC_INVALID_PARAMETER,
                     std::string("Invalid parameter, duplicated address: ") +
                         input.get_str());
             }
             setAddress.insert(address);
         }
     }
 
     bool include_unsafe = true;
     if (request.params.size() > 3 && !request.params[3].isNull()) {
         RPCTypeCheckArgument(request.params[3], UniValue::VBOOL);
         include_unsafe = request.params[3].get_bool();
     }
 
     UniValue results(UniValue::VARR);
     std::vector<COutput> vecOutputs;
     assert(pwalletMain != nullptr);
     LOCK2(cs_main, pwalletMain->cs_wallet);
     pwalletMain->AvailableCoins(vecOutputs, !include_unsafe, nullptr, true);
     for (const COutput &out : vecOutputs) {
         if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth) {
             continue;
         }
 
         CTxDestination address;
         const CScript &scriptPubKey = out.tx->tx->vout[out.i].scriptPubKey;
         bool fValidAddress = ExtractDestination(scriptPubKey, address);
 
         if (setAddress.size() &&
             (!fValidAddress || !setAddress.count(address))) {
             continue;
         }
 
         UniValue entry(UniValue::VOBJ);
         entry.push_back(Pair("txid", out.tx->GetId().GetHex()));
         entry.push_back(Pair("vout", out.i));
 
         if (fValidAddress) {
             {
                 entry.push_back(
                     Pair("address", CBitcoinAddress(address).ToString()));
             }
 
             if (pwalletMain->mapAddressBook.count(address)) {
                 entry.push_back(
                     Pair("account", pwalletMain->mapAddressBook[address].name));
             }
 
             if (scriptPubKey.IsPayToScriptHash()) {
                 const CScriptID &hash = boost::get<CScriptID>(address);
                 CScript redeemScript;
                 if (pwalletMain->GetCScript(hash, redeemScript)) {
                     entry.push_back(
                         Pair("redeemScript",
                              HexStr(redeemScript.begin(), redeemScript.end())));
                 }
             }
         }
 
         entry.push_back(Pair("scriptPubKey",
                              HexStr(scriptPubKey.begin(), scriptPubKey.end())));
         entry.push_back(
             Pair("amount", ValueFromAmount(out.tx->tx->vout[out.i].nValue)));
         entry.push_back(Pair("confirmations", out.nDepth));
         entry.push_back(Pair("spendable", out.fSpendable));
         entry.push_back(Pair("solvable", out.fSolvable));
         results.push_back(entry);
     }
 
     return results;
 }
 
 static UniValue fundrawtransaction(const Config &config,
                                    const JSONRPCRequest &request) {
     if (!EnsureWalletIsAvailable(request.fHelp)) {
         return NullUniValue;
     }
 
     if (request.fHelp || request.params.size() < 1 ||
         request.params.size() > 2) {
         throw std::runtime_error(
             "fundrawtransaction \"hexstring\" ( options )\n"
             "\nAdd inputs to a transaction until it has enough in value to "
             "meet its out value.\n"
             "This will not modify existing inputs, and will add at most one "
             "change output to the outputs.\n"
             "No existing outputs will be modified unless "
             "\"subtractFeeFromOutputs\" is specified.\n"
             "Note that inputs which were signed may need to be resigned after "
             "completion since in/outputs have been added.\n"
             "The inputs added will not be signed, use signrawtransaction for "
             "that.\n"
             "Note that all existing inputs must have their previous output "
             "transaction be in the wallet.\n"
             "Note that all inputs selected must be of standard form and P2SH "
             "scripts must be\n"
             "in the wallet using importaddress or addmultisigaddress (to "
             "calculate fees).\n"
             "You can see whether this is the case by checking the \"solvable\" "
             "field in the listunspent output.\n"
             "Only pay-to-pubkey, multisig, and P2SH versions thereof are "
             "currently supported for watch-only\n"
             "\nArguments:\n"
             "1. \"hexstring\"           (string, required) The hex string of "
             "the raw transaction\n"
             "2. options                 (object, optional)\n"
             "   {\n"
             "     \"changeAddress\"          (string, optional, default pool "
             "address) The bitcoin address to receive the change\n"
             "     \"changePosition\"         (numeric, optional, default "
             "random) The index of the change output\n"
             "     \"includeWatching\"        (boolean, optional, default "
             "false) Also select inputs which are watch only\n"
             "     \"lockUnspents\"           (boolean, optional, default "
             "false) Lock selected unspent outputs\n"
             "     \"reserveChangeKey\"       (boolean, optional, default true) "
             "Reserves the change output key from the keypool\n"
             "     \"feeRate\"                (numeric, optional, default not "
             "set: makes wallet determine the fee) Set a specific feerate (" +
             CURRENCY_UNIT +
             " per KB)\n"
             "     \"subtractFeeFromOutputs\" (array, optional) A json array of "
             "integers.\n"
             "                              The fee will be equally deducted "
             "from the amount of each specified output.\n"
             "                              The outputs are specified by their "
             "zero-based index, before any change output is added.\n"
             "                              Those recipients will receive less "
             "bitcoins than you enter in their corresponding amount field.\n"
             "                              If no outputs are specified here, "
             "the sender pays the fee.\n"
             "                                  [vout_index,...]\n"
             "   }\n"
             "                         for backward compatibility: passing in a "
             "true instead of an object will result in "
             "{\"includeWatching\":true}\n"
             "\nResult:\n"
             "{\n"
             "  \"hex\":       \"value\", (string)  The resulting raw "
             "transaction (hex-encoded string)\n"
             "  \"fee\":       n,         (numeric) Fee in " +
             CURRENCY_UNIT + " the resulting transaction pays\n"
                             "  \"changepos\": n          (numeric) The "
                             "position of the added change output, or -1\n"
                             "}\n"
                             "\nExamples:\n"
                             "\nCreate a transaction with no inputs\n" +
             HelpExampleCli("createrawtransaction",
                            "\"[]\" \"{\\\"myaddress\\\":0.01}\"") +
             "\nAdd sufficient unsigned inputs to meet the output value\n" +
             HelpExampleCli("fundrawtransaction", "\"rawtransactionhex\"") +
             "\nSign the transaction\n" +
             HelpExampleCli("signrawtransaction", "\"fundedtransactionhex\"") +
             "\nSend the transaction\n" +
             HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\""));
     }
 
     RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR));
 
     CTxDestination changeAddress = CNoDestination();
     int changePosition = -1;
     bool includeWatching = false;
     bool lockUnspents = false;
     bool reserveChangeKey = true;
     CFeeRate feeRate = CFeeRate(0);
     bool overrideEstimatedFeerate = false;
     UniValue subtractFeeFromOutputs;
     std::set<int> setSubtractFeeFromOutputs;
 
     if (request.params.size() > 1) {
         if (request.params[1].type() == UniValue::VBOOL) {
             // backward compatibility bool only fallback
             includeWatching = request.params[1].get_bool();
         } else {
             RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR)(
                                              UniValue::VOBJ));
 
             UniValue options = request.params[1];
 
             RPCTypeCheckObj(
                 options,
                 {
                     {"changeAddress", UniValueType(UniValue::VSTR)},
                     {"changePosition", UniValueType(UniValue::VNUM)},
                     {"includeWatching", UniValueType(UniValue::VBOOL)},
                     {"lockUnspents", UniValueType(UniValue::VBOOL)},
                     {"reserveChangeKey", UniValueType(UniValue::VBOOL)},
                     {"feeRate", UniValueType()}, // will be checked below
                     {"subtractFeeFromOutputs", UniValueType(UniValue::VARR)},
                 },
                 true, true);
 
             if (options.exists("changeAddress")) {
                 CBitcoinAddress address(options["changeAddress"].get_str());
 
                 if (!address.IsValid()) {
                     throw JSONRPCError(
                         RPC_INVALID_PARAMETER,
                         "changeAddress must be a valid bitcoin address");
                 }
 
                 changeAddress = address.Get();
             }
 
             if (options.exists("changePosition")) {
                 changePosition = options["changePosition"].get_int();
             }
 
             if (options.exists("includeWatching")) {
                 includeWatching = options["includeWatching"].get_bool();
             }
 
             if (options.exists("lockUnspents")) {
                 lockUnspents = options["lockUnspents"].get_bool();
             }
 
             if (options.exists("reserveChangeKey")) {
                 reserveChangeKey = options["reserveChangeKey"].get_bool();
             }
 
             if (options.exists("feeRate")) {
                 feeRate = CFeeRate(AmountFromValue(options["feeRate"]));
                 overrideEstimatedFeerate = true;
             }
 
             if (options.exists("subtractFeeFromOutputs")) {
                 subtractFeeFromOutputs =
                     options["subtractFeeFromOutputs"].get_array();
             }
         }
     }
 
     // parse hex string from parameter
     CMutableTransaction tx;
     if (!DecodeHexTx(tx, request.params[0].get_str())) {
         throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
     }
 
     if (tx.vout.size() == 0) {
         throw JSONRPCError(RPC_INVALID_PARAMETER,
                            "TX must have at least one output");
     }
 
     if (changePosition != -1 &&
         (changePosition < 0 || (unsigned int)changePosition > tx.vout.size())) {
         throw JSONRPCError(RPC_INVALID_PARAMETER,
                            "changePosition out of bounds");
     }
 
     for (size_t idx = 0; idx < subtractFeeFromOutputs.size(); idx++) {
         int pos = subtractFeeFromOutputs[idx].get_int();
         if (setSubtractFeeFromOutputs.count(pos)) {
             throw JSONRPCError(
                 RPC_INVALID_PARAMETER,
                 strprintf("Invalid parameter, duplicated position: %d", pos));
         }
         if (pos < 0) {
             throw JSONRPCError(
                 RPC_INVALID_PARAMETER,
                 strprintf("Invalid parameter, negative position: %d", pos));
         }
         if (pos >= int(tx.vout.size())) {
             throw JSONRPCError(
                 RPC_INVALID_PARAMETER,
                 strprintf("Invalid parameter, position too large: %d", pos));
         }
         setSubtractFeeFromOutputs.insert(pos);
     }
 
     CAmount nFeeOut;
     std::string strFailReason;
 
     if (!pwalletMain->FundTransaction(
             tx, nFeeOut, overrideEstimatedFeerate, feeRate, changePosition,
             strFailReason, includeWatching, lockUnspents,
             setSubtractFeeFromOutputs, reserveChangeKey, changeAddress)) {
         throw JSONRPCError(RPC_INTERNAL_ERROR, strFailReason);
     }
 
     UniValue result(UniValue::VOBJ);
     result.push_back(Pair("hex", EncodeHexTx(tx)));
     result.push_back(Pair("changepos", changePosition));
     result.push_back(Pair("fee", ValueFromAmount(nFeeOut)));
 
     return result;
 }
 
 // clang-format off
 static const CRPCCommand commands[] = {
     //  category            name                        actor (function)          okSafeMode
     //  ------------------- ------------------------    ----------------------    ----------
     { "rawtransactions",    "fundrawtransaction",       fundrawtransaction,       false,  {"hexstring","options"} },
     { "hidden",             "resendwallettransactions", resendwallettransactions, true,   {} },
     { "wallet",             "abandontransaction",       abandontransaction,       false,  {"txid"} },
     { "wallet",             "addmultisigaddress",       addmultisigaddress,       true,   {"nrequired","keys","account"} },
     { "wallet",             "backupwallet",             backupwallet,             true,   {"destination"} },
     { "wallet",             "encryptwallet",            encryptwallet,            true,   {"passphrase"} },
     { "wallet",             "getaccountaddress",        getaccountaddress,        true,   {"account"} },
     { "wallet",             "getaccount",               getaccount,               true,   {"address"} },
     { "wallet",             "getaddressesbyaccount",    getaddressesbyaccount,    true,   {"account"} },
     { "wallet",             "getbalance",               getbalance,               false,  {"account","minconf","include_watchonly"} },
     { "wallet",             "getnewaddress",            getnewaddress,            true,   {"account"} },
     { "wallet",             "getrawchangeaddress",      getrawchangeaddress,      true,   {} },
     { "wallet",             "getreceivedbyaccount",     getreceivedbyaccount,     false,  {"account","minconf"} },
     { "wallet",             "getreceivedbyaddress",     getreceivedbyaddress,     false,  {"address","minconf"} },
     { "wallet",             "gettransaction",           gettransaction,           false,  {"txid","include_watchonly"} },
     { "wallet",             "getunconfirmedbalance",    getunconfirmedbalance,    false,  {} },
     { "wallet",             "getwalletinfo",            getwalletinfo,            false,  {} },
     { "wallet",             "keypoolrefill",            keypoolrefill,            true,   {"newsize"} },
     { "wallet",             "listaccounts",             listaccounts,             false,  {"minconf","include_watchonly"} },
     { "wallet",             "listaddressgroupings",     listaddressgroupings,     false,  {} },
     { "wallet",             "listlockunspent",          listlockunspent,          false,  {} },
     { "wallet",             "listreceivedbyaccount",    listreceivedbyaccount,    false,  {"minconf","include_empty","include_watchonly"} },
     { "wallet",             "listreceivedbyaddress",    listreceivedbyaddress,    false,  {"minconf","include_empty","include_watchonly"} },
     { "wallet",             "listsinceblock",           listsinceblock,           false,  {"blockhash","target_confirmations","include_watchonly"} },
     { "wallet",             "listtransactions",         listtransactions,         false,  {"account","count","skip","include_watchonly"} },
     { "wallet",             "listunspent",              listunspent,              false,  {"minconf","maxconf","addresses","include_unsafe"} },
     { "wallet",             "lockunspent",              lockunspent,              true,   {"unlock","transactions"} },
     { "wallet",             "move",                     movecmd,                  false,  {"fromaccount","toaccount","amount","minconf","comment"} },
     { "wallet",             "sendfrom",                 sendfrom,                 false,  {"fromaccount","toaddress","amount","minconf","comment","comment_to"} },
     { "wallet",             "sendmany",                 sendmany,                 false,  {"fromaccount","amounts","minconf","comment","subtractfeefrom"} },
     { "wallet",             "sendtoaddress",            sendtoaddress,            false,  {"address","amount","comment","comment_to","subtractfeefromamount"} },
     { "wallet",             "setaccount",               setaccount,               true,   {"address","account"} },
     { "wallet",             "settxfee",                 settxfee,                 true,   {"amount"} },
     { "wallet",             "signmessage",              signmessage,              true,   {"address","message"} },
     { "wallet",             "walletlock",               walletlock,               true,   {} },
     { "wallet",             "walletpassphrasechange",   walletpassphrasechange,   true,   {"oldpassphrase","newpassphrase"} },
     { "wallet",             "walletpassphrase",         walletpassphrase,         true,   {"passphrase","timeout"} },
 };
 // clang-format on
 
 void RegisterWalletRPCCommands(CRPCTable &t) {
     if (GetBoolArg("-disablewallet", false)) {
         return;
     }
 
     for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) {
         t.appendCommand(commands[vcidx].name, &commands[vcidx]);
     }
 }
diff --git a/src/wallet/test/crypto_tests.cpp b/src/wallet/test/crypto_tests.cpp
index 38e77ff51..879e540c1 100644
--- a/src/wallet/test/crypto_tests.cpp
+++ b/src/wallet/test/crypto_tests.cpp
@@ -1,300 +1,294 @@
 // Copyright (c) 2014-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.
 
 #include "test/test_bitcoin.h"
 #include "test/test_random.h"
 #include "utilstrencodings.h"
 #include "wallet/crypter.h"
 
 #include <vector>
 
 #include <boost/test/unit_test.hpp>
 #include <openssl/aes.h>
 #include <openssl/evp.h>
 
 BOOST_FIXTURE_TEST_SUITE(wallet_crypto, BasicTestingSetup)
 
 bool OldSetKeyFromPassphrase(const SecureString &strKeyData,
-                             const std::vector<unsigned char> &chSalt,
+                             const std::vector<uint8_t> &chSalt,
                              const unsigned int nRounds,
                              const unsigned int nDerivationMethod,
-                             unsigned char *chKey, unsigned char *chIV) {
+                             uint8_t *chKey, uint8_t *chIV) {
     if (nRounds < 1 || chSalt.size() != WALLET_CRYPTO_SALT_SIZE) return false;
 
     int i = 0;
     if (nDerivationMethod == 0)
         i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha512(), &chSalt[0],
-                           (unsigned char *)&strKeyData[0], strKeyData.size(),
+                           (uint8_t *)&strKeyData[0], strKeyData.size(),
                            nRounds, chKey, chIV);
 
     if (i != (int)WALLET_CRYPTO_KEY_SIZE) {
         memory_cleanse(chKey, sizeof(chKey));
         memory_cleanse(chIV, sizeof(chIV));
         return false;
     }
     return true;
 }
 
 bool OldEncrypt(const CKeyingMaterial &vchPlaintext,
-                std::vector<unsigned char> &vchCiphertext,
-                const unsigned char chKey[32], const unsigned char chIV[16]) {
+                std::vector<uint8_t> &vchCiphertext, const uint8_t chKey[32],
+                const uint8_t chIV[16]) {
     // max ciphertext len for a n bytes of plaintext is
     // n + AES_BLOCK_SIZE - 1 bytes
     int nLen = vchPlaintext.size();
     int nCLen = nLen + AES_BLOCK_SIZE, nFLen = 0;
-    vchCiphertext = std::vector<unsigned char>(nCLen);
+    vchCiphertext = std::vector<uint8_t>(nCLen);
 
     EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
 
     if (!ctx) return false;
 
     bool fOk = true;
 
     EVP_CIPHER_CTX_init(ctx);
     if (fOk)
         fOk = EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, chKey,
                                  chIV) != 0;
     if (fOk)
         fOk = EVP_EncryptUpdate(ctx, &vchCiphertext[0], &nCLen,
                                 &vchPlaintext[0], nLen) != 0;
     if (fOk)
         fOk =
             EVP_EncryptFinal_ex(ctx, (&vchCiphertext[0]) + nCLen, &nFLen) != 0;
     EVP_CIPHER_CTX_cleanup(ctx);
 
     EVP_CIPHER_CTX_free(ctx);
 
     if (!fOk) return false;
 
     vchCiphertext.resize(nCLen + nFLen);
     return true;
 }
 
-bool OldDecrypt(const std::vector<unsigned char> &vchCiphertext,
-                CKeyingMaterial &vchPlaintext, const unsigned char chKey[32],
-                const unsigned char chIV[16]) {
+bool OldDecrypt(const std::vector<uint8_t> &vchCiphertext,
+                CKeyingMaterial &vchPlaintext, const uint8_t chKey[32],
+                const uint8_t chIV[16]) {
     // plaintext will always be equal to or lesser than length of ciphertext
     int nLen = vchCiphertext.size();
     int nPLen = nLen, nFLen = 0;
 
     vchPlaintext = CKeyingMaterial(nPLen);
 
     EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
 
     if (!ctx) return false;
 
     bool fOk = true;
 
     EVP_CIPHER_CTX_init(ctx);
     if (fOk)
         fOk = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, chKey,
                                  chIV) != 0;
     if (fOk)
         fOk = EVP_DecryptUpdate(ctx, &vchPlaintext[0], &nPLen,
                                 &vchCiphertext[0], nLen) != 0;
     if (fOk)
         fOk = EVP_DecryptFinal_ex(ctx, (&vchPlaintext[0]) + nPLen, &nFLen) != 0;
     EVP_CIPHER_CTX_cleanup(ctx);
 
     EVP_CIPHER_CTX_free(ctx);
 
     if (!fOk) return false;
 
     vchPlaintext.resize(nPLen + nFLen);
     return true;
 }
 
 class TestCrypter {
 public:
-    static void
-    TestPassphraseSingle(const std::vector<unsigned char> &vchSalt,
-                         const SecureString &passphrase, uint32_t rounds,
-                         const std::vector<unsigned char> &correctKey =
-                             std::vector<unsigned char>(),
-                         const std::vector<unsigned char> &correctIV =
-                             std::vector<unsigned char>()) {
-        unsigned char chKey[WALLET_CRYPTO_KEY_SIZE];
-        unsigned char chIV[WALLET_CRYPTO_IV_SIZE];
+    static void TestPassphraseSingle(
+        const std::vector<uint8_t> &vchSalt, const SecureString &passphrase,
+        uint32_t rounds,
+        const std::vector<uint8_t> &correctKey = std::vector<uint8_t>(),
+        const std::vector<uint8_t> &correctIV = std::vector<uint8_t>()) {
+        uint8_t chKey[WALLET_CRYPTO_KEY_SIZE];
+        uint8_t chIV[WALLET_CRYPTO_IV_SIZE];
 
         CCrypter crypt;
         crypt.SetKeyFromPassphrase(passphrase, vchSalt, rounds, 0);
 
         OldSetKeyFromPassphrase(passphrase, vchSalt, rounds, 0, chKey, chIV);
 
         BOOST_CHECK_MESSAGE(
             memcmp(chKey, crypt.vchKey.data(), crypt.vchKey.size()) == 0,
             HexStr(chKey, chKey + sizeof(chKey)) + std::string(" != ") +
                 HexStr(crypt.vchKey));
         BOOST_CHECK_MESSAGE(
             memcmp(chIV, crypt.vchIV.data(), crypt.vchIV.size()) == 0,
             HexStr(chIV, chIV + sizeof(chIV)) + std::string(" != ") +
                 HexStr(crypt.vchIV));
 
         if (!correctKey.empty())
             BOOST_CHECK_MESSAGE(
                 memcmp(chKey, &correctKey[0], sizeof(chKey)) == 0,
                 HexStr(chKey, chKey + sizeof(chKey)) + std::string(" != ") +
                     HexStr(correctKey.begin(), correctKey.end()));
         if (!correctIV.empty())
             BOOST_CHECK_MESSAGE(memcmp(chIV, &correctIV[0], sizeof(chIV)) == 0,
                                 HexStr(chIV, chIV + sizeof(chIV)) +
                                     std::string(" != ") +
                                     HexStr(correctIV.begin(), correctIV.end()));
     }
 
-    static void TestPassphrase(const std::vector<unsigned char> &vchSalt,
-                               const SecureString &passphrase, uint32_t rounds,
-                               const std::vector<unsigned char> &correctKey =
-                                   std::vector<unsigned char>(),
-                               const std::vector<unsigned char> &correctIV =
-                                   std::vector<unsigned char>()) {
+    static void TestPassphrase(
+        const std::vector<uint8_t> &vchSalt, const SecureString &passphrase,
+        uint32_t rounds,
+        const std::vector<uint8_t> &correctKey = std::vector<uint8_t>(),
+        const std::vector<uint8_t> &correctIV = std::vector<uint8_t>()) {
         TestPassphraseSingle(vchSalt, passphrase, rounds, correctKey,
                              correctIV);
         for (SecureString::const_iterator i(passphrase.begin());
              i != passphrase.end(); ++i)
             TestPassphraseSingle(vchSalt, SecureString(i, passphrase.end()),
                                  rounds);
     }
 
-    static void TestDecrypt(const CCrypter &crypt,
-                            const std::vector<unsigned char> &vchCiphertext,
-                            const std::vector<unsigned char> &vchPlaintext =
-                                std::vector<unsigned char>()) {
+    static void TestDecrypt(
+        const CCrypter &crypt, const std::vector<uint8_t> &vchCiphertext,
+        const std::vector<uint8_t> &vchPlaintext = std::vector<uint8_t>()) {
         CKeyingMaterial vchDecrypted1;
         CKeyingMaterial vchDecrypted2;
         int result1, result2;
         result1 = crypt.Decrypt(vchCiphertext, vchDecrypted1);
         result2 = OldDecrypt(vchCiphertext, vchDecrypted2, crypt.vchKey.data(),
                              crypt.vchIV.data());
         BOOST_CHECK(result1 == result2);
 
         // These two should be equal. However, OpenSSL 1.0.1j introduced a
         // change that would zero all padding except for the last byte for
         // failed decrypts.
         // This behavior was reverted for 1.0.1k.
         if (vchDecrypted1 != vchDecrypted2 &&
             vchDecrypted1.size() >= AES_BLOCK_SIZE && SSLeay() == 0x100010afL) {
             for (CKeyingMaterial::iterator it =
                      vchDecrypted1.end() - AES_BLOCK_SIZE;
                  it != vchDecrypted1.end() - 1; it++)
                 *it = 0;
         }
 
         BOOST_CHECK_MESSAGE(
             vchDecrypted1 == vchDecrypted2,
             HexStr(vchDecrypted1.begin(), vchDecrypted1.end()) + " != " +
                 HexStr(vchDecrypted2.begin(), vchDecrypted2.end()));
 
         if (vchPlaintext.size())
             BOOST_CHECK(CKeyingMaterial(vchPlaintext.begin(),
                                         vchPlaintext.end()) == vchDecrypted2);
     }
 
     static void
     TestEncryptSingle(const CCrypter &crypt,
                       const CKeyingMaterial &vchPlaintext,
-                      const std::vector<unsigned char> &vchCiphertextCorrect =
-                          std::vector<unsigned char>()) {
-        std::vector<unsigned char> vchCiphertext1;
-        std::vector<unsigned char> vchCiphertext2;
+                      const std::vector<uint8_t> &vchCiphertextCorrect =
+                          std::vector<uint8_t>()) {
+        std::vector<uint8_t> vchCiphertext1;
+        std::vector<uint8_t> vchCiphertext2;
         int result1 = crypt.Encrypt(vchPlaintext, vchCiphertext1);
 
         int result2 = OldEncrypt(vchPlaintext, vchCiphertext2,
                                  crypt.vchKey.data(), crypt.vchIV.data());
         BOOST_CHECK(result1 == result2);
         BOOST_CHECK(vchCiphertext1 == vchCiphertext2);
 
         if (!vchCiphertextCorrect.empty())
             BOOST_CHECK(vchCiphertext2 == vchCiphertextCorrect);
 
-        const std::vector<unsigned char> vchPlaintext2(vchPlaintext.begin(),
-                                                       vchPlaintext.end());
+        const std::vector<uint8_t> vchPlaintext2(vchPlaintext.begin(),
+                                                 vchPlaintext.end());
 
         if (vchCiphertext1 == vchCiphertext2)
             TestDecrypt(crypt, vchCiphertext1, vchPlaintext2);
     }
 
-    static void
-    TestEncrypt(const CCrypter &crypt,
-                const std::vector<unsigned char> &vchPlaintextIn,
-                const std::vector<unsigned char> &vchCiphertextCorrect =
-                    std::vector<unsigned char>()) {
+    static void TestEncrypt(const CCrypter &crypt,
+                            const std::vector<uint8_t> &vchPlaintextIn,
+                            const std::vector<uint8_t> &vchCiphertextCorrect =
+                                std::vector<uint8_t>()) {
         TestEncryptSingle(crypt, CKeyingMaterial(vchPlaintextIn.begin(),
                                                  vchPlaintextIn.end()),
                           vchCiphertextCorrect);
-        for (std::vector<unsigned char>::const_iterator i(
-                 vchPlaintextIn.begin());
+        for (std::vector<uint8_t>::const_iterator i(vchPlaintextIn.begin());
              i != vchPlaintextIn.end(); ++i)
             TestEncryptSingle(crypt, CKeyingMaterial(i, vchPlaintextIn.end()));
     }
 };
 
 BOOST_AUTO_TEST_CASE(passphrase) {
     // These are expensive.
 
     TestCrypter::TestPassphrase(
         ParseHex("0000deadbeef0000"), "test", 25000,
         ParseHex(
             "fc7aba077ad5f4c3a0988d8daa4810d0d4a0e3bcb53af662998898f33df0556a"),
         ParseHex("cf2f2691526dd1aa220896fb8bf7c369"));
 
     std::string hash(GetRandHash().ToString());
-    std::vector<unsigned char> vchSalt(8);
+    std::vector<uint8_t> vchSalt(8);
     GetRandBytes(&vchSalt[0], vchSalt.size());
     uint32_t rounds = insecure_rand();
     if (rounds > 30000) rounds = 30000;
     TestCrypter::TestPassphrase(vchSalt, SecureString(hash.begin(), hash.end()),
                                 rounds);
 }
 
 BOOST_AUTO_TEST_CASE(encrypt) {
-    std::vector<unsigned char> vchSalt = ParseHex("0000deadbeef0000");
+    std::vector<uint8_t> vchSalt = ParseHex("0000deadbeef0000");
     BOOST_CHECK(vchSalt.size() == WALLET_CRYPTO_SALT_SIZE);
     CCrypter crypt;
     crypt.SetKeyFromPassphrase("passphrase", vchSalt, 25000, 0);
     TestCrypter::TestEncrypt(crypt,
                              ParseHex("22bcade09ac03ff6386914359cfe885cfeb5f77f"
                                       "f0d670f102f619687453b29d"));
 
     for (int i = 0; i != 100; i++) {
         uint256 hash(GetRandHash());
         TestCrypter::TestEncrypt(
-            crypt, std::vector<unsigned char>(hash.begin(), hash.end()));
+            crypt, std::vector<uint8_t>(hash.begin(), hash.end()));
     }
 }
 
 BOOST_AUTO_TEST_CASE(decrypt) {
-    std::vector<unsigned char> vchSalt = ParseHex("0000deadbeef0000");
+    std::vector<uint8_t> vchSalt = ParseHex("0000deadbeef0000");
     BOOST_CHECK(vchSalt.size() == WALLET_CRYPTO_SALT_SIZE);
     CCrypter crypt;
     crypt.SetKeyFromPassphrase("passphrase", vchSalt, 25000, 0);
 
     // Some corner cases the came up while testing
     TestCrypter::TestDecrypt(crypt,
                              ParseHex("795643ce39d736088367822cdc50535ec6f10371"
                                       "5e3e48f4f3b1a60a08ef59ca"));
     TestCrypter::TestDecrypt(crypt,
                              ParseHex("de096f4a8f9bd97db012aa9d90d74de8cdea779c"
                                       "3ee8bc7633d8b5d6da703486"));
     TestCrypter::TestDecrypt(crypt,
                              ParseHex("32d0a8974e3afd9c6c3ebf4d66aa4e6419f8c173"
                                       "de25947f98cf8b7ace49449c"));
     TestCrypter::TestDecrypt(crypt,
                              ParseHex("e7c055cca2faa78cb9ac22c9357a90b4778ded9b"
                                       "2cc220a14cea49f931e596ea"));
     TestCrypter::TestDecrypt(crypt,
                              ParseHex("b88efddd668a6801d19516d6830da4ae9811988c"
                                       "cbaf40df8fbb72f3f4d335fd"));
     TestCrypter::TestDecrypt(crypt,
                              ParseHex("8cae76aa6a43694e961ebcb28c8ca8f8540b8415"
                                       "3d72865e8561ddd93fa7bfa9"));
 
     for (int i = 0; i != 100; i++) {
         uint256 hash(GetRandHash());
         TestCrypter::TestDecrypt(
-            crypt, std::vector<unsigned char>(hash.begin(), hash.end()));
+            crypt, std::vector<uint8_t>(hash.begin(), hash.end()));
     }
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index b567ed537..ceef78e9b 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -1,4485 +1,4483 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #include "wallet/wallet.h"
 
 #include "base58.h"
 #include "chain.h"
 #include "checkpoints.h"
 #include "config.h"
 #include "consensus/consensus.h"
 #include "consensus/validation.h"
 #include "key.h"
 #include "keystore.h"
 #include "net.h"
 #include "policy/policy.h"
 #include "primitives/block.h"
 #include "primitives/transaction.h"
 #include "script/script.h"
 #include "script/sign.h"
 #include "timedata.h"
 #include "txmempool.h"
 #include "ui_interface.h"
 #include "util.h"
 #include "utilmoneystr.h"
 #include "validation.h"
 #include "wallet/coincontrol.h"
 #include "wallet/finaltx.h"
 
 #include <cassert>
 
 #include <boost/algorithm/string/replace.hpp>
 #include <boost/filesystem.hpp>
 #include <boost/thread.hpp>
 
 CWallet *pwalletMain = nullptr;
 
 /** Transaction fee set by the user */
 CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE);
 unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET;
 bool bSpendZeroConfChange = DEFAULT_SPEND_ZEROCONF_CHANGE;
 bool fSendFreeTransactions = DEFAULT_SEND_FREE_TRANSACTIONS;
 
 const char *DEFAULT_WALLET_DAT = "wallet.dat";
 const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000;
 
 /**
  * Fees smaller than this (in satoshi) are considered zero fee (for transaction
  * creation)
  * Override with -mintxfee
  */
 CFeeRate CWallet::minTxFee = CFeeRate(DEFAULT_TRANSACTION_MINFEE);
 
 /**
  * If fee estimation does not have enough data to provide estimates, use this
  * fee instead. Has no effect if not using fee estimation.
  * Override with -fallbackfee
  */
 CFeeRate CWallet::fallbackFee = CFeeRate(DEFAULT_FALLBACK_FEE);
 
 const uint256 CMerkleTx::ABANDON_HASH(uint256S(
     "0000000000000000000000000000000000000000000000000000000000000001"));
 
 /** @defgroup mapWallet
  *
  * @{
  */
 
 struct CompareValueOnly {
     bool operator()(
         const std::pair<CAmount, std::pair<const CWalletTx *, unsigned int>>
             &t1,
         const std::pair<CAmount, std::pair<const CWalletTx *, unsigned int>>
             &t2) const {
         return t1.first < t2.first;
     }
 };
 
 std::string COutput::ToString() const {
     return strprintf("COutput(%s, %d, %d) [%s]", tx->GetId().ToString(), i,
                      nDepth, FormatMoney(tx->tx->vout[i].nValue));
 }
 
 const CWalletTx *CWallet::GetWalletTx(const uint256 &hash) const {
     LOCK(cs_wallet);
     std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(hash);
     if (it == mapWallet.end()) {
         return nullptr;
     }
 
     return &(it->second);
 }
 
 CPubKey CWallet::GenerateNewKey() {
     // mapKeyMetadata
     AssertLockHeld(cs_wallet);
     // default to compressed public keys if we want 0.6.0 wallets
     bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY);
 
     CKey secret;
 
     // Create new metadata
     int64_t nCreationTime = GetTime();
     CKeyMetadata metadata(nCreationTime);
 
     // use HD key derivation if HD was enabled during wallet creation
     if (IsHDEnabled()) {
         DeriveNewChildKey(metadata, secret);
     } else {
         secret.MakeNewKey(fCompressed);
     }
 
     // Compressed public keys were introduced in version 0.6.0
     if (fCompressed) {
         SetMinVersion(FEATURE_COMPRPUBKEY);
     }
 
     CPubKey pubkey = secret.GetPubKey();
     assert(secret.VerifyPubKey(pubkey));
 
     mapKeyMetadata[pubkey.GetID()] = metadata;
     UpdateTimeFirstKey(nCreationTime);
 
     if (!AddKeyPubKey(secret, pubkey)) {
         throw std::runtime_error(std::string(__func__) + ": AddKey failed");
     }
 
     return pubkey;
 }
 
 void CWallet::DeriveNewChildKey(CKeyMetadata &metadata, CKey &secret) {
     // for now we use a fixed keypath scheme of m/0'/0'/k
     // master key seed (256bit)
     CKey key;
     // hd master key
     CExtKey masterKey;
     // key at m/0'
     CExtKey accountKey;
     // key at m/0'/0'
     CExtKey externalChainChildKey;
     // key at m/0'/0'/<n>'
     CExtKey childKey;
 
     // try to get the master key
     if (!GetKey(hdChain.masterKeyID, key)) {
         throw std::runtime_error(std::string(__func__) +
                                  ": Master key not found");
     }
 
     masterKey.SetMaster(key.begin(), key.size());
 
     // derive m/0'
     // use hardened derivation (child keys >= 0x80000000 are hardened after
     // bip32)
     masterKey.Derive(accountKey, BIP32_HARDENED_KEY_LIMIT);
 
     // derive m/0'/0'
     accountKey.Derive(externalChainChildKey, BIP32_HARDENED_KEY_LIMIT);
 
     // derive child key at next index, skip keys already known to the wallet
     do {
         // always derive hardened keys
         // childIndex | BIP32_HARDENED_KEY_LIMIT = derive childIndex in hardened
         // child-index-range
         // example: 1 | BIP32_HARDENED_KEY_LIMIT == 0x80000001 == 2147483649
         externalChainChildKey.Derive(childKey, hdChain.nExternalChainCounter |
                                                    BIP32_HARDENED_KEY_LIMIT);
         metadata.hdKeypath =
             "m/0'/0'/" + std::to_string(hdChain.nExternalChainCounter) + "'";
         metadata.hdMasterKeyID = hdChain.masterKeyID;
         // increment childkey index
         hdChain.nExternalChainCounter++;
     } while (HaveKey(childKey.key.GetPubKey().GetID()));
     secret = childKey.key;
 
     // update the chain model in the database
     if (!CWalletDB(strWalletFile).WriteHDChain(hdChain)) {
         throw std::runtime_error(std::string(__func__) +
                                  ": Writing HD chain model failed");
     }
 }
 
 bool CWallet::AddKeyPubKey(const CKey &secret, const CPubKey &pubkey) {
     // mapKeyMetadata
     AssertLockHeld(cs_wallet);
     if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey)) {
         return false;
     }
 
     // Check if we need to remove from watch-only.
     CScript script;
     script = GetScriptForDestination(pubkey.GetID());
     if (HaveWatchOnly(script)) {
         RemoveWatchOnly(script);
     }
 
     script = GetScriptForRawPubKey(pubkey);
     if (HaveWatchOnly(script)) {
         RemoveWatchOnly(script);
     }
 
     if (!fFileBacked) {
         return true;
     }
 
     if (IsCrypted()) {
         return true;
     }
 
     return CWalletDB(strWalletFile)
         .WriteKey(pubkey, secret.GetPrivKey(), mapKeyMetadata[pubkey.GetID()]);
 }
 
-bool CWallet::AddCryptedKey(
-    const CPubKey &vchPubKey,
-    const std::vector<unsigned char> &vchCryptedSecret) {
+bool CWallet::AddCryptedKey(const CPubKey &vchPubKey,
+                            const std::vector<uint8_t> &vchCryptedSecret) {
     if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret)) {
         return false;
     }
 
     if (!fFileBacked) {
         return true;
     }
 
     LOCK(cs_wallet);
     if (pwalletdbEncryption) {
         return pwalletdbEncryption->WriteCryptedKey(
             vchPubKey, vchCryptedSecret, mapKeyMetadata[vchPubKey.GetID()]);
     }
 
     return CWalletDB(strWalletFile)
         .WriteCryptedKey(vchPubKey, vchCryptedSecret,
                          mapKeyMetadata[vchPubKey.GetID()]);
 }
 
 bool CWallet::LoadKeyMetadata(const CTxDestination &keyID,
                               const CKeyMetadata &meta) {
     // mapKeyMetadata
     AssertLockHeld(cs_wallet);
     UpdateTimeFirstKey(meta.nCreateTime);
     mapKeyMetadata[keyID] = meta;
     return true;
 }
 
-bool CWallet::LoadCryptedKey(
-    const CPubKey &vchPubKey,
-    const std::vector<unsigned char> &vchCryptedSecret) {
+bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey,
+                             const std::vector<uint8_t> &vchCryptedSecret) {
     return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret);
 }
 
 void CWallet::UpdateTimeFirstKey(int64_t nCreateTime) {
     AssertLockHeld(cs_wallet);
     if (nCreateTime <= 1) {
         // Cannot determine birthday information, so set the wallet birthday to
         // the beginning of time.
         nTimeFirstKey = 1;
     } else if (!nTimeFirstKey || nCreateTime < nTimeFirstKey) {
         nTimeFirstKey = nCreateTime;
     }
 }
 
 bool CWallet::AddCScript(const CScript &redeemScript) {
     if (!CCryptoKeyStore::AddCScript(redeemScript)) {
         return false;
     }
 
     if (!fFileBacked) {
         return true;
     }
 
     return CWalletDB(strWalletFile)
         .WriteCScript(Hash160(redeemScript), redeemScript);
 }
 
 bool CWallet::LoadCScript(const CScript &redeemScript) {
     /**
      * A sanity check was added in pull #3843 to avoid adding redeemScripts that
      * never can be redeemed. However, old wallets may still contain these. Do
      * not add them to the wallet and warn.
      */
     if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE) {
         std::string strAddr =
             CBitcoinAddress(CScriptID(redeemScript)).ToString();
         LogPrintf("%s: Warning: This wallet contains a redeemScript of size %i "
                   "which exceeds maximum size %i thus can never be redeemed. "
                   "Do not use address %s.\n",
                   __func__, redeemScript.size(), MAX_SCRIPT_ELEMENT_SIZE,
                   strAddr);
         return true;
     }
 
     return CCryptoKeyStore::AddCScript(redeemScript);
 }
 
 bool CWallet::AddWatchOnly(const CScript &dest) {
     if (!CCryptoKeyStore::AddWatchOnly(dest)) {
         return false;
     }
 
     const CKeyMetadata &meta = mapKeyMetadata[CScriptID(dest)];
     UpdateTimeFirstKey(meta.nCreateTime);
     NotifyWatchonlyChanged(true);
 
     if (!fFileBacked) {
         return true;
     }
 
     return CWalletDB(strWalletFile).WriteWatchOnly(dest, meta);
 }
 
 bool CWallet::AddWatchOnly(const CScript &dest, int64_t nCreateTime) {
     mapKeyMetadata[CScriptID(dest)].nCreateTime = nCreateTime;
     return AddWatchOnly(dest);
 }
 
 bool CWallet::RemoveWatchOnly(const CScript &dest) {
     AssertLockHeld(cs_wallet);
     if (!CCryptoKeyStore::RemoveWatchOnly(dest)) {
         return false;
     }
 
     if (!HaveWatchOnly()) {
         NotifyWatchonlyChanged(false);
     }
 
     if (fFileBacked && !CWalletDB(strWalletFile).EraseWatchOnly(dest)) {
         return false;
     }
 
     return true;
 }
 
 bool CWallet::LoadWatchOnly(const CScript &dest) {
     return CCryptoKeyStore::AddWatchOnly(dest);
 }
 
 bool CWallet::Unlock(const SecureString &strWalletPassphrase) {
     CCrypter crypter;
     CKeyingMaterial vMasterKey;
 
     LOCK(cs_wallet);
     for (const MasterKeyMap::value_type &pMasterKey : mapMasterKeys) {
         if (!crypter.SetKeyFromPassphrase(
                 strWalletPassphrase, pMasterKey.second.vchSalt,
                 pMasterKey.second.nDeriveIterations,
                 pMasterKey.second.nDerivationMethod)) {
             return false;
         }
 
         if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey)) {
             // try another master key
             continue;
         }
 
         if (CCryptoKeyStore::Unlock(vMasterKey)) {
             return true;
         }
     }
 
     return false;
 }
 
 bool CWallet::ChangeWalletPassphrase(
     const SecureString &strOldWalletPassphrase,
     const SecureString &strNewWalletPassphrase) {
     bool fWasLocked = IsLocked();
 
     LOCK(cs_wallet);
     Lock();
 
     CCrypter crypter;
     CKeyingMaterial vMasterKey;
     for (MasterKeyMap::value_type &pMasterKey : mapMasterKeys) {
         if (!crypter.SetKeyFromPassphrase(
                 strOldWalletPassphrase, pMasterKey.second.vchSalt,
                 pMasterKey.second.nDeriveIterations,
                 pMasterKey.second.nDerivationMethod)) {
             return false;
         }
 
         if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey)) {
             return false;
         }
 
         if (CCryptoKeyStore::Unlock(vMasterKey)) {
             int64_t nStartTime = GetTimeMillis();
             crypter.SetKeyFromPassphrase(strNewWalletPassphrase,
                                          pMasterKey.second.vchSalt,
                                          pMasterKey.second.nDeriveIterations,
                                          pMasterKey.second.nDerivationMethod);
             pMasterKey.second.nDeriveIterations =
                 pMasterKey.second.nDeriveIterations *
                 (100 / ((double)(GetTimeMillis() - nStartTime)));
 
             nStartTime = GetTimeMillis();
             crypter.SetKeyFromPassphrase(strNewWalletPassphrase,
                                          pMasterKey.second.vchSalt,
                                          pMasterKey.second.nDeriveIterations,
                                          pMasterKey.second.nDerivationMethod);
             pMasterKey.second.nDeriveIterations =
                 (pMasterKey.second.nDeriveIterations +
                  pMasterKey.second.nDeriveIterations * 100 /
                      double(GetTimeMillis() - nStartTime)) /
                 2;
 
             if (pMasterKey.second.nDeriveIterations < 25000) {
                 pMasterKey.second.nDeriveIterations = 25000;
             }
 
             LogPrintf(
                 "Wallet passphrase changed to an nDeriveIterations of %i\n",
                 pMasterKey.second.nDeriveIterations);
 
             if (!crypter.SetKeyFromPassphrase(
                     strNewWalletPassphrase, pMasterKey.second.vchSalt,
                     pMasterKey.second.nDeriveIterations,
                     pMasterKey.second.nDerivationMethod)) {
                 return false;
             }
 
             if (!crypter.Encrypt(vMasterKey, pMasterKey.second.vchCryptedKey)) {
                 return false;
             }
 
             CWalletDB(strWalletFile)
                 .WriteMasterKey(pMasterKey.first, pMasterKey.second);
             if (fWasLocked) {
                 Lock();
             }
 
             return true;
         }
     }
 
     return false;
 }
 
 void CWallet::SetBestChain(const CBlockLocator &loc) {
     CWalletDB walletdb(strWalletFile);
     walletdb.WriteBestBlock(loc);
 }
 
 bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB *pwalletdbIn,
                             bool fExplicit) {
     // nWalletVersion
     LOCK(cs_wallet);
     if (nWalletVersion >= nVersion) {
         return true;
     }
 
     // When doing an explicit upgrade, if we pass the max version permitted,
     // upgrade all the way.
     if (fExplicit && nVersion > nWalletMaxVersion) {
         nVersion = FEATURE_LATEST;
     }
 
     nWalletVersion = nVersion;
 
     if (nVersion > nWalletMaxVersion) {
         nWalletMaxVersion = nVersion;
     }
 
     if (fFileBacked) {
         CWalletDB *pwalletdb =
             pwalletdbIn ? pwalletdbIn : new CWalletDB(strWalletFile);
         if (nWalletVersion > 40000) {
             pwalletdb->WriteMinVersion(nWalletVersion);
         }
 
         if (!pwalletdbIn) {
             delete pwalletdb;
         }
     }
 
     return true;
 }
 
 bool CWallet::SetMaxVersion(int nVersion) {
     // nWalletVersion, nWalletMaxVersion
     LOCK(cs_wallet);
 
     // Cannot downgrade below current version
     if (nWalletVersion > nVersion) {
         return false;
     }
 
     nWalletMaxVersion = nVersion;
 
     return true;
 }
 
 std::set<uint256> CWallet::GetConflicts(const uint256 &txid) const {
     std::set<uint256> result;
     AssertLockHeld(cs_wallet);
 
     std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(txid);
     if (it == mapWallet.end()) {
         return result;
     }
 
     const CWalletTx &wtx = it->second;
 
     std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
 
     for (const CTxIn &txin : wtx.tx->vin) {
         if (mapTxSpends.count(txin.prevout) <= 1) {
             // No conflict if zero or one spends.
             continue;
         }
 
         range = mapTxSpends.equal_range(txin.prevout);
         for (TxSpends::const_iterator _it = range.first; _it != range.second;
              ++_it) {
             result.insert(_it->second);
         }
     }
 
     return result;
 }
 
 bool CWallet::HasWalletSpend(const uint256 &txid) const {
     AssertLockHeld(cs_wallet);
     auto iter = mapTxSpends.lower_bound(COutPoint(txid, 0));
     return (iter != mapTxSpends.end() && iter->first.hash == txid);
 }
 
 void CWallet::Flush(bool shutdown) {
     bitdb.Flush(shutdown);
 }
 
 bool CWallet::Verify() {
     if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
         return true;
     }
 
     LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0));
     std::string walletFile = GetArg("-wallet", DEFAULT_WALLET_DAT);
 
     LogPrintf("Using wallet %s\n", walletFile);
     uiInterface.InitMessage(_("Verifying wallet..."));
 
     // Wallet file must be a plain filename without a directory.
     if (walletFile !=
         boost::filesystem::basename(walletFile) +
             boost::filesystem::extension(walletFile)) {
         return InitError(
             strprintf(_("Wallet %s resides outside data directory %s"),
                       walletFile, GetDataDir().string()));
     }
 
     if (!bitdb.Open(GetDataDir())) {
         // Try moving the database env out of the way.
         boost::filesystem::path pathDatabase = GetDataDir() / "database";
         boost::filesystem::path pathDatabaseBak =
             GetDataDir() / strprintf("database.%d.bak", GetTime());
         try {
             boost::filesystem::rename(pathDatabase, pathDatabaseBak);
             LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(),
                       pathDatabaseBak.string());
         } catch (const boost::filesystem::filesystem_error &) {
             // Failure is ok (well, not really, but it's not worse than what we
             // started with)
         }
 
         // try again
         if (!bitdb.Open(GetDataDir())) {
             // If it still fails, it probably means we can't even create the
             // database env.
             return InitError(strprintf(
                 _("Error initializing wallet database environment %s!"),
                 GetDataDir()));
         }
     }
 
     if (GetBoolArg("-salvagewallet", false)) {
         // Recover readable keypairs:
         if (!CWalletDB::Recover(bitdb, walletFile, true)) return false;
     }
 
     if (boost::filesystem::exists(GetDataDir() / walletFile)) {
         CDBEnv::VerifyResult r = bitdb.Verify(walletFile, CWalletDB::Recover);
         if (r == CDBEnv::RECOVER_OK) {
             InitWarning(strprintf(
                 _("Warning: Wallet file corrupt, data salvaged!"
                   " Original %s saved as %s in %s; if"
                   " your balance or transactions are incorrect you should"
                   " restore from a backup."),
                 walletFile, "wallet.{timestamp}.bak", GetDataDir()));
         }
 
         if (r == CDBEnv::RECOVER_FAIL) {
             return InitError(
                 strprintf(_("%s corrupt, salvage failed"), walletFile));
         }
     }
 
     return true;
 }
 
 void CWallet::SyncMetaData(
     std::pair<TxSpends::iterator, TxSpends::iterator> range) {
     // We want all the wallet transactions in range to have the same metadata as
     // the oldest (smallest nOrderPos).
     // So: find smallest nOrderPos:
 
     int nMinOrderPos = std::numeric_limits<int>::max();
     const CWalletTx *copyFrom = nullptr;
     for (TxSpends::iterator it = range.first; it != range.second; ++it) {
         const uint256 &hash = it->second;
         int n = mapWallet[hash].nOrderPos;
         if (n < nMinOrderPos) {
             nMinOrderPos = n;
             copyFrom = &mapWallet[hash];
         }
     }
 
     // Now copy data from copyFrom to rest:
     for (TxSpends::iterator it = range.first; it != range.second; ++it) {
         const uint256 &hash = it->second;
         CWalletTx *copyTo = &mapWallet[hash];
         if (copyFrom == copyTo) {
             continue;
         }
 
         if (!copyFrom->IsEquivalentTo(*copyTo)) {
             continue;
         }
 
         copyTo->mapValue = copyFrom->mapValue;
         copyTo->vOrderForm = copyFrom->vOrderForm;
         // fTimeReceivedIsTxTime not copied on purpose nTimeReceived not copied
         // on purpose.
         copyTo->nTimeSmart = copyFrom->nTimeSmart;
         copyTo->fFromMe = copyFrom->fFromMe;
         copyTo->strFromAccount = copyFrom->strFromAccount;
         // nOrderPos not copied on purpose cached members not copied on purpose.
     }
 }
 
 /**
  * Outpoint is spent if any non-conflicted transaction, spends it:
  */
 bool CWallet::IsSpent(const uint256 &hash, unsigned int n) const {
     const COutPoint outpoint(hash, n);
     std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
     range = mapTxSpends.equal_range(outpoint);
 
     for (TxSpends::const_iterator it = range.first; it != range.second; ++it) {
         const uint256 &wtxid = it->second;
         std::map<uint256, CWalletTx>::const_iterator mit =
             mapWallet.find(wtxid);
         if (mit != mapWallet.end()) {
             int depth = mit->second.GetDepthInMainChain();
             if (depth > 0 || (depth == 0 && !mit->second.isAbandoned())) {
                 // Spent
                 return true;
             }
         }
     }
 
     return false;
 }
 
 void CWallet::AddToSpends(const COutPoint &outpoint, const uint256 &wtxid) {
     mapTxSpends.insert(std::make_pair(outpoint, wtxid));
 
     std::pair<TxSpends::iterator, TxSpends::iterator> range;
     range = mapTxSpends.equal_range(outpoint);
     SyncMetaData(range);
 }
 
 void CWallet::AddToSpends(const uint256 &wtxid) {
     assert(mapWallet.count(wtxid));
     CWalletTx &thisTx = mapWallet[wtxid];
     // Coinbases don't spend anything!
     if (thisTx.IsCoinBase()) {
         return;
     }
 
     for (const CTxIn &txin : thisTx.tx->vin) {
         AddToSpends(txin.prevout, wtxid);
     }
 }
 
 bool CWallet::EncryptWallet(const SecureString &strWalletPassphrase) {
     if (IsCrypted()) {
         return false;
     }
 
     CKeyingMaterial vMasterKey;
 
     vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
     GetStrongRandBytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
 
     CMasterKey kMasterKey;
 
     kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
     GetStrongRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
 
     CCrypter crypter;
     int64_t nStartTime = GetTimeMillis();
     crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000,
                                  kMasterKey.nDerivationMethod);
     kMasterKey.nDeriveIterations =
         2500000 / ((double)(GetTimeMillis() - nStartTime));
 
     nStartTime = GetTimeMillis();
     crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt,
                                  kMasterKey.nDeriveIterations,
                                  kMasterKey.nDerivationMethod);
     kMasterKey.nDeriveIterations =
         (kMasterKey.nDeriveIterations +
          kMasterKey.nDeriveIterations * 100 /
              ((double)(GetTimeMillis() - nStartTime))) /
         2;
 
     if (kMasterKey.nDeriveIterations < 25000) {
         kMasterKey.nDeriveIterations = 25000;
     }
 
     LogPrintf("Encrypting Wallet with an nDeriveIterations of %i\n",
               kMasterKey.nDeriveIterations);
 
     if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt,
                                       kMasterKey.nDeriveIterations,
                                       kMasterKey.nDerivationMethod)) {
         return false;
     }
 
     if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey)) {
         return false;
     }
 
     {
         LOCK(cs_wallet);
         mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
         if (fFileBacked) {
             assert(!pwalletdbEncryption);
             pwalletdbEncryption = new CWalletDB(strWalletFile);
             if (!pwalletdbEncryption->TxnBegin()) {
                 delete pwalletdbEncryption;
                 pwalletdbEncryption = nullptr;
                 return false;
             }
 
             pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
         }
 
         if (!EncryptKeys(vMasterKey)) {
             if (fFileBacked) {
                 pwalletdbEncryption->TxnAbort();
                 delete pwalletdbEncryption;
             }
 
             // We now probably have half of our keys encrypted in memory, and
             // half not... die and let the user reload the unencrypted wallet.
             assert(false);
         }
 
         // Encryption was introduced in version 0.4.0
         SetMinVersion(FEATURE_WALLETCRYPT, pwalletdbEncryption, true);
 
         if (fFileBacked) {
             if (!pwalletdbEncryption->TxnCommit()) {
                 delete pwalletdbEncryption;
                 // We now have keys encrypted in memory, but not on disk... die
                 // to avoid confusion and let the user reload the unencrypted
                 // wallet.
                 assert(false);
             }
 
             delete pwalletdbEncryption;
             pwalletdbEncryption = nullptr;
         }
 
         Lock();
         Unlock(strWalletPassphrase);
 
         // If we are using HD, replace the HD master key (seed) with a new one.
         if (IsHDEnabled()) {
             CKey key;
             CPubKey masterPubKey = GenerateNewHDMasterKey();
             if (!SetHDMasterKey(masterPubKey)) {
                 return false;
             }
         }
 
         NewKeyPool();
         Lock();
 
         // Need to completely rewrite the wallet file; if we don't, bdb might
         // keep bits of the unencrypted private key in slack space in the
         // database file.
         CDB::Rewrite(strWalletFile);
     }
 
     NotifyStatusChanged(this);
     return true;
 }
 
 DBErrors CWallet::ReorderTransactions() {
     LOCK(cs_wallet);
     CWalletDB walletdb(strWalletFile);
 
     // Old wallets didn't have any defined order for transactions. Probably a
     // bad idea to change the output of this.
 
     // First: get all CWalletTx and CAccountingEntry into a sorted-by-time
     // multimap.
     typedef std::pair<CWalletTx *, CAccountingEntry *> TxPair;
     typedef std::multimap<int64_t, TxPair> TxItems;
     TxItems txByTime;
 
     for (std::map<uint256, CWalletTx>::iterator it = mapWallet.begin();
          it != mapWallet.end(); ++it) {
         CWalletTx *wtx = &((*it).second);
         txByTime.insert(
             std::make_pair(wtx->nTimeReceived, TxPair(wtx, nullptr)));
     }
 
     std::list<CAccountingEntry> acentries;
     walletdb.ListAccountCreditDebit("", acentries);
     for (CAccountingEntry &entry : acentries) {
         txByTime.insert(std::make_pair(entry.nTime, TxPair(nullptr, &entry)));
     }
 
     nOrderPosNext = 0;
     std::vector<int64_t> nOrderPosOffsets;
     for (TxItems::iterator it = txByTime.begin(); it != txByTime.end(); ++it) {
         CWalletTx *const pwtx = (*it).second.first;
         CAccountingEntry *const pacentry = (*it).second.second;
         int64_t &nOrderPos =
             (pwtx != 0) ? pwtx->nOrderPos : pacentry->nOrderPos;
 
         if (nOrderPos == -1) {
             nOrderPos = nOrderPosNext++;
             nOrderPosOffsets.push_back(nOrderPos);
 
             if (pwtx) {
                 if (!walletdb.WriteTx(*pwtx)) {
                     return DB_LOAD_FAIL;
                 }
             } else if (!walletdb.WriteAccountingEntry(pacentry->nEntryNo,
                                                       *pacentry)) {
                 return DB_LOAD_FAIL;
             }
         } else {
             int64_t nOrderPosOff = 0;
             for (const int64_t &nOffsetStart : nOrderPosOffsets) {
                 if (nOrderPos >= nOffsetStart) {
                     ++nOrderPosOff;
                 }
             }
 
             nOrderPos += nOrderPosOff;
             nOrderPosNext = std::max(nOrderPosNext, nOrderPos + 1);
 
             if (!nOrderPosOff) {
                 continue;
             }
 
             // Since we're changing the order, write it back.
             if (pwtx) {
                 if (!walletdb.WriteTx(*pwtx)) {
                     return DB_LOAD_FAIL;
                 }
             } else if (!walletdb.WriteAccountingEntry(pacentry->nEntryNo,
                                                       *pacentry)) {
                 return DB_LOAD_FAIL;
             }
         }
     }
 
     walletdb.WriteOrderPosNext(nOrderPosNext);
 
     return DB_LOAD_OK;
 }
 
 int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb) {
     // nOrderPosNext
     AssertLockHeld(cs_wallet);
     int64_t nRet = nOrderPosNext++;
     if (pwalletdb) {
         pwalletdb->WriteOrderPosNext(nOrderPosNext);
     } else {
         CWalletDB(strWalletFile).WriteOrderPosNext(nOrderPosNext);
     }
 
     return nRet;
 }
 
 bool CWallet::AccountMove(std::string strFrom, std::string strTo,
                           CAmount nAmount, std::string strComment) {
     CWalletDB walletdb(strWalletFile);
     if (!walletdb.TxnBegin()) {
         return false;
     }
 
     int64_t nNow = GetAdjustedTime();
 
     // Debit
     CAccountingEntry debit;
     debit.nOrderPos = IncOrderPosNext(&walletdb);
     debit.strAccount = strFrom;
     debit.nCreditDebit = -nAmount;
     debit.nTime = nNow;
     debit.strOtherAccount = strTo;
     debit.strComment = strComment;
     AddAccountingEntry(debit, &walletdb);
 
     // Credit
     CAccountingEntry credit;
     credit.nOrderPos = IncOrderPosNext(&walletdb);
     credit.strAccount = strTo;
     credit.nCreditDebit = nAmount;
     credit.nTime = nNow;
     credit.strOtherAccount = strFrom;
     credit.strComment = strComment;
     AddAccountingEntry(credit, &walletdb);
 
     if (!walletdb.TxnCommit()) {
         return false;
     }
 
     return true;
 }
 
 bool CWallet::GetAccountPubkey(CPubKey &pubKey, std::string strAccount,
                                bool bForceNew) {
     CWalletDB walletdb(strWalletFile);
 
     CAccount account;
     walletdb.ReadAccount(strAccount, account);
 
     if (!bForceNew) {
         if (!account.vchPubKey.IsValid()) {
             bForceNew = true;
         } else {
             // Check if the current key has been used.
             CScript scriptPubKey =
                 GetScriptForDestination(account.vchPubKey.GetID());
             for (std::map<uint256, CWalletTx>::iterator it = mapWallet.begin();
                  it != mapWallet.end() && account.vchPubKey.IsValid(); ++it) {
                 for (const CTxOut &txout : (*it).second.tx->vout) {
                     if (txout.scriptPubKey == scriptPubKey) {
                         bForceNew = true;
                         break;
                     }
                 }
             }
         }
     }
 
     // Generate a new key
     if (bForceNew) {
         if (!GetKeyFromPool(account.vchPubKey)) {
             return false;
         }
 
         SetAddressBook(account.vchPubKey.GetID(), strAccount, "receive");
         walletdb.WriteAccount(strAccount, account);
     }
 
     pubKey = account.vchPubKey;
 
     return true;
 }
 
 void CWallet::MarkDirty() {
     LOCK(cs_wallet);
     for (std::pair<const uint256, CWalletTx> &item : mapWallet) {
         item.second.MarkDirty();
     }
 }
 
 bool CWallet::MarkReplaced(const uint256 &originalHash,
                            const uint256 &newHash) {
     LOCK(cs_wallet);
 
     auto mi = mapWallet.find(originalHash);
 
     // There is a bug if MarkReplaced is not called on an existing wallet
     // transaction.
     assert(mi != mapWallet.end());
 
     CWalletTx &wtx = (*mi).second;
 
     // Ensure for now that we're not overwriting data.
     assert(wtx.mapValue.count("replaced_by_txid") == 0);
 
     wtx.mapValue["replaced_by_txid"] = newHash.ToString();
 
     CWalletDB walletdb(strWalletFile, "r+");
 
     bool success = true;
     if (!walletdb.WriteTx(wtx)) {
         LogPrintf("%s: Updating walletdb tx %s failed", __func__,
                   wtx.GetId().ToString());
         success = false;
     }
 
     NotifyTransactionChanged(this, originalHash, CT_UPDATED);
 
     return success;
 }
 
 bool CWallet::AddToWallet(const CWalletTx &wtxIn, bool fFlushOnClose) {
     LOCK(cs_wallet);
 
     CWalletDB walletdb(strWalletFile, "r+", fFlushOnClose);
 
     uint256 hash = wtxIn.GetId();
 
     // Inserts only if not already there, returns tx inserted or tx found.
     std::pair<std::map<uint256, CWalletTx>::iterator, bool> ret =
         mapWallet.insert(std::make_pair(hash, wtxIn));
     CWalletTx &wtx = (*ret.first).second;
     wtx.BindWallet(this);
     bool fInsertedNew = ret.second;
     if (fInsertedNew) {
         wtx.nTimeReceived = GetAdjustedTime();
         wtx.nOrderPos = IncOrderPosNext(&walletdb);
         wtxOrdered.insert(std::make_pair(wtx.nOrderPos, TxPair(&wtx, nullptr)));
 
         wtx.nTimeSmart = wtx.nTimeReceived;
         if (!wtxIn.hashUnset()) {
             if (mapBlockIndex.count(wtxIn.hashBlock)) {
                 int64_t latestNow = wtx.nTimeReceived;
                 int64_t latestEntry = 0;
                 {
                     // Tolerate times up to the last timestamp in the wallet not
                     // more than 5 minutes into the future.
                     int64_t latestTolerated = latestNow + 300;
                     const TxItems &txOrdered = wtxOrdered;
                     for (TxItems::const_reverse_iterator it =
                              txOrdered.rbegin();
                          it != txOrdered.rend(); ++it) {
                         CWalletTx *const pwtx = (*it).second.first;
                         if (pwtx == &wtx) {
                             continue;
                         }
 
                         CAccountingEntry *const pacentry = (*it).second.second;
                         int64_t nSmartTime;
                         if (pwtx) {
                             nSmartTime = pwtx->nTimeSmart;
                             if (!nSmartTime) {
                                 nSmartTime = pwtx->nTimeReceived;
                             }
                         } else {
                             nSmartTime = pacentry->nTime;
                         }
 
                         if (nSmartTime <= latestTolerated) {
                             latestEntry = nSmartTime;
                             if (nSmartTime > latestNow) {
                                 latestNow = nSmartTime;
                             }
 
                             break;
                         }
                     }
                 }
 
                 int64_t blocktime =
                     mapBlockIndex[wtxIn.hashBlock]->GetBlockTime();
                 wtx.nTimeSmart =
                     std::max(latestEntry, std::min(blocktime, latestNow));
             } else {
                 LogPrintf("AddToWallet(): found %s in block %s not in index\n",
                           wtxIn.GetId().ToString(), wtxIn.hashBlock.ToString());
             }
         }
 
         AddToSpends(hash);
     }
 
     bool fUpdated = false;
     if (!fInsertedNew) {
         // Merge
         if (!wtxIn.hashUnset() && wtxIn.hashBlock != wtx.hashBlock) {
             wtx.hashBlock = wtxIn.hashBlock;
             fUpdated = true;
         }
 
         // If no longer abandoned, update
         if (wtxIn.hashBlock.IsNull() && wtx.isAbandoned()) {
             wtx.hashBlock = wtxIn.hashBlock;
             fUpdated = true;
         }
 
         if (wtxIn.nIndex != -1 && (wtxIn.nIndex != wtx.nIndex)) {
             wtx.nIndex = wtxIn.nIndex;
             fUpdated = true;
         }
 
         if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe) {
             wtx.fFromMe = wtxIn.fFromMe;
             fUpdated = true;
         }
     }
 
     //// debug print
     LogPrintf("AddToWallet %s  %s%s\n", wtxIn.GetId().ToString(),
               (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
 
     // Write to disk
     if ((fInsertedNew || fUpdated) && !walletdb.WriteTx(wtx)) {
         return false;
     }
 
     // Break debit/credit balance caches:
     wtx.MarkDirty();
 
     // Notify UI of new or updated transaction.
     NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED);
 
     // Notify an external script when a wallet transaction comes in or is
     // updated.
     std::string strCmd = GetArg("-walletnotify", "");
 
     if (!strCmd.empty()) {
         boost::replace_all(strCmd, "%s", wtxIn.GetId().GetHex());
         // Thread runs free.
         boost::thread t(runCommand, strCmd);
     }
 
     return true;
 }
 
 bool CWallet::LoadToWallet(const CWalletTx &wtxIn) {
     uint256 txid = wtxIn.GetId();
 
     mapWallet[txid] = wtxIn;
     CWalletTx &wtx = mapWallet[txid];
     wtx.BindWallet(this);
     wtxOrdered.insert(std::make_pair(wtx.nOrderPos, TxPair(&wtx, nullptr)));
     AddToSpends(txid);
     for (const CTxIn &txin : wtx.tx->vin) {
         if (mapWallet.count(txin.prevout.hash)) {
             CWalletTx &prevtx = mapWallet[txin.prevout.hash];
             if (prevtx.nIndex == -1 && !prevtx.hashUnset()) {
                 MarkConflicted(prevtx.hashBlock, wtx.GetId());
             }
         }
     }
 
     return true;
 }
 
 /**
  * Add a transaction to the wallet, or update it. pIndex and posInBlock should
  * be set when the transaction was known to be included in a block. When
  * posInBlock = SYNC_TRANSACTION_NOT_IN_BLOCK (-1), then wallet state is not
  * updated in AddToWallet, but notifications happen and cached balances are
  * marked dirty. If fUpdate is true, existing transactions will be updated.
  *
  * TODO: One exception to this is that the abandoned state is cleared under the
  * assumption that any further notification of a transaction that was considered
  * abandoned is an indication that it is not safe to be considered abandoned.
  * Abandoned state should probably be more carefuly tracked via different
  * posInBlock signals or by checking mempool presence when necessary.
  */
 bool CWallet::AddToWalletIfInvolvingMe(const CTransaction &tx,
                                        const CBlockIndex *pIndex,
                                        int posInBlock, bool fUpdate) {
     AssertLockHeld(cs_wallet);
 
     if (posInBlock != -1) {
         for (const CTxIn &txin : tx.vin) {
             std::pair<TxSpends::const_iterator, TxSpends::const_iterator>
                 range = mapTxSpends.equal_range(txin.prevout);
             while (range.first != range.second) {
                 if (range.first->second != tx.GetId()) {
                     LogPrintf("Transaction %s (in block %s) conflicts with "
                               "wallet transaction %s (both spend %s:%i)\n",
                               tx.GetId().ToString(),
                               pIndex->GetBlockHash().ToString(),
                               range.first->second.ToString(),
                               range.first->first.hash.ToString(),
                               range.first->first.n);
                     MarkConflicted(pIndex->GetBlockHash(), range.first->second);
                 }
                 range.first++;
             }
         }
     }
 
     bool fExisted = mapWallet.count(tx.GetId()) != 0;
     if (fExisted && !fUpdate) {
         return false;
     }
 
     if (fExisted || IsMine(tx) || IsFromMe(tx)) {
         CWalletTx wtx(this, MakeTransactionRef(tx));
 
         // Get merkle branch if transaction was found in a block.
         if (posInBlock != -1) {
             wtx.SetMerkleBranch(pIndex, posInBlock);
         }
 
         return AddToWallet(wtx, false);
     }
 
     return false;
 }
 
 bool CWallet::AbandonTransaction(const uint256 &hashTx) {
     LOCK2(cs_main, cs_wallet);
 
     CWalletDB walletdb(strWalletFile, "r+");
 
     std::set<uint256> todo;
     std::set<uint256> done;
 
     // Can't mark abandoned if confirmed or in mempool.
     assert(mapWallet.count(hashTx));
     CWalletTx &origtx = mapWallet[hashTx];
     if (origtx.GetDepthInMainChain() > 0 || origtx.InMempool()) {
         return false;
     }
 
     todo.insert(hashTx);
 
     while (!todo.empty()) {
         uint256 now = *todo.begin();
         todo.erase(now);
         done.insert(now);
         assert(mapWallet.count(now));
         CWalletTx &wtx = mapWallet[now];
         int currentconfirm = wtx.GetDepthInMainChain();
         // If the orig tx was not in block, none of its spends can be.
         assert(currentconfirm <= 0);
         // If (currentconfirm < 0) {Tx and spends are already conflicted, no
         // need to abandon}
         if (currentconfirm == 0 && !wtx.isAbandoned()) {
             // If the orig tx was not in block/mempool, none of its spends can
             // be in mempool.
             assert(!wtx.InMempool());
             wtx.nIndex = -1;
             wtx.setAbandoned();
             wtx.MarkDirty();
             walletdb.WriteTx(wtx);
             NotifyTransactionChanged(this, wtx.GetId(), CT_UPDATED);
             // Iterate over all its outputs, and mark transactions in the wallet
             // that spend them abandoned too.
             TxSpends::const_iterator iter =
                 mapTxSpends.lower_bound(COutPoint(hashTx, 0));
             while (iter != mapTxSpends.end() && iter->first.hash == now) {
                 if (!done.count(iter->second)) {
                     todo.insert(iter->second);
                 }
                 iter++;
             }
 
             // If a transaction changes 'conflicted' state, that changes the
             // balance available of the outputs it spends. So force those to be
             // recomputed.
             for (const CTxIn &txin : wtx.tx->vin) {
                 if (mapWallet.count(txin.prevout.hash))
                     mapWallet[txin.prevout.hash].MarkDirty();
             }
         }
     }
 
     return true;
 }
 
 void CWallet::MarkConflicted(const uint256 &hashBlock, const uint256 &hashTx) {
     LOCK2(cs_main, cs_wallet);
 
     int conflictconfirms = 0;
     if (mapBlockIndex.count(hashBlock)) {
         CBlockIndex *pindex = mapBlockIndex[hashBlock];
         if (chainActive.Contains(pindex)) {
             conflictconfirms = -(chainActive.Height() - pindex->nHeight + 1);
         }
     }
 
     // If number of conflict confirms cannot be determined, this means that the
     // block is still unknown or not yet part of the main chain, for example
     // when loading the wallet during a reindex. Do nothing in that case.
     if (conflictconfirms >= 0) {
         return;
     }
 
     // Do not flush the wallet here for performance reasons
     CWalletDB walletdb(strWalletFile, "r+", false);
 
     std::set<uint256> todo;
     std::set<uint256> done;
 
     todo.insert(hashTx);
 
     while (!todo.empty()) {
         uint256 now = *todo.begin();
         todo.erase(now);
         done.insert(now);
         assert(mapWallet.count(now));
         CWalletTx &wtx = mapWallet[now];
         int currentconfirm = wtx.GetDepthInMainChain();
         if (conflictconfirms < currentconfirm) {
             // Block is 'more conflicted' than current confirm; update.
             // Mark transaction as conflicted with this block.
             wtx.nIndex = -1;
             wtx.hashBlock = hashBlock;
             wtx.MarkDirty();
             walletdb.WriteTx(wtx);
             // Iterate over all its outputs, and mark transactions in the wallet
             // that spend them conflicted too.
             TxSpends::const_iterator iter =
                 mapTxSpends.lower_bound(COutPoint(now, 0));
             while (iter != mapTxSpends.end() && iter->first.hash == now) {
                 if (!done.count(iter->second)) {
                     todo.insert(iter->second);
                 }
                 iter++;
             }
 
             // If a transaction changes 'conflicted' state, that changes the
             // balance available of the outputs it spends. So force those to be
             // recomputed.
             for (const CTxIn &txin : wtx.tx->vin) {
                 if (mapWallet.count(txin.prevout.hash)) {
                     mapWallet[txin.prevout.hash].MarkDirty();
                 }
             }
         }
     }
 }
 
 void CWallet::SyncTransaction(const CTransaction &tx, const CBlockIndex *pindex,
                               int posInBlock) {
     LOCK2(cs_main, cs_wallet);
 
     if (!AddToWalletIfInvolvingMe(tx, pindex, posInBlock, true)) {
         // Not one of ours
         return;
     }
 
     // If a transaction changes 'conflicted' state, that changes the balance
     // available of the outputs it spends. So force those to be recomputed,
     // also:
     for (const CTxIn &txin : tx.vin) {
         if (mapWallet.count(txin.prevout.hash))
             mapWallet[txin.prevout.hash].MarkDirty();
     }
 }
 
 isminetype CWallet::IsMine(const CTxIn &txin) const {
     LOCK(cs_wallet);
     std::map<uint256, CWalletTx>::const_iterator mi =
         mapWallet.find(txin.prevout.hash);
     if (mi != mapWallet.end()) {
         const CWalletTx &prev = (*mi).second;
         if (txin.prevout.n < prev.tx->vout.size()) {
             return IsMine(prev.tx->vout[txin.prevout.n]);
         }
     }
 
     return ISMINE_NO;
 }
 
 // Note that this function doesn't distinguish between a 0-valued input, and a
 // not-"is mine" (according to the filter) input.
 CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter &filter) const {
     LOCK(cs_wallet);
     std::map<uint256, CWalletTx>::const_iterator mi =
         mapWallet.find(txin.prevout.hash);
     if (mi != mapWallet.end()) {
         const CWalletTx &prev = (*mi).second;
         if (txin.prevout.n < prev.tx->vout.size()) {
             if (IsMine(prev.tx->vout[txin.prevout.n]) & filter) {
                 return prev.tx->vout[txin.prevout.n].nValue;
             }
         }
     }
 
     return 0;
 }
 
 isminetype CWallet::IsMine(const CTxOut &txout) const {
     return ::IsMine(*this, txout.scriptPubKey);
 }
 
 CAmount CWallet::GetCredit(const CTxOut &txout,
                            const isminefilter &filter) const {
     if (!MoneyRange(txout.nValue)) {
         throw std::runtime_error(std::string(__func__) +
                                  ": value out of range");
     }
 
     return (IsMine(txout) & filter) ? txout.nValue : 0;
 }
 
 bool CWallet::IsChange(const CTxOut &txout) const {
     // TODO: fix handling of 'change' outputs. The assumption is that any
     // payment to a script that is ours, but is not in the address book is
     // change. That assumption is likely to break when we implement
     // multisignature wallets that return change back into a
     // multi-signature-protected address; a better way of identifying which
     // outputs are 'the send' and which are 'the change' will need to be
     // implemented (maybe extend CWalletTx to remember which output, if any, was
     // change).
     if (::IsMine(*this, txout.scriptPubKey)) {
         CTxDestination address;
         if (!ExtractDestination(txout.scriptPubKey, address)) {
             return true;
         }
 
         LOCK(cs_wallet);
         if (!mapAddressBook.count(address)) {
             return true;
         }
     }
 
     return false;
 }
 
 CAmount CWallet::GetChange(const CTxOut &txout) const {
     if (!MoneyRange(txout.nValue)) {
         throw std::runtime_error(std::string(__func__) +
                                  ": value out of range");
     }
 
     return (IsChange(txout) ? txout.nValue : 0);
 }
 
 bool CWallet::IsMine(const CTransaction &tx) const {
     for (const CTxOut &txout : tx.vout) {
         if (IsMine(txout)) {
             return true;
         }
     }
 
     return false;
 }
 
 bool CWallet::IsFromMe(const CTransaction &tx) const {
     return GetDebit(tx, ISMINE_ALL) > 0;
 }
 
 CAmount CWallet::GetDebit(const CTransaction &tx,
                           const isminefilter &filter) const {
     CAmount nDebit = 0;
     for (const CTxIn &txin : tx.vin) {
         nDebit += GetDebit(txin, filter);
         if (!MoneyRange(nDebit)) {
             throw std::runtime_error(std::string(__func__) +
                                      ": value out of range");
         }
     }
 
     return nDebit;
 }
 
 bool CWallet::IsAllFromMe(const CTransaction &tx,
                           const isminefilter &filter) const {
     LOCK(cs_wallet);
 
     for (const CTxIn &txin : tx.vin) {
         auto mi = mapWallet.find(txin.prevout.hash);
         if (mi == mapWallet.end()) {
             // Any unknown inputs can't be from us.
             return false;
         }
 
         const CWalletTx &prev = (*mi).second;
 
         if (txin.prevout.n >= prev.tx->vout.size()) {
             // Invalid input!
             return false;
         }
 
         if (!(IsMine(prev.tx->vout[txin.prevout.n]) & filter)) {
             return false;
         }
     }
 
     return true;
 }
 
 CAmount CWallet::GetCredit(const CTransaction &tx,
                            const isminefilter &filter) const {
     CAmount nCredit = 0;
     for (const CTxOut &txout : tx.vout) {
         nCredit += GetCredit(txout, filter);
         if (!MoneyRange(nCredit)) {
             throw std::runtime_error(std::string(__func__) +
                                      ": value out of range");
         }
     }
 
     return nCredit;
 }
 
 CAmount CWallet::GetChange(const CTransaction &tx) const {
     CAmount nChange = 0;
     for (const CTxOut &txout : tx.vout) {
         nChange += GetChange(txout);
         if (!MoneyRange(nChange)) {
             throw std::runtime_error(std::string(__func__) +
                                      ": value out of range");
         }
     }
 
     return nChange;
 }
 
 CPubKey CWallet::GenerateNewHDMasterKey() {
     CKey key;
     key.MakeNewKey(true);
 
     int64_t nCreationTime = GetTime();
     CKeyMetadata metadata(nCreationTime);
 
     // Calculate the pubkey.
     CPubKey pubkey = key.GetPubKey();
     assert(key.VerifyPubKey(pubkey));
 
     // Set the hd keypath to "m" -> Master, refers the masterkeyid to itself.
     metadata.hdKeypath = "m";
     metadata.hdMasterKeyID = pubkey.GetID();
 
     LOCK(cs_wallet);
 
     // mem store the metadata
     mapKeyMetadata[pubkey.GetID()] = metadata;
 
     // Write the key&metadata to the database.
     if (!AddKeyPubKey(key, pubkey)) {
         throw std::runtime_error(std::string(__func__) +
                                  ": AddKeyPubKey failed");
     }
 
     return pubkey;
 }
 
 bool CWallet::SetHDMasterKey(const CPubKey &pubkey) {
     LOCK(cs_wallet);
 
     // Ensure this wallet.dat can only be opened by clients supporting HD.
     SetMinVersion(FEATURE_HD);
 
     // Store the keyid (hash160) together with the child index counter in the
     // database as a hdchain object.
     CHDChain newHdChain;
     newHdChain.masterKeyID = pubkey.GetID();
     SetHDChain(newHdChain, false);
 
     return true;
 }
 
 bool CWallet::SetHDChain(const CHDChain &chain, bool memonly) {
     LOCK(cs_wallet);
     if (!memonly && !CWalletDB(strWalletFile).WriteHDChain(chain)) {
         throw std::runtime_error(std::string(__func__) +
                                  ": writing chain failed");
     }
 
     hdChain = chain;
     return true;
 }
 
 bool CWallet::IsHDEnabled() {
     return !hdChain.masterKeyID.IsNull();
 }
 
 int64_t CWalletTx::GetTxTime() const {
     int64_t n = nTimeSmart;
     return n ? n : nTimeReceived;
 }
 
 int CWalletTx::GetRequestCount() const {
     LOCK(pwallet->cs_wallet);
 
     // Returns -1 if it wasn't being tracked.
     int nRequests = -1;
 
     if (IsCoinBase()) {
         // Generated block.
         if (!hashUnset()) {
             std::map<uint256, int>::const_iterator mi =
                 pwallet->mapRequestCount.find(hashBlock);
             if (mi != pwallet->mapRequestCount.end()) {
                 nRequests = (*mi).second;
             }
         }
     } else {
         // Did anyone request this transaction?
         std::map<uint256, int>::const_iterator mi =
             pwallet->mapRequestCount.find(GetId());
         if (mi != pwallet->mapRequestCount.end()) {
             nRequests = (*mi).second;
 
             // How about the block it's in?
             if (nRequests == 0 && !hashUnset()) {
                 std::map<uint256, int>::const_iterator _mi =
                     pwallet->mapRequestCount.find(hashBlock);
                 if (_mi != pwallet->mapRequestCount.end()) {
                     nRequests = (*_mi).second;
                 } else {
                     // If it's in someone else's block it must have got out.
                     nRequests = 1;
                 }
             }
         }
     }
 
     return nRequests;
 }
 
 void CWalletTx::GetAmounts(std::list<COutputEntry> &listReceived,
                            std::list<COutputEntry> &listSent, CAmount &nFee,
                            std::string &strSentAccount,
                            const isminefilter &filter) const {
     nFee = 0;
     listReceived.clear();
     listSent.clear();
     strSentAccount = strFromAccount;
 
     // Compute fee:
     CAmount nDebit = GetDebit(filter);
     // debit>0 means we signed/sent this transaction.
     if (nDebit > 0) {
         CAmount nValueOut = tx->GetValueOut();
         nFee = nDebit - nValueOut;
     }
 
     // Sent/received.
     for (unsigned int i = 0; i < tx->vout.size(); ++i) {
         const CTxOut &txout = tx->vout[i];
         isminetype fIsMine = pwallet->IsMine(txout);
         // Only need to handle txouts if AT LEAST one of these is true:
         //   1) they debit from us (sent)
         //   2) the output is to us (received)
         if (nDebit > 0) {
             // Don't report 'change' txouts
             if (pwallet->IsChange(txout)) {
                 continue;
             }
         } else if (!(fIsMine & filter)) {
             continue;
         }
 
         // In either case, we need to get the destination address.
         CTxDestination address;
 
         if (!ExtractDestination(txout.scriptPubKey, address) &&
             !txout.scriptPubKey.IsUnspendable()) {
             LogPrintf("CWalletTx::GetAmounts: Unknown transaction type found, "
                       "txid %s\n",
                       this->GetId().ToString());
             address = CNoDestination();
         }
 
         COutputEntry output = {address, txout.nValue, (int)i};
 
         // If we are debited by the transaction, add the output as a "sent"
         // entry.
         if (nDebit > 0) {
             listSent.push_back(output);
         }
 
         // If we are receiving the output, add it as a "received" entry.
         if (fIsMine & filter) {
             listReceived.push_back(output);
         }
     }
 }
 
 void CWalletTx::GetAccountAmounts(const std::string &strAccount,
                                   CAmount &nReceived, CAmount &nSent,
                                   CAmount &nFee,
                                   const isminefilter &filter) const {
     nReceived = nSent = nFee = 0;
 
     CAmount allFee;
     std::string strSentAccount;
     std::list<COutputEntry> listReceived;
     std::list<COutputEntry> listSent;
     GetAmounts(listReceived, listSent, allFee, strSentAccount, filter);
 
     if (strAccount == strSentAccount) {
         for (const COutputEntry &s : listSent) {
             nSent += s.amount;
         }
         nFee = allFee;
     }
 
     LOCK(pwallet->cs_wallet);
     for (const COutputEntry &r : listReceived) {
         if (pwallet->mapAddressBook.count(r.destination)) {
             std::map<CTxDestination, CAddressBookData>::const_iterator mi =
                 pwallet->mapAddressBook.find(r.destination);
             if (mi != pwallet->mapAddressBook.end() &&
                 (*mi).second.name == strAccount) {
                 nReceived += r.amount;
             }
         } else if (strAccount.empty()) {
             nReceived += r.amount;
         }
     }
 }
 
 /**
  * Scan the block chain (starting in pindexStart) for transactions from or to
  * us. If fUpdate is true, found transactions that already exist in the wallet
  * will be updated.
  *
  * Returns pointer to the first block in the last contiguous range that was
  * successfully scanned.
  */
 CBlockIndex *CWallet::ScanForWalletTransactions(CBlockIndex *pindexStart,
                                                 bool fUpdate) {
     LOCK2(cs_main, cs_wallet);
 
     CBlockIndex *ret = nullptr;
     int64_t nNow = GetTime();
     const CChainParams &chainParams = Params();
 
     CBlockIndex *pindex = pindexStart;
 
     // No need to read and scan block, if block was created before our wallet
     // birthday (as adjusted for block time variability)
     while (pindex && nTimeFirstKey &&
            (pindex->GetBlockTime() < (nTimeFirstKey - 7200))) {
         pindex = chainActive.Next(pindex);
     }
 
     // Show rescan progress in GUI as dialog or on splashscreen, if -rescan on
     // startup.
     ShowProgress(_("Rescanning..."), 0);
     double dProgressStart =
         GuessVerificationProgress(chainParams.TxData(), pindex);
     double dProgressTip =
         GuessVerificationProgress(chainParams.TxData(), chainActive.Tip());
     while (pindex) {
         if (pindex->nHeight % 100 == 0 && dProgressTip - dProgressStart > 0.0) {
             ShowProgress(
                 _("Rescanning..."),
                 std::max(1,
                          std::min(99, (int)((GuessVerificationProgress(
                                                  chainParams.TxData(), pindex) -
                                              dProgressStart) /
                                             (dProgressTip - dProgressStart) *
                                             100))));
         }
 
         CBlock block;
         if (ReadBlockFromDisk(block, pindex, Params().GetConsensus())) {
             for (size_t posInBlock = 0; posInBlock < block.vtx.size();
                  ++posInBlock) {
                 AddToWalletIfInvolvingMe(*block.vtx[posInBlock], pindex,
                                          posInBlock, fUpdate);
             }
 
             if (!ret) {
                 ret = pindex;
             }
         } else {
             ret = nullptr;
         }
 
         pindex = chainActive.Next(pindex);
         if (GetTime() >= nNow + 60) {
             nNow = GetTime();
             LogPrintf("Still rescanning. At block %d. Progress=%f\n",
                       pindex->nHeight,
                       GuessVerificationProgress(chainParams.TxData(), pindex));
         }
     }
 
     // Hide progress dialog in GUI.
     ShowProgress(_("Rescanning..."), 100);
 
     return ret;
 }
 
 void CWallet::ReacceptWalletTransactions() {
     // If transactions aren't being broadcasted, don't let them into local
     // mempool either.
     if (!fBroadcastTransactions) {
         return;
     }
 
     LOCK2(cs_main, cs_wallet);
     std::map<int64_t, CWalletTx *> mapSorted;
 
     // Sort pending wallet transactions based on their initial wallet insertion
     // order.
     for (std::pair<const uint256, CWalletTx> &item : mapWallet) {
         const uint256 &wtxid = item.first;
         CWalletTx &wtx = item.second;
         assert(wtx.GetId() == wtxid);
 
         int nDepth = wtx.GetDepthInMainChain();
 
         if (!wtx.IsCoinBase() && (nDepth == 0 && !wtx.isAbandoned())) {
             mapSorted.insert(std::make_pair(wtx.nOrderPos, &wtx));
         }
     }
 
     // Try to add wallet transactions to memory pool.
     for (std::pair<const int64_t, CWalletTx *> &item : mapSorted) {
         CWalletTx &wtx = *(item.second);
 
         LOCK(mempool.cs);
         CValidationState state;
         wtx.AcceptToMemoryPool(maxTxFee, state);
     }
 }
 
 bool CWalletTx::RelayWalletTransaction(CConnman *connman) {
     assert(pwallet->GetBroadcastTransactions());
     if (IsCoinBase() || isAbandoned() || GetDepthInMainChain() != 0) {
         return false;
     }
 
     CValidationState state;
     // GetDepthInMainChain already catches known conflicts.
     if (InMempool() || AcceptToMemoryPool(maxTxFee, state)) {
         LogPrintf("Relaying wtx %s\n", GetId().ToString());
         if (connman) {
             CInv inv(MSG_TX, GetId());
             connman->ForEachNode(
                 [&inv](CNode *pnode) { pnode->PushInventory(inv); });
             return true;
         }
     }
 
     return false;
 }
 
 std::set<uint256> CWalletTx::GetConflicts() const {
     std::set<uint256> result;
     if (pwallet != nullptr) {
         uint256 myHash = GetId();
         result = pwallet->GetConflicts(myHash);
         result.erase(myHash);
     }
 
     return result;
 }
 
 CAmount CWalletTx::GetDebit(const isminefilter &filter) const {
     if (tx->vin.empty()) return 0;
 
     CAmount debit = 0;
     if (filter & ISMINE_SPENDABLE) {
         if (fDebitCached) {
             debit += nDebitCached;
         } else {
             nDebitCached = pwallet->GetDebit(*this, ISMINE_SPENDABLE);
             fDebitCached = true;
             debit += nDebitCached;
         }
     }
 
     if (filter & ISMINE_WATCH_ONLY) {
         if (fWatchDebitCached) {
             debit += nWatchDebitCached;
         } else {
             nWatchDebitCached = pwallet->GetDebit(*this, ISMINE_WATCH_ONLY);
             fWatchDebitCached = true;
             debit += nWatchDebitCached;
         }
     }
 
     return debit;
 }
 
 CAmount CWalletTx::GetCredit(const isminefilter &filter) const {
     // Must wait until coinbase is safely deep enough in the chain before
     // valuing it.
     if (IsCoinBase() && GetBlocksToMaturity() > 0) {
         return 0;
     }
 
     CAmount credit = 0;
     if (filter & ISMINE_SPENDABLE) {
         // GetBalance can assume transactions in mapWallet won't change.
         if (fCreditCached) {
             credit += nCreditCached;
         } else {
             nCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
             fCreditCached = true;
             credit += nCreditCached;
         }
     }
 
     if (filter & ISMINE_WATCH_ONLY) {
         if (fWatchCreditCached) {
             credit += nWatchCreditCached;
         } else {
             nWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
             fWatchCreditCached = true;
             credit += nWatchCreditCached;
         }
     }
 
     return credit;
 }
 
 CAmount CWalletTx::GetImmatureCredit(bool fUseCache) const {
     if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain()) {
         if (fUseCache && fImmatureCreditCached) return nImmatureCreditCached;
         nImmatureCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
         fImmatureCreditCached = true;
         return nImmatureCreditCached;
     }
 
     return 0;
 }
 
 CAmount CWalletTx::GetAvailableCredit(bool fUseCache) const {
     if (pwallet == 0) {
         return 0;
     }
 
     // Must wait until coinbase is safely deep enough in the chain before
     // valuing it.
     if (IsCoinBase() && GetBlocksToMaturity() > 0) {
         return 0;
     }
 
     if (fUseCache && fAvailableCreditCached) {
         return nAvailableCreditCached;
     }
 
     CAmount nCredit = 0;
     uint256 hashTx = GetId();
     for (unsigned int i = 0; i < tx->vout.size(); i++) {
         if (!pwallet->IsSpent(hashTx, i)) {
             const CTxOut &txout = tx->vout[i];
             nCredit += pwallet->GetCredit(txout, ISMINE_SPENDABLE);
             if (!MoneyRange(nCredit)) {
                 throw std::runtime_error(
                     "CWalletTx::GetAvailableCredit() : value out of range");
             }
         }
     }
 
     nAvailableCreditCached = nCredit;
     fAvailableCreditCached = true;
     return nCredit;
 }
 
 CAmount CWalletTx::GetImmatureWatchOnlyCredit(const bool &fUseCache) const {
     if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain()) {
         if (fUseCache && fImmatureWatchCreditCached) {
             return nImmatureWatchCreditCached;
         }
 
         nImmatureWatchCreditCached =
             pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
         fImmatureWatchCreditCached = true;
         return nImmatureWatchCreditCached;
     }
 
     return 0;
 }
 
 CAmount CWalletTx::GetAvailableWatchOnlyCredit(const bool &fUseCache) const {
     if (pwallet == 0) {
         return 0;
     }
 
     // Must wait until coinbase is safely deep enough in the chain before
     // valuing it.
     if (IsCoinBase() && GetBlocksToMaturity() > 0) {
         return 0;
     }
 
     if (fUseCache && fAvailableWatchCreditCached) {
         return nAvailableWatchCreditCached;
     }
 
     CAmount nCredit = 0;
     for (unsigned int i = 0; i < tx->vout.size(); i++) {
         if (!pwallet->IsSpent(GetId(), i)) {
             const CTxOut &txout = tx->vout[i];
             nCredit += pwallet->GetCredit(txout, ISMINE_WATCH_ONLY);
             if (!MoneyRange(nCredit)) {
                 throw std::runtime_error(
                     "CWalletTx::GetAvailableCredit() : value out of range");
             }
         }
     }
 
     nAvailableWatchCreditCached = nCredit;
     fAvailableWatchCreditCached = true;
     return nCredit;
 }
 
 CAmount CWalletTx::GetChange() const {
     if (fChangeCached) {
         return nChangeCached;
     }
 
     nChangeCached = pwallet->GetChange(*this);
     fChangeCached = true;
     return nChangeCached;
 }
 
 bool CWalletTx::InMempool() const {
     LOCK(mempool.cs);
     if (mempool.exists(GetId())) {
         return true;
     }
 
     return false;
 }
 
 bool CWalletTx::IsTrusted() const {
     // Quick answer in most cases
     if (!CheckFinalTx(*this)) {
         return false;
     }
 
     int nDepth = GetDepthInMainChain();
     if (nDepth >= 1) {
         return true;
     }
 
     if (nDepth < 0) {
         return false;
     }
 
     // using wtx's cached debit
     if (!bSpendZeroConfChange || !IsFromMe(ISMINE_ALL)) {
         return false;
     }
 
     // Don't trust unconfirmed transactions from us unless they are in the
     // mempool.
     if (!InMempool()) {
         return false;
     }
 
     // Trusted if all inputs are from us and are in the mempool:
     for (const CTxIn &txin : tx->vin) {
         // Transactions not sent by us: not trusted
         const CWalletTx *parent = pwallet->GetWalletTx(txin.prevout.hash);
         if (parent == nullptr) {
             return false;
         }
 
         const CTxOut &parentOut = parent->tx->vout[txin.prevout.n];
         if (pwallet->IsMine(parentOut) != ISMINE_SPENDABLE) {
             return false;
         }
     }
 
     return true;
 }
 
 bool CWalletTx::IsEquivalentTo(const CWalletTx &_tx) const {
     CMutableTransaction tx1 = *this->tx;
     CMutableTransaction tx2 = *_tx.tx;
     for (unsigned int i = 0; i < tx1.vin.size(); i++) {
         tx1.vin[i].scriptSig = CScript();
     }
 
     for (unsigned int i = 0; i < tx2.vin.size(); i++) {
         tx2.vin[i].scriptSig = CScript();
     }
 
     return CTransaction(tx1) == CTransaction(tx2);
 }
 
 std::vector<uint256>
 CWallet::ResendWalletTransactionsBefore(int64_t nTime, CConnman *connman) {
     std::vector<uint256> result;
 
     LOCK(cs_wallet);
     // Sort them in chronological order
     std::multimap<unsigned int, CWalletTx *> mapSorted;
     for (std::pair<const uint256, CWalletTx> &item : mapWallet) {
         CWalletTx &wtx = item.second;
         // Don't rebroadcast if newer than nTime:
         if (wtx.nTimeReceived > nTime) {
             continue;
         }
 
         mapSorted.insert(std::make_pair(wtx.nTimeReceived, &wtx));
     }
 
     for (std::pair<const unsigned int, CWalletTx *> &item : mapSorted) {
         CWalletTx &wtx = *item.second;
         if (wtx.RelayWalletTransaction(connman)) {
             result.push_back(wtx.GetId());
         }
     }
 
     return result;
 }
 
 void CWallet::ResendWalletTransactions(int64_t nBestBlockTime,
                                        CConnman *connman) {
     // Do this infrequently and randomly to avoid giving away that these are our
     // transactions.
     if (GetTime() < nNextResend || !fBroadcastTransactions) {
         return;
     }
 
     bool fFirst = (nNextResend == 0);
     nNextResend = GetTime() + GetRand(30 * 60);
     if (fFirst) {
         return;
     }
 
     // Only do it if there's been a new block since last time
     if (nBestBlockTime < nLastResend) {
         return;
     }
 
     nLastResend = GetTime();
 
     // Rebroadcast unconfirmed txes older than 5 minutes before the last block
     // was found:
     std::vector<uint256> relayed =
         ResendWalletTransactionsBefore(nBestBlockTime - 5 * 60, connman);
     if (!relayed.empty()) {
         LogPrintf("%s: rebroadcast %u unconfirmed transactions\n", __func__,
                   relayed.size());
     }
 }
 
 /** @} */ // end of mapWallet
 
 /**
  * @defgroup Actions
  *
  * @{
  */
 CAmount CWallet::GetBalance() const {
     LOCK2(cs_main, cs_wallet);
 
     CAmount nTotal = 0;
     for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin();
          it != mapWallet.end(); ++it) {
         const CWalletTx *pcoin = &(*it).second;
         if (pcoin->IsTrusted()) {
             nTotal += pcoin->GetAvailableCredit();
         }
     }
 
     return nTotal;
 }
 
 CAmount CWallet::GetUnconfirmedBalance() const {
     LOCK2(cs_main, cs_wallet);
 
     CAmount nTotal = 0;
     for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin();
          it != mapWallet.end(); ++it) {
         const CWalletTx *pcoin = &(*it).second;
         if (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0 &&
             pcoin->InMempool()) {
             nTotal += pcoin->GetAvailableCredit();
         }
     }
 
     return nTotal;
 }
 
 CAmount CWallet::GetImmatureBalance() const {
     LOCK2(cs_main, cs_wallet);
 
     CAmount nTotal = 0;
     for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin();
          it != mapWallet.end(); ++it) {
         const CWalletTx *pcoin = &(*it).second;
         nTotal += pcoin->GetImmatureCredit();
     }
 
     return nTotal;
 }
 
 CAmount CWallet::GetWatchOnlyBalance() const {
     LOCK2(cs_main, cs_wallet);
 
     CAmount nTotal = 0;
     for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin();
          it != mapWallet.end(); ++it) {
         const CWalletTx *pcoin = &(*it).second;
         if (pcoin->IsTrusted()) {
             nTotal += pcoin->GetAvailableWatchOnlyCredit();
         }
     }
 
     return nTotal;
 }
 
 CAmount CWallet::GetUnconfirmedWatchOnlyBalance() const {
     LOCK2(cs_main, cs_wallet);
 
     CAmount nTotal = 0;
     for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin();
          it != mapWallet.end(); ++it) {
         const CWalletTx *pcoin = &(*it).second;
         if (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0 &&
             pcoin->InMempool()) {
             nTotal += pcoin->GetAvailableWatchOnlyCredit();
         }
     }
 
     return nTotal;
 }
 
 CAmount CWallet::GetImmatureWatchOnlyBalance() const {
     LOCK2(cs_main, cs_wallet);
 
     CAmount nTotal = 0;
     for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin();
          it != mapWallet.end(); ++it) {
         const CWalletTx *pcoin = &(*it).second;
         nTotal += pcoin->GetImmatureWatchOnlyCredit();
     }
 
     return nTotal;
 }
 
 void CWallet::AvailableCoins(std::vector<COutput> &vCoins, bool fOnlyConfirmed,
                              const CCoinControl *coinControl,
                              bool fIncludeZeroValue) const {
     vCoins.clear();
 
     LOCK2(cs_main, cs_wallet);
     for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin();
          it != mapWallet.end(); ++it) {
         const uint256 &wtxid = it->first;
         const CWalletTx *pcoin = &(*it).second;
 
         if (!CheckFinalTx(*pcoin)) {
             continue;
         }
 
         if (fOnlyConfirmed && !pcoin->IsTrusted()) {
             continue;
         }
 
         if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0) {
             continue;
         }
 
         int nDepth = pcoin->GetDepthInMainChain();
         if (nDepth < 0) {
             continue;
         }
 
         // We should not consider coins which aren't at least in our mempool.
         // It's possible for these to be conflicted via ancestors which we may
         // never be able to detect.
         if (nDepth == 0 && !pcoin->InMempool()) {
             continue;
         }
 
         // Bitcoin-ABC: Removed check that prevents consideration of coins from
         // transactions that are replacing other transactions. This check based
         // on pcoin->mapValue.count("replaces_txid") which was not being set
         // anywhere.
 
         // Similarly, we should not consider coins from transactions that have
         // been replaced. In the example above, we would want to prevent
         // creation of a transaction A' spending an output of A, because if
         // transaction B were initially confirmed, conflicting with A and A', we
         // wouldn't want to the user to create a transaction D intending to
         // replace A', but potentially resulting in a scenario where A, A', and
         // D could all be accepted (instead of just B and D, or just A and A'
         // like the user would want).
 
         // Bitcoin-ABC: retained this check as 'replaced_by_txid' is still set
         // in the wallet code.
         if (nDepth == 0 && fOnlyConfirmed &&
             pcoin->mapValue.count("replaced_by_txid")) {
             continue;
         }
 
         for (unsigned int i = 0; i < pcoin->tx->vout.size(); i++) {
             isminetype mine = IsMine(pcoin->tx->vout[i]);
             if (!(IsSpent(wtxid, i)) && mine != ISMINE_NO &&
                 !IsLockedCoin((*it).first, i) &&
                 (pcoin->tx->vout[i].nValue > 0 || fIncludeZeroValue) &&
                 (!coinControl || !coinControl->HasSelected() ||
                  coinControl->fAllowOtherInputs ||
                  coinControl->IsSelected(COutPoint((*it).first, i)))) {
                 vCoins.push_back(COutput(
                     pcoin, i, nDepth,
                     ((mine & ISMINE_SPENDABLE) != ISMINE_NO) ||
                         (coinControl && coinControl->fAllowWatchOnly &&
                          (mine & ISMINE_WATCH_SOLVABLE) != ISMINE_NO),
                     (mine & (ISMINE_SPENDABLE | ISMINE_WATCH_SOLVABLE)) !=
                         ISMINE_NO));
             }
         }
     }
 }
 
 static void ApproximateBestSubset(
     std::vector<std::pair<CAmount, std::pair<const CWalletTx *, unsigned int>>>
         vValue,
     const CAmount &nTotalLower, const CAmount &nTargetValue,
     std::vector<char> &vfBest, CAmount &nBest, int iterations = 1000) {
     std::vector<char> vfIncluded;
 
     vfBest.assign(vValue.size(), true);
     nBest = nTotalLower;
 
     FastRandomContext insecure_rand;
 
     for (int nRep = 0; nRep < iterations && nBest != nTargetValue; nRep++) {
         vfIncluded.assign(vValue.size(), false);
         CAmount nTotal = 0;
         bool fReachedTarget = false;
         for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++) {
             for (size_t i = 0; i < vValue.size(); i++) {
                 // The solver here uses a randomized algorithm, the randomness
                 // serves no real security purpose but is just needed to prevent
                 // degenerate behavior and it is important that the rng is fast.
                 // We do not use a constant random sequence, because there may
                 // be some privacy improvement by making the selection random.
                 if (nPass == 0 ? insecure_rand.rand32() & 1 : !vfIncluded[i]) {
                     nTotal += vValue[i].first;
                     vfIncluded[i] = true;
                     if (nTotal >= nTargetValue) {
                         fReachedTarget = true;
                         if (nTotal < nBest) {
                             nBest = nTotal;
                             vfBest = vfIncluded;
                         }
 
                         nTotal -= vValue[i].first;
                         vfIncluded[i] = false;
                     }
                 }
             }
         }
     }
 }
 
 bool CWallet::SelectCoinsMinConf(
     const CAmount &nTargetValue, const int nConfMine, const int nConfTheirs,
     const uint64_t nMaxAncestors, std::vector<COutput> vCoins,
     std::set<std::pair<const CWalletTx *, unsigned int>> &setCoinsRet,
     CAmount &nValueRet) const {
     setCoinsRet.clear();
     nValueRet = 0;
 
     // List of values less than target
     std::pair<CAmount, std::pair<const CWalletTx *, unsigned int>>
         coinLowestLarger;
     coinLowestLarger.first = std::numeric_limits<CAmount>::max();
     coinLowestLarger.second.first = nullptr;
     std::vector<std::pair<CAmount, std::pair<const CWalletTx *, unsigned int>>>
         vValue;
     CAmount nTotalLower = 0;
 
     random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
 
     for (const COutput &output : vCoins) {
         if (!output.fSpendable) {
             continue;
         }
 
         const CWalletTx *pcoin = output.tx;
 
         if (output.nDepth <
             (pcoin->IsFromMe(ISMINE_ALL) ? nConfMine : nConfTheirs)) {
             continue;
         }
 
         if (!mempool.TransactionWithinChainLimit(pcoin->GetId(),
                                                  nMaxAncestors)) {
             continue;
         }
 
         int i = output.i;
         CAmount n = pcoin->tx->vout[i].nValue;
 
         std::pair<CAmount, std::pair<const CWalletTx *, unsigned int>> coin =
             std::make_pair(n, std::make_pair(pcoin, i));
 
         if (n == nTargetValue) {
             setCoinsRet.insert(coin.second);
             nValueRet += coin.first;
             return true;
         } else if (n < nTargetValue + MIN_CHANGE) {
             vValue.push_back(coin);
             nTotalLower += n;
         } else if (n < coinLowestLarger.first) {
             coinLowestLarger = coin;
         }
     }
 
     if (nTotalLower == nTargetValue) {
         for (unsigned int i = 0; i < vValue.size(); ++i) {
             setCoinsRet.insert(vValue[i].second);
             nValueRet += vValue[i].first;
         }
 
         return true;
     }
 
     if (nTotalLower < nTargetValue) {
         if (coinLowestLarger.second.first == nullptr) {
             return false;
         }
 
         setCoinsRet.insert(coinLowestLarger.second);
         nValueRet += coinLowestLarger.first;
         return true;
     }
 
     // Solve subset sum by stochastic approximation
     std::sort(vValue.begin(), vValue.end(), CompareValueOnly());
     std::reverse(vValue.begin(), vValue.end());
     std::vector<char> vfBest;
     CAmount nBest;
 
     ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest);
     if (nBest != nTargetValue && nTotalLower >= nTargetValue + MIN_CHANGE) {
         ApproximateBestSubset(vValue, nTotalLower, nTargetValue + MIN_CHANGE,
                               vfBest, nBest);
     }
 
     // If we have a bigger coin and (either the stochastic approximation didn't
     // find a good solution, or the next bigger coin is closer), return the
     // bigger coin.
     if (coinLowestLarger.second.first &&
         ((nBest != nTargetValue && nBest < nTargetValue + MIN_CHANGE) ||
          coinLowestLarger.first <= nBest)) {
         setCoinsRet.insert(coinLowestLarger.second);
         nValueRet += coinLowestLarger.first;
     } else {
         for (unsigned int i = 0; i < vValue.size(); i++) {
             if (vfBest[i]) {
                 setCoinsRet.insert(vValue[i].second);
                 nValueRet += vValue[i].first;
             }
         }
 
         LogPrint("selectcoins", "SelectCoins() best subset: ");
         for (unsigned int i = 0; i < vValue.size(); i++) {
             if (vfBest[i]) {
                 LogPrint("selectcoins", "%s ", FormatMoney(vValue[i].first));
             }
         }
 
         LogPrint("selectcoins", "total %s\n", FormatMoney(nBest));
     }
 
     return true;
 }
 
 bool CWallet::SelectCoins(
     const std::vector<COutput> &vAvailableCoins, const CAmount &nTargetValue,
     std::set<std::pair<const CWalletTx *, unsigned int>> &setCoinsRet,
     CAmount &nValueRet, const CCoinControl *coinControl) const {
     std::vector<COutput> vCoins(vAvailableCoins);
 
     // coin control -> return all selected outputs (we want all selected to go
     // into the transaction for sure).
     if (coinControl && coinControl->HasSelected() &&
         !coinControl->fAllowOtherInputs) {
         for (const COutput &out : vCoins) {
             if (!out.fSpendable) {
                 continue;
             }
 
             nValueRet += out.tx->tx->vout[out.i].nValue;
             setCoinsRet.insert(std::make_pair(out.tx, out.i));
         }
 
         return (nValueRet >= nTargetValue);
     }
 
     // Calculate value from preset inputs and store them.
     std::set<std::pair<const CWalletTx *, uint32_t>> setPresetCoins;
     CAmount nValueFromPresetInputs = 0;
 
     std::vector<COutPoint> vPresetInputs;
     if (coinControl) {
         coinControl->ListSelected(vPresetInputs);
     }
 
     for (const COutPoint &outpoint : vPresetInputs) {
         std::map<uint256, CWalletTx>::const_iterator it =
             mapWallet.find(outpoint.hash);
         if (it == mapWallet.end()) {
             // TODO: Allow non-wallet inputs
             return false;
         }
 
         const CWalletTx *pcoin = &it->second;
         // Clearly invalid input, fail.
         if (pcoin->tx->vout.size() <= outpoint.n) {
             return false;
         }
 
         nValueFromPresetInputs += pcoin->tx->vout[outpoint.n].nValue;
         setPresetCoins.insert(std::make_pair(pcoin, outpoint.n));
     }
 
     // Remove preset inputs from vCoins.
     for (std::vector<COutput>::iterator it = vCoins.begin();
          it != vCoins.end() && coinControl && coinControl->HasSelected();) {
         if (setPresetCoins.count(std::make_pair(it->tx, it->i))) {
             it = vCoins.erase(it);
         } else {
             ++it;
         }
     }
 
     size_t nMaxChainLength =
         std::min(GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT),
                  GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT));
     bool fRejectLongChains = GetBoolArg("-walletrejectlongchains",
                                         DEFAULT_WALLET_REJECT_LONG_CHAINS);
 
     bool res =
         nTargetValue <= nValueFromPresetInputs ||
         SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 1, 6, 0,
                            vCoins, setCoinsRet, nValueRet) ||
         SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 1, 1, 0,
                            vCoins, setCoinsRet, nValueRet) ||
         (bSpendZeroConfChange &&
          SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, 2,
                             vCoins, setCoinsRet, nValueRet)) ||
         (bSpendZeroConfChange &&
          SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1,
                             std::min((size_t)4, nMaxChainLength / 3), vCoins,
                             setCoinsRet, nValueRet)) ||
         (bSpendZeroConfChange &&
          SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1,
                             nMaxChainLength / 2, vCoins, setCoinsRet,
                             nValueRet)) ||
         (bSpendZeroConfChange &&
          SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1,
                             nMaxChainLength, vCoins, setCoinsRet, nValueRet)) ||
         (bSpendZeroConfChange && !fRejectLongChains &&
          SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1,
                             std::numeric_limits<uint64_t>::max(), vCoins,
                             setCoinsRet, nValueRet));
 
     // Because SelectCoinsMinConf clears the setCoinsRet, we now add the
     // possible inputs to the coinset.
     setCoinsRet.insert(setPresetCoins.begin(), setPresetCoins.end());
 
     // Add preset inputs to the total value selected.
     nValueRet += nValueFromPresetInputs;
 
     return res;
 }
 
 bool CWallet::FundTransaction(CMutableTransaction &tx, CAmount &nFeeRet,
                               bool overrideEstimatedFeeRate,
                               const CFeeRate &specificFeeRate,
                               int &nChangePosInOut, std::string &strFailReason,
                               bool includeWatching, bool lockUnspents,
                               const std::set<int> &setSubtractFeeFromOutputs,
                               bool keepReserveKey,
                               const CTxDestination &destChange) {
     std::vector<CRecipient> vecSend;
 
     // Turn the txout set into a CRecipient vector.
     for (size_t idx = 0; idx < tx.vout.size(); idx++) {
         const CTxOut &txOut = tx.vout[idx];
         CRecipient recipient = {txOut.scriptPubKey, txOut.nValue,
                                 setSubtractFeeFromOutputs.count(idx) == 1};
         vecSend.push_back(recipient);
     }
 
     CCoinControl coinControl;
     coinControl.destChange = destChange;
     coinControl.fAllowOtherInputs = true;
     coinControl.fAllowWatchOnly = includeWatching;
     coinControl.fOverrideFeeRate = overrideEstimatedFeeRate;
     coinControl.nFeeRate = specificFeeRate;
 
     for (const CTxIn &txin : tx.vin) {
         coinControl.Select(txin.prevout);
     }
 
     CReserveKey reservekey(this);
     CWalletTx wtx;
     if (!CreateTransaction(vecSend, wtx, reservekey, nFeeRet, nChangePosInOut,
                            strFailReason, &coinControl, false)) {
         return false;
     }
 
     if (nChangePosInOut != -1) {
         tx.vout.insert(tx.vout.begin() + nChangePosInOut,
                        wtx.tx->vout[nChangePosInOut]);
     }
 
     // Copy output sizes from new transaction; they may have had the fee
     // subtracted from them.
     for (size_t idx = 0; idx < tx.vout.size(); idx++) {
         tx.vout[idx].nValue = wtx.tx->vout[idx].nValue;
     }
 
     // Add new txins (keeping original txin scriptSig/order)
     for (const CTxIn &txin : wtx.tx->vin) {
         if (!coinControl.IsSelected(txin.prevout)) {
             tx.vin.push_back(txin);
 
             if (lockUnspents) {
                 LOCK2(cs_main, cs_wallet);
                 LockCoin(txin.prevout);
             }
         }
     }
 
     // Optionally keep the change output key.
     if (keepReserveKey) {
         reservekey.KeepKey();
     }
 
     return true;
 }
 
 bool CWallet::CreateTransaction(const std::vector<CRecipient> &vecSend,
                                 CWalletTx &wtxNew, CReserveKey &reservekey,
                                 CAmount &nFeeRet, int &nChangePosInOut,
                                 std::string &strFailReason,
                                 const CCoinControl *coinControl, bool sign) {
     CAmount nValue = 0;
     int nChangePosRequest = nChangePosInOut;
     unsigned int nSubtractFeeFromAmount = 0;
     for (const auto &recipient : vecSend) {
         if (nValue < 0 || recipient.nAmount < 0) {
             strFailReason = _("Transaction amounts must not be negative");
             return false;
         }
 
         nValue += recipient.nAmount;
 
         if (recipient.fSubtractFeeFromAmount) {
             nSubtractFeeFromAmount++;
         }
     }
 
     if (vecSend.empty()) {
         strFailReason = _("Transaction must have at least one recipient");
         return false;
     }
 
     wtxNew.fTimeReceivedIsTxTime = true;
     wtxNew.BindWallet(this);
     CMutableTransaction txNew;
 
     // Discourage fee sniping.
     //
     // For a large miner the value of the transactions in the best block and the
     // mempool can exceed the cost of deliberately attempting to mine two blocks
     // to orphan the current best block. By setting nLockTime such that only the
     // next block can include the transaction, we discourage this practice as
     // the height restricted and limited blocksize gives miners considering fee
     // sniping fewer options for pulling off this attack.
     //
     // A simple way to think about this is from the wallet's point of view we
     // always want the blockchain to move forward. By setting nLockTime this way
     // we're basically making the statement that we only want this transaction
     // to appear in the next block; we don't want to potentially encourage
     // reorgs by allowing transactions to appear at lower heights than the next
     // block in forks of the best chain.
     //
     // Of course, the subsidy is high enough, and transaction volume low enough,
     // that fee sniping isn't a problem yet, but by implementing a fix now we
     // ensure code won't be written that makes assumptions about nLockTime that
     // preclude a fix later.
     txNew.nLockTime = chainActive.Height();
 
     // Secondly occasionally randomly pick a nLockTime even further back, so
     // that transactions that are delayed after signing for whatever reason,
     // e.g. high-latency mix networks and some CoinJoin implementations, have
     // better privacy.
     if (GetRandInt(10) == 0) {
         txNew.nLockTime = std::max(0, (int)txNew.nLockTime - GetRandInt(100));
     }
 
     assert(txNew.nLockTime <= (unsigned int)chainActive.Height());
     assert(txNew.nLockTime < LOCKTIME_THRESHOLD);
 
     {
         std::set<std::pair<const CWalletTx *, unsigned int>> setCoins;
         LOCK2(cs_main, cs_wallet);
 
         std::vector<COutput> vAvailableCoins;
         AvailableCoins(vAvailableCoins, true, coinControl);
 
         nFeeRet = 0;
         // Start with no fee and loop until there is enough fee.
         while (true) {
             nChangePosInOut = nChangePosRequest;
             txNew.vin.clear();
             txNew.vout.clear();
             wtxNew.fFromMe = true;
             bool fFirst = true;
 
             CAmount nValueToSelect = nValue;
             if (nSubtractFeeFromAmount == 0) {
                 nValueToSelect += nFeeRet;
             }
 
             double dPriority = 0;
             // vouts to the payees
             for (const auto &recipient : vecSend) {
                 CTxOut txout(recipient.nAmount, recipient.scriptPubKey);
 
                 if (recipient.fSubtractFeeFromAmount) {
                     // Subtract fee equally from each selected recipient.
                     txout.nValue -= nFeeRet / nSubtractFeeFromAmount;
 
                     // First receiver pays the remainder not divisible by output
                     // count.
                     if (fFirst) {
                         fFirst = false;
                         txout.nValue -= nFeeRet % nSubtractFeeFromAmount;
                     }
                 }
 
                 if (txout.IsDust(dustRelayFee)) {
                     if (recipient.fSubtractFeeFromAmount && nFeeRet > 0) {
                         if (txout.nValue < 0) {
                             strFailReason = _("The transaction amount is "
                                               "too small to pay the fee");
                         } else {
                             strFailReason =
                                 _("The transaction amount is too small to "
                                   "send after the fee has been deducted");
                         }
                     } else {
                         strFailReason = _("Transaction amount too small");
                     }
 
                     return false;
                 }
 
                 txNew.vout.push_back(txout);
             }
 
             // Choose coins to use.
             CAmount nValueIn = 0;
             setCoins.clear();
             if (!SelectCoins(vAvailableCoins, nValueToSelect, setCoins,
                              nValueIn, coinControl)) {
                 strFailReason = _("Insufficient funds");
                 return false;
             }
 
             for (const auto &pcoin : setCoins) {
                 CAmount nCredit = pcoin.first->tx->vout[pcoin.second].nValue;
                 // The coin age after the next block (depth+1) is used instead
                 // of the current, reflecting an assumption the user would
                 // accept a bit more delay for a chance at a free transaction.
                 // But mempool inputs might still be in the mempool, so their
                 // age stays 0.
                 int age = pcoin.first->GetDepthInMainChain();
                 assert(age >= 0);
                 if (age != 0) age += 1;
                 dPriority += (double)nCredit * age;
             }
 
             const CAmount nChange = nValueIn - nValueToSelect;
             if (nChange > 0) {
                 // Fill a vout to ourself.
                 // TODO: pass in scriptChange instead of reservekey so change
                 // transaction isn't always pay-to-bitcoin-address.
                 CScript scriptChange;
 
                 // Coin control: send change to custom address.
                 if (coinControl &&
                     !boost::get<CNoDestination>(&coinControl->destChange)) {
                     scriptChange =
                         GetScriptForDestination(coinControl->destChange);
 
                     // No coin control: send change to newly generated address.
                 } else {
                     // Note: We use a new key here to keep it from being obvious
                     // which side is the change. The drawback is that by not
                     // reusing a previous key, the change may be lost if a
                     // backup is restored, if the backup doesn't have the new
                     // private key for the change. If we reused the old key, it
                     // would be possible to add code to look for and rediscover
                     // unknown transactions that were written with keys of ours
                     // to recover post-backup change.
 
                     // Reserve a new key pair from key pool.
                     CPubKey vchPubKey;
                     bool ret;
                     ret = reservekey.GetReservedKey(vchPubKey);
                     if (!ret) {
                         strFailReason = _("Keypool ran out, please call "
                                           "keypoolrefill first");
                         return false;
                     }
 
                     scriptChange = GetScriptForDestination(vchPubKey.GetID());
                 }
 
                 CTxOut newTxOut(nChange, scriptChange);
 
                 // We do not move dust-change to fees, because the sender would
                 // end up paying more than requested. This would be against the
                 // purpose of the all-inclusive feature. So instead we raise the
                 // change and deduct from the recipient.
                 if (nSubtractFeeFromAmount > 0 &&
                     newTxOut.IsDust(dustRelayFee)) {
                     CAmount nDust = newTxOut.GetDustThreshold(dustRelayFee) -
                                     newTxOut.nValue;
                     // Raise change until no more dust.
                     newTxOut.nValue += nDust;
                     // Subtract from first recipient.
                     for (unsigned int i = 0; i < vecSend.size(); i++) {
                         if (vecSend[i].fSubtractFeeFromAmount) {
                             txNew.vout[i].nValue -= nDust;
                             if (txNew.vout[i].IsDust(dustRelayFee)) {
                                 strFailReason =
                                     _("The transaction amount is too small "
                                       "to send after the fee has been "
                                       "deducted");
                                 return false;
                             }
 
                             break;
                         }
                     }
                 }
 
                 // Never create dust outputs; if we would, just add the dust to
                 // the fee.
                 if (newTxOut.IsDust(dustRelayFee)) {
                     nChangePosInOut = -1;
                     nFeeRet += nChange;
                     reservekey.ReturnKey();
                 } else {
                     if (nChangePosInOut == -1) {
                         // Insert change txn at random position:
                         nChangePosInOut = GetRandInt(txNew.vout.size() + 1);
                     } else if ((unsigned int)nChangePosInOut >
                                txNew.vout.size()) {
                         strFailReason = _("Change index out of range");
                         return false;
                     }
 
                     std::vector<CTxOut>::iterator position =
                         txNew.vout.begin() + nChangePosInOut;
                     txNew.vout.insert(position, newTxOut);
                 }
             } else {
                 reservekey.ReturnKey();
             }
 
             // Fill vin
             //
             // Note how the sequence number is set to non-maxint so that the
             // nLockTime set above actually works.
             for (const auto &coin : setCoins) {
                 txNew.vin.push_back(
                     CTxIn(coin.first->GetId(), coin.second, CScript(),
                           std::numeric_limits<unsigned int>::max() - 1));
             }
 
             // Fill in dummy signatures for fee calculation.
             if (!DummySignTx(txNew, setCoins)) {
                 strFailReason = _("Signing transaction failed");
                 return false;
             }
 
             unsigned int nBytes = GetTransactionSize(txNew);
 
             CTransaction txNewConst(txNew);
             dPriority = txNewConst.ComputePriority(dPriority, nBytes);
 
             // Remove scriptSigs to eliminate the fee calculation dummy
             // signatures.
             for (auto &vin : txNew.vin) {
                 vin.scriptSig = CScript();
             }
 
             // Allow to override the default confirmation target over the
             // CoinControl instance.
             int currentConfirmationTarget = nTxConfirmTarget;
             if (coinControl && coinControl->nConfirmTarget > 0) {
                 currentConfirmationTarget = coinControl->nConfirmTarget;
             }
 
             // Can we complete this as a free transaction?
             if (fSendFreeTransactions &&
                 nBytes <= MAX_FREE_TRANSACTION_CREATE_SIZE) {
                 // Not enough fee: enough priority?
                 double dPriorityNeeded =
                     mempool.estimateSmartPriority(currentConfirmationTarget);
                 // Require at least hard-coded AllowFree.
                 if (dPriority >= dPriorityNeeded && AllowFree(dPriority)) {
                     break;
                 }
             }
 
             CAmount nFeeNeeded =
                 GetMinimumFee(nBytes, currentConfirmationTarget, mempool);
             if (coinControl && nFeeNeeded > 0 &&
                 coinControl->nMinimumTotalFee > nFeeNeeded) {
                 nFeeNeeded = coinControl->nMinimumTotalFee;
             }
 
             if (coinControl && coinControl->fOverrideFeeRate) {
                 nFeeNeeded = coinControl->nFeeRate.GetFee(nBytes);
             }
 
             // If we made it here and we aren't even able to meet the relay fee
             // on the next pass, give up because we must be at the maximum
             // allowed fee.
             if (nFeeNeeded < ::minRelayTxFee.GetFee(nBytes)) {
                 strFailReason = _("Transaction too large for fee policy");
                 return false;
             }
 
             if (nFeeRet >= nFeeNeeded) {
                 // Reduce fee to only the needed amount if we have change output
                 // to increase. This prevents potential overpayment in fees if
                 // the coins selected to meet nFeeNeeded result in a transaction
                 // that requires less fee than the prior iteration.
                 // TODO: The case where nSubtractFeeFromAmount > 0 remains to be
                 // addressed because it requires returning the fee to the payees
                 // and not the change output.
                 // TODO: The case where there is no change output remains to be
                 // addressed so we avoid creating too small an output.
                 if (nFeeRet > nFeeNeeded && nChangePosInOut != -1 &&
                     nSubtractFeeFromAmount == 0) {
                     CAmount extraFeePaid = nFeeRet - nFeeNeeded;
                     std::vector<CTxOut>::iterator change_position =
                         txNew.vout.begin() + nChangePosInOut;
                     change_position->nValue += extraFeePaid;
                     nFeeRet -= extraFeePaid;
                 }
 
                 // Done, enough fee included.
                 break;
             }
 
             // Try to reduce change to include necessary fee.
             if (nChangePosInOut != -1 && nSubtractFeeFromAmount == 0) {
                 CAmount additionalFeeNeeded = nFeeNeeded - nFeeRet;
                 std::vector<CTxOut>::iterator change_position =
                     txNew.vout.begin() + nChangePosInOut;
                 // Only reduce change if remaining amount is still a large
                 // enough output.
                 if (change_position->nValue >=
                     MIN_FINAL_CHANGE + additionalFeeNeeded) {
                     change_position->nValue -= additionalFeeNeeded;
                     nFeeRet += additionalFeeNeeded;
                     // Done, able to increase fee from change.
                     break;
                 }
             }
 
             // Include more fee and try again.
             nFeeRet = nFeeNeeded;
             continue;
         }
 
         if (sign) {
             uint32_t nHashType = SIGHASH_ALL | SIGHASH_FORKID;
 
             CTransaction txNewConst(txNew);
             int nIn = 0;
             for (const auto &coin : setCoins) {
                 const CScript &scriptPubKey =
                     coin.first->tx->vout[coin.second].scriptPubKey;
                 SignatureData sigdata;
 
                 if (!ProduceSignature(
                         TransactionSignatureCreator(
                             this, &txNewConst, nIn,
                             coin.first->tx->vout[coin.second].nValue,
                             nHashType),
                         scriptPubKey, sigdata)) {
                     strFailReason = _("Signing transaction failed");
                     return false;
                 } else {
                     UpdateTransaction(txNew, nIn, sigdata);
                 }
 
                 nIn++;
             }
         }
 
         // Embed the constructed transaction data in wtxNew.
         wtxNew.SetTx(MakeTransactionRef(std::move(txNew)));
 
         // Limit size.
         if (GetTransactionSize(wtxNew) >= MAX_STANDARD_TX_SIZE) {
             strFailReason = _("Transaction too large");
             return false;
         }
     }
 
     if (GetBoolArg("-walletrejectlongchains",
                    DEFAULT_WALLET_REJECT_LONG_CHAINS)) {
         // Lastly, ensure this tx will pass the mempool's chain limits.
         LockPoints lp;
         CTxMemPoolEntry entry(wtxNew.tx, 0, 0, 0, 0, 0, false, 0, lp);
         CTxMemPool::setEntries setAncestors;
         size_t nLimitAncestors =
             GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT);
         size_t nLimitAncestorSize =
             GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT) * 1000;
         size_t nLimitDescendants =
             GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT);
         size_t nLimitDescendantSize =
             GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) *
             1000;
         std::string errString;
         if (!mempool.CalculateMemPoolAncestors(
                 entry, setAncestors, nLimitAncestors, nLimitAncestorSize,
                 nLimitDescendants, nLimitDescendantSize, errString)) {
             strFailReason = _("Transaction has too long of a mempool chain");
             return false;
         }
     }
 
     return true;
 }
 
 /**
  * Call after CreateTransaction unless you want to abort
  */
 bool CWallet::CommitTransaction(CWalletTx &wtxNew, CReserveKey &reservekey,
                                 CConnman *connman, CValidationState &state) {
     LOCK2(cs_main, cs_wallet);
     LogPrintf("CommitTransaction:\n%s", wtxNew.tx->ToString());
 
     // Take key pair from key pool so it won't be used again.
     reservekey.KeepKey();
 
     // Add tx to wallet, because if it has change it's also ours, otherwise just
     // for transaction history.
     AddToWallet(wtxNew);
 
     // Notify that old coins are spent.
     for (const CTxIn &txin : wtxNew.tx->vin) {
         CWalletTx &coin = mapWallet[txin.prevout.hash];
         coin.BindWallet(this);
         NotifyTransactionChanged(this, coin.GetId(), CT_UPDATED);
     }
 
     // Track how many getdata requests our transaction gets.
     mapRequestCount[wtxNew.GetId()] = 0;
 
     if (fBroadcastTransactions) {
         // Broadcast
         if (!wtxNew.AcceptToMemoryPool(maxTxFee, state)) {
             LogPrintf("CommitTransaction(): Transaction cannot be "
                       "broadcast immediately, %s\n",
                       state.GetRejectReason());
             // TODO: if we expect the failure to be long term or permanent,
             // instead delete wtx from the wallet and return failure.
         } else {
             wtxNew.RelayWalletTransaction(connman);
         }
     }
 
     return true;
 }
 
 void CWallet::ListAccountCreditDebit(const std::string &strAccount,
                                      std::list<CAccountingEntry> &entries) {
     CWalletDB walletdb(strWalletFile);
     return walletdb.ListAccountCreditDebit(strAccount, entries);
 }
 
 bool CWallet::AddAccountingEntry(const CAccountingEntry &acentry) {
     CWalletDB walletdb(strWalletFile);
 
     return AddAccountingEntry(acentry, &walletdb);
 }
 
 bool CWallet::AddAccountingEntry(const CAccountingEntry &acentry,
                                  CWalletDB *pwalletdb) {
     if (!pwalletdb->WriteAccountingEntry_Backend(acentry)) {
         return false;
     }
 
     laccentries.push_back(acentry);
     CAccountingEntry &entry = laccentries.back();
     wtxOrdered.insert(std::make_pair(entry.nOrderPos, TxPair(nullptr, &entry)));
 
     return true;
 }
 
 CAmount CWallet::GetRequiredFee(unsigned int nTxBytes) {
     return std::max(minTxFee.GetFee(nTxBytes),
                     ::minRelayTxFee.GetFee(nTxBytes));
 }
 
 CAmount CWallet::GetMinimumFee(unsigned int nTxBytes,
                                unsigned int nConfirmTarget,
                                const CTxMemPool &pool) {
     // payTxFee is the user-set global for desired feerate.
     return GetMinimumFee(nTxBytes, nConfirmTarget, pool,
                          payTxFee.GetFee(nTxBytes));
 }
 
 CAmount CWallet::GetMinimumFee(unsigned int nTxBytes,
                                unsigned int nConfirmTarget,
                                const CTxMemPool &pool, CAmount targetFee) {
     CAmount nFeeNeeded = targetFee;
     // User didn't set: use -txconfirmtarget to estimate...
     if (nFeeNeeded == 0) {
         int estimateFoundTarget = nConfirmTarget;
         nFeeNeeded = pool.estimateSmartFee(nConfirmTarget, &estimateFoundTarget)
                          .GetFee(nTxBytes);
         // ... unless we don't have enough mempool data for estimatefee, then
         // use fallbackFee.
         if (nFeeNeeded == 0) {
             nFeeNeeded = fallbackFee.GetFee(nTxBytes);
         }
     }
 
     // Prevent user from paying a fee below minRelayTxFee or minTxFee.
     nFeeNeeded = std::max(nFeeNeeded, GetRequiredFee(nTxBytes));
 
     // But always obey the maximum.
     if (nFeeNeeded > maxTxFee) {
         nFeeNeeded = maxTxFee;
     }
 
     return nFeeNeeded;
 }
 
 DBErrors CWallet::LoadWallet(bool &fFirstRunRet) {
     if (!fFileBacked) {
         return DB_LOAD_OK;
     }
 
     fFirstRunRet = false;
     DBErrors nLoadWalletRet = CWalletDB(strWalletFile, "cr+").LoadWallet(this);
     if (nLoadWalletRet == DB_NEED_REWRITE) {
         if (CDB::Rewrite(strWalletFile, "\x04pool")) {
             LOCK(cs_wallet);
             setKeyPool.clear();
             // Note: can't top-up keypool here, because wallet is locked. User
             // will be prompted to unlock wallet the next operation that
             // requires a new key.
         }
     }
 
     if (nLoadWalletRet != DB_LOAD_OK) {
         return nLoadWalletRet;
     }
 
     fFirstRunRet = !vchDefaultKey.IsValid();
 
     uiInterface.LoadWallet(this);
 
     return DB_LOAD_OK;
 }
 
 DBErrors CWallet::ZapSelectTx(std::vector<uint256> &vHashIn,
                               std::vector<uint256> &vHashOut) {
     if (!fFileBacked) {
         return DB_LOAD_OK;
     }
 
     DBErrors nZapSelectTxRet =
         CWalletDB(strWalletFile, "cr+").ZapSelectTx(this, vHashIn, vHashOut);
     if (nZapSelectTxRet == DB_NEED_REWRITE) {
         if (CDB::Rewrite(strWalletFile, "\x04pool")) {
             LOCK(cs_wallet);
             setKeyPool.clear();
             // Note: can't top-up keypool here, because wallet is locked. User
             // will be prompted to unlock wallet the next operation that
             // requires a new key.
         }
     }
 
     if (nZapSelectTxRet != DB_LOAD_OK) {
         return nZapSelectTxRet;
     }
 
     MarkDirty();
 
     return DB_LOAD_OK;
 }
 
 DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx> &vWtx) {
     if (!fFileBacked) {
         return DB_LOAD_OK;
     }
 
     DBErrors nZapWalletTxRet =
         CWalletDB(strWalletFile, "cr+").ZapWalletTx(this, vWtx);
     if (nZapWalletTxRet == DB_NEED_REWRITE) {
         if (CDB::Rewrite(strWalletFile, "\x04pool")) {
             LOCK(cs_wallet);
             setKeyPool.clear();
             // Note: can't top-up keypool here, because wallet is locked. User
             // will be prompted to unlock wallet the next operation that
             // requires a new key.
         }
     }
 
     if (nZapWalletTxRet != DB_LOAD_OK) {
         return nZapWalletTxRet;
     }
 
     return DB_LOAD_OK;
 }
 
 bool CWallet::SetAddressBook(const CTxDestination &address,
                              const std::string &strName,
                              const std::string &strPurpose) {
     bool fUpdated = false;
     {
         // mapAddressBook
         LOCK(cs_wallet);
         std::map<CTxDestination, CAddressBookData>::iterator mi =
             mapAddressBook.find(address);
         fUpdated = mi != mapAddressBook.end();
         mapAddressBook[address].name = strName;
         // Update purpose only if requested.
         if (!strPurpose.empty()) {
             mapAddressBook[address].purpose = strPurpose;
         }
     }
 
     NotifyAddressBookChanged(this, address, strName,
                              ::IsMine(*this, address) != ISMINE_NO, strPurpose,
                              (fUpdated ? CT_UPDATED : CT_NEW));
     if (!fFileBacked) {
         return false;
     }
 
     if (!strPurpose.empty() &&
         !CWalletDB(strWalletFile)
              .WritePurpose(CBitcoinAddress(address).ToString(), strPurpose)) {
         return false;
     }
 
     return CWalletDB(strWalletFile)
         .WriteName(CBitcoinAddress(address).ToString(), strName);
 }
 
 bool CWallet::DelAddressBook(const CTxDestination &address) {
     {
         // mapAddressBook
         LOCK(cs_wallet);
 
         if (fFileBacked) {
             // Delete destdata tuples associated with address.
             std::string strAddress = CBitcoinAddress(address).ToString();
             for (const std::pair<std::string, std::string> &item :
                  mapAddressBook[address].destdata) {
                 CWalletDB(strWalletFile).EraseDestData(strAddress, item.first);
             }
         }
         mapAddressBook.erase(address);
     }
 
     NotifyAddressBookChanged(this, address, "",
                              ::IsMine(*this, address) != ISMINE_NO, "",
                              CT_DELETED);
 
     if (!fFileBacked) {
         return false;
     }
 
     CWalletDB(strWalletFile).ErasePurpose(CBitcoinAddress(address).ToString());
     return CWalletDB(strWalletFile)
         .EraseName(CBitcoinAddress(address).ToString());
 }
 
 bool CWallet::SetDefaultKey(const CPubKey &vchPubKey) {
     if (fFileBacked && !CWalletDB(strWalletFile).WriteDefaultKey(vchPubKey)) {
         return false;
     }
 
     vchDefaultKey = vchPubKey;
     return true;
 }
 
 /**
  * Mark old keypool keys as used, and generate all new keys.
  */
 bool CWallet::NewKeyPool() {
     LOCK(cs_wallet);
     CWalletDB walletdb(strWalletFile);
     for (int64_t nIndex : setKeyPool) {
         walletdb.ErasePool(nIndex);
     }
     setKeyPool.clear();
 
     if (IsLocked()) {
         return false;
     }
 
     int64_t nKeys =
         std::max(GetArg("-keypool", DEFAULT_KEYPOOL_SIZE), int64_t(0));
     for (int i = 0; i < nKeys; i++) {
         int64_t nIndex = i + 1;
         walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey()));
         setKeyPool.insert(nIndex);
     }
 
     LogPrintf("CWallet::NewKeyPool wrote %d new keys\n", nKeys);
     return true;
 }
 
 bool CWallet::TopUpKeyPool(unsigned int kpSize) {
     LOCK(cs_wallet);
 
     if (IsLocked()) {
         return false;
     }
 
     CWalletDB walletdb(strWalletFile);
 
     // Top up key pool.
     unsigned int nTargetSize;
     if (kpSize > 0) {
         nTargetSize = kpSize;
     } else {
         nTargetSize =
             std::max(GetArg("-keypool", DEFAULT_KEYPOOL_SIZE), int64_t(0));
     }
 
     while (setKeyPool.size() < (nTargetSize + 1)) {
         int64_t nEnd = 1;
         if (!setKeyPool.empty()) {
             nEnd = *(--setKeyPool.end()) + 1;
         }
 
         if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey()))) {
             throw std::runtime_error(std::string(__func__) +
                                      ": writing generated key failed");
         }
 
         setKeyPool.insert(nEnd);
         LogPrintf("keypool added key %d, size=%u\n", nEnd, setKeyPool.size());
     }
 
     return true;
 }
 
 void CWallet::ReserveKeyFromKeyPool(int64_t &nIndex, CKeyPool &keypool) {
     nIndex = -1;
     keypool.vchPubKey = CPubKey();
 
     LOCK(cs_wallet);
 
     if (!IsLocked()) {
         TopUpKeyPool();
     }
 
     // Get the oldest key.
     if (setKeyPool.empty()) {
         return;
     }
 
     CWalletDB walletdb(strWalletFile);
 
     nIndex = *(setKeyPool.begin());
     setKeyPool.erase(setKeyPool.begin());
     if (!walletdb.ReadPool(nIndex, keypool)) {
         throw std::runtime_error(std::string(__func__) + ": read failed");
     }
 
     if (!HaveKey(keypool.vchPubKey.GetID())) {
         throw std::runtime_error(std::string(__func__) +
                                  ": unknown key in key pool");
     }
 
     assert(keypool.vchPubKey.IsValid());
     LogPrintf("keypool reserve %d\n", nIndex);
 }
 
 void CWallet::KeepKey(int64_t nIndex) {
     // Remove from key pool.
     if (fFileBacked) {
         CWalletDB walletdb(strWalletFile);
         walletdb.ErasePool(nIndex);
     }
 
     LogPrintf("keypool keep %d\n", nIndex);
 }
 
 void CWallet::ReturnKey(int64_t nIndex) {
     // Return to key pool.
     {
         LOCK(cs_wallet);
         setKeyPool.insert(nIndex);
     }
 
     LogPrintf("keypool return %d\n", nIndex);
 }
 
 bool CWallet::GetKeyFromPool(CPubKey &result) {
     LOCK(cs_wallet);
 
     int64_t nIndex = 0;
     CKeyPool keypool;
 
     ReserveKeyFromKeyPool(nIndex, keypool);
     if (nIndex == -1) {
         if (IsLocked()) {
             return false;
         }
 
         result = GenerateNewKey();
         return true;
     }
 
     KeepKey(nIndex);
     result = keypool.vchPubKey;
 
     return true;
 }
 
 int64_t CWallet::GetOldestKeyPoolTime() {
     LOCK(cs_wallet);
 
     // If the keypool is empty, return <NOW>
     if (setKeyPool.empty()) {
         return GetTime();
     }
 
     // Load oldest key from keypool, get time and return.
     CKeyPool keypool;
     CWalletDB walletdb(strWalletFile);
     int64_t nIndex = *(setKeyPool.begin());
     if (!walletdb.ReadPool(nIndex, keypool)) {
         throw std::runtime_error(std::string(__func__) +
                                  ": read oldest key in keypool failed");
     }
 
     assert(keypool.vchPubKey.IsValid());
     return keypool.nTime;
 }
 
 std::map<CTxDestination, CAmount> CWallet::GetAddressBalances() {
     std::map<CTxDestination, CAmount> balances;
 
     LOCK(cs_wallet);
     for (std::pair<uint256, CWalletTx> walletEntry : mapWallet) {
         CWalletTx *pcoin = &walletEntry.second;
 
         if (!pcoin->IsTrusted()) {
             continue;
         }
 
         if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0) {
             continue;
         }
 
         int nDepth = pcoin->GetDepthInMainChain();
         if (nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? 0 : 1)) {
             continue;
         }
 
         for (unsigned int i = 0; i < pcoin->tx->vout.size(); i++) {
             CTxDestination addr;
             if (!IsMine(pcoin->tx->vout[i])) {
                 continue;
             }
 
             if (!ExtractDestination(pcoin->tx->vout[i].scriptPubKey, addr)) {
                 continue;
             }
 
             CAmount n =
                 IsSpent(walletEntry.first, i) ? 0 : pcoin->tx->vout[i].nValue;
 
             if (!balances.count(addr)) balances[addr] = 0;
             balances[addr] += n;
         }
     }
 
     return balances;
 }
 
 std::set<std::set<CTxDestination>> CWallet::GetAddressGroupings() {
     // mapWallet
     AssertLockHeld(cs_wallet);
     std::set<std::set<CTxDestination>> groupings;
     std::set<CTxDestination> grouping;
 
     for (std::pair<uint256, CWalletTx> walletEntry : mapWallet) {
         CWalletTx *pcoin = &walletEntry.second;
 
         if (pcoin->tx->vin.size() > 0) {
             bool any_mine = false;
             // Group all input addresses with each other.
             for (CTxIn txin : pcoin->tx->vin) {
                 CTxDestination address;
                 // If this input isn't mine, ignore it.
                 if (!IsMine(txin)) {
                     continue;
                 }
 
                 if (!ExtractDestination(mapWallet[txin.prevout.hash]
                                             .tx->vout[txin.prevout.n]
                                             .scriptPubKey,
                                         address)) {
                     continue;
                 }
 
                 grouping.insert(address);
                 any_mine = true;
             }
 
             // Group change with input addresses.
             if (any_mine) {
                 for (CTxOut txout : pcoin->tx->vout) {
                     if (IsChange(txout)) {
                         CTxDestination txoutAddr;
                         if (!ExtractDestination(txout.scriptPubKey,
                                                 txoutAddr)) {
                             continue;
                         }
 
                         grouping.insert(txoutAddr);
                     }
                 }
             }
 
             if (grouping.size() > 0) {
                 groupings.insert(grouping);
                 grouping.clear();
             }
         }
 
         // Group lone addrs by themselves.
         for (unsigned int i = 0; i < pcoin->tx->vout.size(); i++)
             if (IsMine(pcoin->tx->vout[i])) {
                 CTxDestination address;
                 if (!ExtractDestination(pcoin->tx->vout[i].scriptPubKey,
                                         address)) {
                     continue;
                 }
 
                 grouping.insert(address);
                 groupings.insert(grouping);
                 grouping.clear();
             }
     }
 
     // A set of pointers to groups of addresses.
     std::set<std::set<CTxDestination> *> uniqueGroupings;
     // Map addresses to the unique group containing it.
     std::map<CTxDestination, std::set<CTxDestination> *> setmap;
     for (std::set<CTxDestination> _grouping : groupings) {
         // Make a set of all the groups hit by this new group.
         std::set<std::set<CTxDestination> *> hits;
         std::map<CTxDestination, std::set<CTxDestination> *>::iterator it;
         for (CTxDestination address : _grouping) {
             if ((it = setmap.find(address)) != setmap.end())
                 hits.insert((*it).second);
         }
 
         // Merge all hit groups into a new single group and delete old groups.
         std::set<CTxDestination> *merged =
             new std::set<CTxDestination>(_grouping);
         for (std::set<CTxDestination> *hit : hits) {
             merged->insert(hit->begin(), hit->end());
             uniqueGroupings.erase(hit);
             delete hit;
         }
         uniqueGroupings.insert(merged);
 
         // Update setmap.
         for (CTxDestination element : *merged) {
             setmap[element] = merged;
         }
     }
 
     std::set<std::set<CTxDestination>> ret;
     for (std::set<CTxDestination> *uniqueGrouping : uniqueGroupings) {
         ret.insert(*uniqueGrouping);
         delete uniqueGrouping;
     }
 
     return ret;
 }
 
 CAmount CWallet::GetAccountBalance(const std::string &strAccount, int nMinDepth,
                                    const isminefilter &filter) {
     CWalletDB walletdb(strWalletFile);
     return GetAccountBalance(walletdb, strAccount, nMinDepth, filter);
 }
 
 CAmount CWallet::GetAccountBalance(CWalletDB &walletdb,
                                    const std::string &strAccount, int nMinDepth,
                                    const isminefilter &filter) {
     CAmount nBalance = 0;
 
     // Tally wallet transactions.
     for (std::map<uint256, CWalletTx>::iterator it = mapWallet.begin();
          it != mapWallet.end(); ++it) {
         const CWalletTx &wtx = (*it).second;
         if (!CheckFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0 ||
             wtx.GetDepthInMainChain() < 0) {
             continue;
         }
 
         CAmount nReceived, nSent, nFee;
         wtx.GetAccountAmounts(strAccount, nReceived, nSent, nFee, filter);
 
         if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth) {
             nBalance += nReceived;
         }
 
         nBalance -= nSent + nFee;
     }
 
     // Tally internal accounting entries.
     nBalance += walletdb.GetAccountCreditDebit(strAccount);
 
     return nBalance;
 }
 
 std::set<CTxDestination>
 CWallet::GetAccountAddresses(const std::string &strAccount) const {
     LOCK(cs_wallet);
     std::set<CTxDestination> result;
     for (const std::pair<CTxDestination, CAddressBookData> &item :
          mapAddressBook) {
         const CTxDestination &address = item.first;
         const std::string &strName = item.second.name;
         if (strName == strAccount) {
             result.insert(address);
         }
     }
 
     return result;
 }
 
 bool CReserveKey::GetReservedKey(CPubKey &pubkey) {
     if (nIndex == -1) {
         CKeyPool keypool;
         pwallet->ReserveKeyFromKeyPool(nIndex, keypool);
         if (nIndex != -1) {
             vchPubKey = keypool.vchPubKey;
         } else {
             return false;
         }
     }
 
     assert(vchPubKey.IsValid());
     pubkey = vchPubKey;
     return true;
 }
 
 void CReserveKey::KeepKey() {
     if (nIndex != -1) {
         pwallet->KeepKey(nIndex);
     }
 
     nIndex = -1;
     vchPubKey = CPubKey();
 }
 
 void CReserveKey::ReturnKey() {
     if (nIndex != -1) {
         pwallet->ReturnKey(nIndex);
     }
 
     nIndex = -1;
     vchPubKey = CPubKey();
 }
 
 void CWallet::GetAllReserveKeys(std::set<CKeyID> &setAddress) const {
     setAddress.clear();
 
     CWalletDB walletdb(strWalletFile);
 
     LOCK2(cs_main, cs_wallet);
     for (const int64_t &id : setKeyPool) {
         CKeyPool keypool;
         if (!walletdb.ReadPool(id, keypool)) {
             throw std::runtime_error(std::string(__func__) + ": read failed");
         }
 
         assert(keypool.vchPubKey.IsValid());
         CKeyID keyID = keypool.vchPubKey.GetID();
         if (!HaveKey(keyID)) {
             throw std::runtime_error(std::string(__func__) +
                                      ": unknown key in key pool");
         }
 
         setAddress.insert(keyID);
     }
 }
 
 void CWallet::UpdatedTransaction(const uint256 &hashTx) {
     LOCK(cs_wallet);
     // Only notify UI if this transaction is in this wallet.
     std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(hashTx);
     if (mi != mapWallet.end()) {
         NotifyTransactionChanged(this, hashTx, CT_UPDATED);
     }
 }
 
 void CWallet::GetScriptForMining(boost::shared_ptr<CReserveScript> &script) {
     boost::shared_ptr<CReserveKey> rKey(new CReserveKey(this));
     CPubKey pubkey;
     if (!rKey->GetReservedKey(pubkey)) {
         return;
     }
 
     script = rKey;
     script->reserveScript = CScript() << ToByteVector(pubkey) << OP_CHECKSIG;
 }
 
 void CWallet::LockCoin(const COutPoint &output) {
     // setLockedCoins
     AssertLockHeld(cs_wallet);
     setLockedCoins.insert(output);
 }
 
 void CWallet::UnlockCoin(const COutPoint &output) {
     // setLockedCoins
     AssertLockHeld(cs_wallet);
     setLockedCoins.erase(output);
 }
 
 void CWallet::UnlockAllCoins() {
     // setLockedCoins
     AssertLockHeld(cs_wallet);
     setLockedCoins.clear();
 }
 
 bool CWallet::IsLockedCoin(uint256 hash, unsigned int n) const {
     // setLockedCoins
     AssertLockHeld(cs_wallet);
     COutPoint outpt(hash, n);
 
     return setLockedCoins.count(outpt) > 0;
 }
 
 void CWallet::ListLockedCoins(std::vector<COutPoint> &vOutpts) {
     // setLockedCoins
     AssertLockHeld(cs_wallet);
     for (std::set<COutPoint>::iterator it = setLockedCoins.begin();
          it != setLockedCoins.end(); it++) {
         COutPoint outpt = (*it);
         vOutpts.push_back(outpt);
     }
 }
 
 /** @} */ // end of Actions
 
 class CAffectedKeysVisitor : public boost::static_visitor<void> {
 private:
     const CKeyStore &keystore;
     std::vector<CKeyID> &vKeys;
 
 public:
     CAffectedKeysVisitor(const CKeyStore &keystoreIn,
                          std::vector<CKeyID> &vKeysIn)
         : keystore(keystoreIn), vKeys(vKeysIn) {}
 
     void Process(const CScript &script) {
         txnouttype type;
         std::vector<CTxDestination> vDest;
         int nRequired;
         if (ExtractDestinations(script, type, vDest, nRequired)) {
             for (const CTxDestination &dest : vDest) {
                 boost::apply_visitor(*this, dest);
             }
         }
     }
 
     void operator()(const CKeyID &keyId) {
         if (keystore.HaveKey(keyId)) {
             vKeys.push_back(keyId);
         }
     }
 
     void operator()(const CScriptID &scriptId) {
         CScript script;
         if (keystore.GetCScript(scriptId, script)) {
             Process(script);
         }
     }
 
     void operator()(const CNoDestination &none) {}
 };
 
 void CWallet::GetKeyBirthTimes(
     std::map<CTxDestination, int64_t> &mapKeyBirth) const {
     // mapKeyMetadata
     AssertLockHeld(cs_wallet);
     mapKeyBirth.clear();
 
     // Get birth times for keys with metadata.
     for (const auto &entry : mapKeyMetadata) {
         if (entry.second.nCreateTime) {
             mapKeyBirth[entry.first] = entry.second.nCreateTime;
         }
     }
 
     // Map in which we'll infer heights of other keys the tip can be
     // reorganized; use a 144-block safety margin.
     CBlockIndex *pindexMax =
         chainActive[std::max(0, chainActive.Height() - 144)];
     std::map<CKeyID, CBlockIndex *> mapKeyFirstBlock;
     std::set<CKeyID> setKeys;
     GetKeys(setKeys);
     for (const CKeyID &keyid : setKeys) {
         if (mapKeyBirth.count(keyid) == 0) {
             mapKeyFirstBlock[keyid] = pindexMax;
         }
     }
     setKeys.clear();
 
     // If there are no such keys, we're done.
     if (mapKeyFirstBlock.empty()) {
         return;
     }
 
     // Find first block that affects those keys, if there are any left.
     std::vector<CKeyID> vAffected;
     for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin();
          it != mapWallet.end(); it++) {
         // Iterate over all wallet transactions...
         const CWalletTx &wtx = (*it).second;
         BlockMap::const_iterator blit = mapBlockIndex.find(wtx.hashBlock);
         if (blit != mapBlockIndex.end() && chainActive.Contains(blit->second)) {
             // ... which are already in a block.
             int nHeight = blit->second->nHeight;
             for (const CTxOut &txout : wtx.tx->vout) {
                 // Iterate over all their outputs...
                 CAffectedKeysVisitor(*this, vAffected)
                     .Process(txout.scriptPubKey);
                 for (const CKeyID &keyid : vAffected) {
                     // ... and all their affected keys.
                     std::map<CKeyID, CBlockIndex *>::iterator rit =
                         mapKeyFirstBlock.find(keyid);
                     if (rit != mapKeyFirstBlock.end() &&
                         nHeight < rit->second->nHeight) {
                         rit->second = blit->second;
                     }
                 }
                 vAffected.clear();
             }
         }
     }
 
     // Extract block timestamps for those keys.
     for (std::map<CKeyID, CBlockIndex *>::const_iterator it =
              mapKeyFirstBlock.begin();
          it != mapKeyFirstBlock.end(); it++) {
         // Block times can be 2h off.
         mapKeyBirth[it->first] = it->second->GetBlockTime() - 7200;
     }
 }
 
 bool CWallet::AddDestData(const CTxDestination &dest, const std::string &key,
                           const std::string &value) {
     if (boost::get<CNoDestination>(&dest)) {
         return false;
     }
 
     mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
     if (!fFileBacked) {
         return true;
     }
 
     return CWalletDB(strWalletFile)
         .WriteDestData(CBitcoinAddress(dest).ToString(), key, value);
 }
 
 bool CWallet::EraseDestData(const CTxDestination &dest,
                             const std::string &key) {
     if (!mapAddressBook[dest].destdata.erase(key)) {
         return false;
     }
 
     if (!fFileBacked) {
         return true;
     }
 
     return CWalletDB(strWalletFile)
         .EraseDestData(CBitcoinAddress(dest).ToString(), key);
 }
 
 bool CWallet::LoadDestData(const CTxDestination &dest, const std::string &key,
                            const std::string &value) {
     mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
     return true;
 }
 
 bool CWallet::GetDestData(const CTxDestination &dest, const std::string &key,
                           std::string *value) const {
     std::map<CTxDestination, CAddressBookData>::const_iterator i =
         mapAddressBook.find(dest);
     if (i != mapAddressBook.end()) {
         CAddressBookData::StringMap::const_iterator j =
             i->second.destdata.find(key);
         if (j != i->second.destdata.end()) {
             if (value) {
                 *value = j->second;
             }
 
             return true;
         }
     }
 
     return false;
 }
 
 std::string CWallet::GetWalletHelpString(bool showDebug) {
     std::string strUsage = HelpMessageGroup(_("Wallet options:"));
     strUsage += HelpMessageOpt(
         "-disablewallet",
         _("Do not load the wallet and disable wallet RPC calls"));
     strUsage += HelpMessageOpt(
         "-keypool=<n>", strprintf(_("Set key pool size to <n> (default: %u)"),
                                   DEFAULT_KEYPOOL_SIZE));
     strUsage += HelpMessageOpt(
         "-fallbackfee=<amt>",
         strprintf(_("A fee rate (in %s/kB) that will be used when fee "
                     "estimation has insufficient data (default: %s)"),
                   CURRENCY_UNIT, FormatMoney(DEFAULT_FALLBACK_FEE)));
     strUsage += HelpMessageOpt(
         "-mintxfee=<amt>",
         strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee "
                     "for transaction creation (default: %s)"),
                   CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MINFEE)));
     strUsage += HelpMessageOpt(
         "-paytxfee=<amt>",
         strprintf(
             _("Fee (in %s/kB) to add to transactions you send (default: %s)"),
             CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK())));
     strUsage += HelpMessageOpt(
         "-rescan",
         _("Rescan the block chain for missing wallet transactions on startup"));
     strUsage += HelpMessageOpt(
         "-salvagewallet",
         _("Attempt to recover private keys from a corrupt wallet on startup"));
     if (showDebug) {
         strUsage += HelpMessageOpt(
             "-sendfreetransactions",
             strprintf(_("Send transactions as zero-fee transactions if "
                         "possible (default: %u)"),
                       DEFAULT_SEND_FREE_TRANSACTIONS));
     }
 
     strUsage +=
         HelpMessageOpt("-spendzeroconfchange",
                        strprintf(_("Spend unconfirmed change when sending "
                                    "transactions (default: %u)"),
                                  DEFAULT_SPEND_ZEROCONF_CHANGE));
     strUsage +=
         HelpMessageOpt("-txconfirmtarget=<n>",
                        strprintf(_("If paytxfee is not set, include enough fee "
                                    "so transactions begin confirmation on "
                                    "average within n blocks (default: %u)"),
                                  DEFAULT_TX_CONFIRM_TARGET));
     strUsage += HelpMessageOpt(
         "-usehd",
         _("Use hierarchical deterministic key generation (HD) after BIP32. "
           "Only has effect during wallet creation/first start") +
             " " + strprintf(_("(default: %u)"), DEFAULT_USE_HD_WALLET));
     strUsage += HelpMessageOpt("-upgradewallet",
                                _("Upgrade wallet to latest format on startup"));
     strUsage +=
         HelpMessageOpt("-wallet=<file>",
                        _("Specify wallet file (within data directory)") + " " +
                            strprintf(_("(default: %s)"), DEFAULT_WALLET_DAT));
     strUsage += HelpMessageOpt(
         "-walletbroadcast",
         _("Make the wallet broadcast transactions") + " " +
             strprintf(_("(default: %u)"), DEFAULT_WALLETBROADCAST));
     strUsage += HelpMessageOpt("-walletnotify=<cmd>",
                                _("Execute command when a wallet transaction "
                                  "changes (%s in cmd is replaced by TxID)"));
     strUsage += HelpMessageOpt(
         "-zapwallettxes=<mode>",
         _("Delete all wallet transactions and only recover those parts of the "
           "blockchain through -rescan on startup") +
             " " + _("(1 = keep tx meta data e.g. account owner and payment "
                     "request information, 2 = drop tx meta data)"));
 
     if (showDebug) {
         strUsage += HelpMessageGroup(_("Wallet debugging/testing options:"));
 
         strUsage += HelpMessageOpt(
             "-dblogsize=<n>",
             strprintf("Flush wallet database activity from memory to disk log "
                       "every <n> megabytes (default: %u)",
                       DEFAULT_WALLET_DBLOGSIZE));
         strUsage += HelpMessageOpt(
             "-flushwallet",
             strprintf("Run a thread to flush wallet periodically (default: %u)",
                       DEFAULT_FLUSHWALLET));
         strUsage += HelpMessageOpt(
             "-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db "
                                  "environment (default: %u)",
                                  DEFAULT_WALLET_PRIVDB));
         strUsage += HelpMessageOpt(
             "-walletrejectlongchains",
             strprintf(_("Wallet will not create transactions that violate "
                         "mempool chain limits (default: %u)"),
                       DEFAULT_WALLET_REJECT_LONG_CHAINS));
     }
 
     return strUsage;
 }
 
 CWallet *CWallet::CreateWalletFromFile(const std::string walletFile) {
     // Needed to restore wallet transaction meta data after -zapwallettxes
     std::vector<CWalletTx> vWtx;
 
     if (GetBoolArg("-zapwallettxes", false)) {
         uiInterface.InitMessage(_("Zapping all transactions from wallet..."));
 
         CWallet *tempWallet = new CWallet(walletFile);
         DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx);
         if (nZapWalletRet != DB_LOAD_OK) {
             InitError(
                 strprintf(_("Error loading %s: Wallet corrupted"), walletFile));
             return nullptr;
         }
 
         delete tempWallet;
         tempWallet = nullptr;
     }
 
     uiInterface.InitMessage(_("Loading wallet..."));
 
     int64_t nStart = GetTimeMillis();
     bool fFirstRun = true;
     CWallet *walletInstance = new CWallet(walletFile);
     DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun);
     if (nLoadWalletRet != DB_LOAD_OK) {
         if (nLoadWalletRet == DB_CORRUPT) {
             InitError(
                 strprintf(_("Error loading %s: Wallet corrupted"), walletFile));
             return nullptr;
         }
 
         if (nLoadWalletRet == DB_NONCRITICAL_ERROR) {
             InitWarning(strprintf(
                 _("Error reading %s! All keys read correctly, but transaction "
                   "data"
                   " or address book entries might be missing or incorrect."),
                 walletFile));
         } else if (nLoadWalletRet == DB_TOO_NEW) {
             InitError(strprintf(
                 _("Error loading %s: Wallet requires newer version of %s"),
                 walletFile, _(PACKAGE_NAME)));
             return nullptr;
         } else if (nLoadWalletRet == DB_NEED_REWRITE) {
             InitError(strprintf(
                 _("Wallet needed to be rewritten: restart %s to complete"),
                 _(PACKAGE_NAME)));
             return nullptr;
         } else {
             InitError(strprintf(_("Error loading %s"), walletFile));
             return nullptr;
         }
     }
 
     if (GetBoolArg("-upgradewallet", fFirstRun)) {
         int nMaxVersion = GetArg("-upgradewallet", 0);
         // The -upgradewallet without argument case
         if (nMaxVersion == 0) {
             LogPrintf("Performing wallet upgrade to %i\n", FEATURE_LATEST);
             nMaxVersion = CLIENT_VERSION;
             // permanently upgrade the wallet immediately
             walletInstance->SetMinVersion(FEATURE_LATEST);
         } else {
             LogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion);
         }
 
         if (nMaxVersion < walletInstance->GetVersion()) {
             InitError(_("Cannot downgrade wallet"));
             return nullptr;
         }
 
         walletInstance->SetMaxVersion(nMaxVersion);
     }
 
     if (fFirstRun) {
         // Create new keyUser and set as default key.
         if (GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET) &&
             !walletInstance->IsHDEnabled()) {
             // Generate a new master key.
             CPubKey masterPubKey = walletInstance->GenerateNewHDMasterKey();
             if (!walletInstance->SetHDMasterKey(masterPubKey)) {
                 throw std::runtime_error(std::string(__func__) +
                                          ": Storing master key failed");
             }
         }
 
         CPubKey newDefaultKey;
         if (walletInstance->GetKeyFromPool(newDefaultKey)) {
             walletInstance->SetDefaultKey(newDefaultKey);
             if (!walletInstance->SetAddressBook(
                     walletInstance->vchDefaultKey.GetID(), "", "receive")) {
                 InitError(_("Cannot write default address") += "\n");
                 return nullptr;
             }
         }
 
         walletInstance->SetBestChain(chainActive.GetLocator());
     } else if (IsArgSet("-usehd")) {
         bool useHD = GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET);
         if (walletInstance->IsHDEnabled() && !useHD) {
             InitError(strprintf(_("Error loading %s: You can't disable HD on a "
                                   "already existing HD wallet"),
                                 walletFile));
             return nullptr;
         }
 
         if (!walletInstance->IsHDEnabled() && useHD) {
             InitError(strprintf(_("Error loading %s: You can't enable HD on a "
                                   "already existing non-HD wallet"),
                                 walletFile));
             return nullptr;
         }
     }
 
     LogPrintf(" wallet      %15dms\n", GetTimeMillis() - nStart);
 
     RegisterValidationInterface(walletInstance);
 
     CBlockIndex *pindexRescan = chainActive.Tip();
     if (GetBoolArg("-rescan", false)) {
         pindexRescan = chainActive.Genesis();
     } else {
         CWalletDB walletdb(walletFile);
         CBlockLocator locator;
         if (walletdb.ReadBestBlock(locator)) {
             pindexRescan = FindForkInGlobalIndex(chainActive, locator);
         } else {
             pindexRescan = chainActive.Genesis();
         }
     }
 
     if (chainActive.Tip() && chainActive.Tip() != pindexRescan) {
         // We can't rescan beyond non-pruned blocks, stop and throw an error.
         // This might happen if a user uses a old wallet within a pruned node or
         // if he ran -disablewallet for a longer time, then decided to
         // re-enable.
         if (fPruneMode) {
             CBlockIndex *block = chainActive.Tip();
             while (block && block->pprev &&
                    (block->pprev->nStatus & BLOCK_HAVE_DATA) &&
                    block->pprev->nTx > 0 && pindexRescan != block) {
                 block = block->pprev;
             }
 
             if (pindexRescan != block) {
                 InitError(_("Prune: last wallet synchronisation goes beyond "
                             "pruned data. You need to -reindex (download the "
                             "whole blockchain again in case of pruned node)"));
                 return nullptr;
             }
         }
 
         uiInterface.InitMessage(_("Rescanning..."));
         LogPrintf("Rescanning last %i blocks (from block %i)...\n",
                   chainActive.Height() - pindexRescan->nHeight,
                   pindexRescan->nHeight);
         nStart = GetTimeMillis();
         walletInstance->ScanForWalletTransactions(pindexRescan, true);
         LogPrintf(" rescan      %15dms\n", GetTimeMillis() - nStart);
         walletInstance->SetBestChain(chainActive.GetLocator());
         CWalletDB::IncrementUpdateCounter();
 
         // Restore wallet transaction metadata after -zapwallettxes=1
         if (GetBoolArg("-zapwallettxes", false) &&
             GetArg("-zapwallettxes", "1") != "2") {
             CWalletDB walletdb(walletFile);
 
             for (const CWalletTx &wtxOld : vWtx) {
                 uint256 txid = wtxOld.GetId();
                 std::map<uint256, CWalletTx>::iterator mi =
                     walletInstance->mapWallet.find(txid);
                 if (mi != walletInstance->mapWallet.end()) {
                     const CWalletTx *copyFrom = &wtxOld;
                     CWalletTx *copyTo = &mi->second;
                     copyTo->mapValue = copyFrom->mapValue;
                     copyTo->vOrderForm = copyFrom->vOrderForm;
                     copyTo->nTimeReceived = copyFrom->nTimeReceived;
                     copyTo->nTimeSmart = copyFrom->nTimeSmart;
                     copyTo->fFromMe = copyFrom->fFromMe;
                     copyTo->strFromAccount = copyFrom->strFromAccount;
                     copyTo->nOrderPos = copyFrom->nOrderPos;
                     walletdb.WriteTx(*copyTo);
                 }
             }
         }
     }
 
     walletInstance->SetBroadcastTransactions(
         GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST));
 
     LOCK(walletInstance->cs_wallet);
     LogPrintf("setKeyPool.size() = %u\n", walletInstance->GetKeyPoolSize());
     LogPrintf("mapWallet.size() = %u\n", walletInstance->mapWallet.size());
     LogPrintf("mapAddressBook.size() = %u\n",
               walletInstance->mapAddressBook.size());
 
     return walletInstance;
 }
 
 bool CWallet::InitLoadWallet() {
     if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
         pwalletMain = nullptr;
         LogPrintf("Wallet disabled!\n");
         return true;
     }
 
     std::string walletFile = GetArg("-wallet", DEFAULT_WALLET_DAT);
 
     CWallet *const pwallet = CreateWalletFromFile(walletFile);
     if (!pwallet) {
         return false;
     }
 
     pwalletMain = pwallet;
 
     return true;
 }
 
 std::atomic<bool> CWallet::fFlushThreadRunning(false);
 
 void CWallet::postInitProcess(boost::thread_group &threadGroup) {
     // Add wallet transactions that aren't already in a block to mempool.
     // Do this here as mempool requires genesis block to be loaded.
     ReacceptWalletTransactions();
 
     // Run a thread to flush wallet periodically.
     if (!CWallet::fFlushThreadRunning.exchange(true)) {
         threadGroup.create_thread(ThreadFlushWalletDB);
     }
 }
 
 bool CWallet::ParameterInteraction() {
     if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
         return true;
     }
 
     if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) &&
         SoftSetBoolArg("-walletbroadcast", false)) {
         LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting "
                   "-walletbroadcast=0\n",
                   __func__);
     }
 
     if (GetBoolArg("-salvagewallet", false) &&
         SoftSetBoolArg("-rescan", true)) {
         // Rewrite just private keys: rescan to find transactions
         LogPrintf("%s: parameter interaction: -salvagewallet=1 -> setting "
                   "-rescan=1\n",
                   __func__);
     }
 
     // -zapwallettx implies a rescan
     if (GetBoolArg("-zapwallettxes", false) &&
         SoftSetBoolArg("-rescan", true)) {
         LogPrintf("%s: parameter interaction: -zapwallettxes=<mode> -> setting "
                   "-rescan=1\n",
                   __func__);
     }
 
     if (GetBoolArg("-sysperms", false)) {
         return InitError("-sysperms is not allowed in combination with enabled "
                          "wallet functionality");
     }
 
     if (GetArg("-prune", 0) && GetBoolArg("-rescan", false)) {
         return InitError(
             _("Rescans are not possible in pruned mode. You will need to use "
               "-reindex which will download the whole blockchain again."));
     }
 
     if (::minRelayTxFee.GetFeePerK() > HIGH_TX_FEE_PER_KB) {
         InitWarning(
             AmountHighWarn("-minrelaytxfee") + " " +
             _("The wallet will avoid paying less than the minimum relay fee."));
     }
 
     if (IsArgSet("-mintxfee")) {
         CAmount n = 0;
         if (!ParseMoney(GetArg("-mintxfee", ""), n) || 0 == n) {
             return InitError(AmountErrMsg("mintxfee", GetArg("-mintxfee", "")));
         }
 
         if (n > HIGH_TX_FEE_PER_KB) {
             InitWarning(AmountHighWarn("-mintxfee") + " " +
                         _("This is the minimum transaction fee you pay on "
                           "every transaction."));
         }
 
         CWallet::minTxFee = CFeeRate(n);
     }
 
     if (IsArgSet("-fallbackfee")) {
         CAmount nFeePerK = 0;
         if (!ParseMoney(GetArg("-fallbackfee", ""), nFeePerK)) {
             return InitError(
                 strprintf(_("Invalid amount for -fallbackfee=<amount>: '%s'"),
                           GetArg("-fallbackfee", "")));
         }
 
         if (nFeePerK > HIGH_TX_FEE_PER_KB) {
             InitWarning(AmountHighWarn("-fallbackfee") + " " +
                         _("This is the transaction fee you may pay when fee "
                           "estimates are not available."));
         }
 
         CWallet::fallbackFee = CFeeRate(nFeePerK);
     }
 
     if (IsArgSet("-paytxfee")) {
         CAmount nFeePerK = 0;
         if (!ParseMoney(GetArg("-paytxfee", ""), nFeePerK)) {
             return InitError(AmountErrMsg("paytxfee", GetArg("-paytxfee", "")));
         }
 
         if (nFeePerK > HIGH_TX_FEE_PER_KB) {
             InitWarning(AmountHighWarn("-paytxfee") + " " +
                         _("This is the transaction fee you will pay if you "
                           "send a transaction."));
         }
 
         payTxFee = CFeeRate(nFeePerK, 1000);
         if (payTxFee < ::minRelayTxFee) {
             return InitError(
                 strprintf(_("Invalid amount for -paytxfee=<amount>: '%s' (must "
                             "be at least %s)"),
                           GetArg("-paytxfee", ""), ::minRelayTxFee.ToString()));
         }
     }
 
     if (IsArgSet("-maxtxfee")) {
         CAmount nMaxFee = 0;
         if (!ParseMoney(GetArg("-maxtxfee", ""), nMaxFee)) {
             return InitError(AmountErrMsg("maxtxfee", GetArg("-maxtxfee", "")));
         }
 
         if (nMaxFee > HIGH_MAX_TX_FEE) {
             InitWarning(_("-maxtxfee is set very high! Fees this large could "
                           "be paid on a single transaction."));
         }
 
         maxTxFee = nMaxFee;
         if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee) {
             return InitError(
                 strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s' (must "
                             "be at least the minrelay fee of %s to prevent "
                             "stuck transactions)"),
                           GetArg("-maxtxfee", ""), ::minRelayTxFee.ToString()));
         }
     }
 
     nTxConfirmTarget = GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET);
     bSpendZeroConfChange =
         GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE);
     fSendFreeTransactions =
         GetBoolArg("-sendfreetransactions", DEFAULT_SEND_FREE_TRANSACTIONS);
 
     if (fSendFreeTransactions &&
         GetArg("-limitfreerelay", DEFAULT_LIMITFREERELAY) <= 0) {
         return InitError("Creation of free transactions with their relay "
                          "disabled is not supported.");
     }
 
     return true;
 }
 
 bool CWallet::BackupWallet(const std::string &strDest) {
     if (!fFileBacked) {
         return false;
     }
 
     while (true) {
         {
             LOCK(bitdb.cs_db);
             if (!bitdb.mapFileUseCount.count(strWalletFile) ||
                 bitdb.mapFileUseCount[strWalletFile] == 0) {
                 // Flush log data to the dat file.
                 bitdb.CloseDb(strWalletFile);
                 bitdb.CheckpointLSN(strWalletFile);
                 bitdb.mapFileUseCount.erase(strWalletFile);
 
                 // Copy wallet file.
                 boost::filesystem::path pathSrc = GetDataDir() / strWalletFile;
                 boost::filesystem::path pathDest(strDest);
                 if (boost::filesystem::is_directory(pathDest)) {
                     pathDest /= strWalletFile;
                 }
 
                 try {
 #if BOOST_VERSION >= 104000
                     boost::filesystem::copy_file(
                         pathSrc, pathDest,
                         boost::filesystem::copy_option::overwrite_if_exists);
 #else
                     boost::filesystem::copy_file(pathSrc, pathDest);
 #endif
                     LogPrintf("copied %s to %s\n", strWalletFile,
                               pathDest.string());
                     return true;
                 } catch (const boost::filesystem::filesystem_error &e) {
                     LogPrintf("error copying %s to %s - %s\n", strWalletFile,
                               pathDest.string(), e.what());
                     return false;
                 }
             }
         }
 
         MilliSleep(100);
     }
 
     return false;
 }
 
 CKeyPool::CKeyPool() {
     nTime = GetTime();
 }
 
 CKeyPool::CKeyPool(const CPubKey &vchPubKeyIn) {
     nTime = GetTime();
     vchPubKey = vchPubKeyIn;
 }
 
 CWalletKey::CWalletKey(int64_t nExpires) {
     nTimeCreated = (nExpires ? GetTime() : 0);
     nTimeExpires = nExpires;
 }
 
 void CMerkleTx::SetMerkleBranch(const CBlockIndex *pindex, int posInBlock) {
     // Update the tx's hashBlock
     hashBlock = pindex->GetBlockHash();
 
     // Set the position of the transaction in the block.
     nIndex = posInBlock;
 }
 
 int CMerkleTx::GetDepthInMainChain(const CBlockIndex *&pindexRet) const {
     if (hashUnset()) {
         return 0;
     }
 
     AssertLockHeld(cs_main);
 
     // Find the block it claims to be in.
     BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
     if (mi == mapBlockIndex.end()) {
         return 0;
     }
 
     CBlockIndex *pindex = (*mi).second;
     if (!pindex || !chainActive.Contains(pindex)) {
         return 0;
     }
 
     pindexRet = pindex;
     return ((nIndex == -1) ? (-1) : 1) *
            (chainActive.Height() - pindex->nHeight + 1);
 }
 
 int CMerkleTx::GetBlocksToMaturity() const {
     if (!IsCoinBase()) {
         return 0;
     }
 
     return std::max(0, (COINBASE_MATURITY + 1) - GetDepthInMainChain());
 }
 
 bool CMerkleTx::AcceptToMemoryPool(const CAmount &nAbsurdFee,
                                    CValidationState &state) {
     return ::AcceptToMemoryPool(GetConfig(), mempool, state, tx, true, nullptr,
                                 nullptr, false, nAbsurdFee);
 }
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 01eec0663..b5c180b53 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -1,1139 +1,1138 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_WALLET_WALLET_H
 #define BITCOIN_WALLET_WALLET_H
 
 #include "amount.h"
 #include "script/ismine.h"
 #include "script/sign.h"
 #include "streams.h"
 #include "tinyformat.h"
 #include "ui_interface.h"
 #include "utilstrencodings.h"
 #include "validationinterface.h"
 #include "wallet/crypter.h"
 #include "wallet/rpcwallet.h"
 #include "wallet/walletdb.h"
 
 #include <algorithm>
 #include <atomic>
 #include <cstdint>
 #include <map>
 #include <set>
 #include <stdexcept>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include <boost/shared_ptr.hpp>
 #include <boost/thread.hpp>
 
 extern CWallet *pwalletMain;
 
 /**
  * Settings
  */
 extern CFeeRate payTxFee;
 extern unsigned int nTxConfirmTarget;
 extern bool bSpendZeroConfChange;
 extern bool fSendFreeTransactions;
 
 static const unsigned int DEFAULT_KEYPOOL_SIZE = 100;
 //! -paytxfee default
 static const CAmount DEFAULT_TRANSACTION_FEE = 0;
 //! -fallbackfee default
 static const CAmount DEFAULT_FALLBACK_FEE = 20000;
 //! -mintxfee default
 static const CAmount DEFAULT_TRANSACTION_MINFEE = 1000;
 //! minimum recommended increment for BIP 125 replacement txs
 static const CAmount WALLET_INCREMENTAL_RELAY_FEE = 5000;
 //! target minimum change amount
 static const CAmount MIN_CHANGE = CENT;
 //! final minimum change amount after paying for fees
 static const CAmount MIN_FINAL_CHANGE = MIN_CHANGE / 2;
 //! Default for -spendzeroconfchange
 static const bool DEFAULT_SPEND_ZEROCONF_CHANGE = true;
 //! Default for -sendfreetransactions
 static const bool DEFAULT_SEND_FREE_TRANSACTIONS = false;
 //! Default for -walletrejectlongchains
 static const bool DEFAULT_WALLET_REJECT_LONG_CHAINS = false;
 //! -txconfirmtarget default
 static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 6;
 //! Largest (in bytes) free transaction we're willing to create
 static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000;
 static const bool DEFAULT_WALLETBROADCAST = true;
 static const bool DEFAULT_DISABLE_WALLET = false;
 //! if set, all keys will be derived by using BIP32
 static const bool DEFAULT_USE_HD_WALLET = true;
 
 extern const char *DEFAULT_WALLET_DAT;
 
 class CBlockIndex;
 class CCoinControl;
 class COutput;
 class CReserveKey;
 class CScript;
 class CTxMemPool;
 class CWalletTx;
 
 /** (client) version numbers for particular wallet features */
 enum WalletFeature {
     // the earliest version new wallets supports (only useful for getinfo's
     // clientversion output)
     FEATURE_BASE = 10500,
 
     // wallet encryption
     FEATURE_WALLETCRYPT = 40000,
     // compressed public keys
     FEATURE_COMPRPUBKEY = 60000,
 
     // Hierarchical key derivation after BIP32 (HD Wallet)
     FEATURE_HD = 130000,
 
     // HD is optional, use FEATURE_COMPRPUBKEY as latest version
     FEATURE_LATEST = FEATURE_COMPRPUBKEY,
 };
 
 /** A key pool entry */
 class CKeyPool {
 public:
     int64_t nTime;
     CPubKey vchPubKey;
 
     CKeyPool();
     CKeyPool(const CPubKey &vchPubKeyIn);
 
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
     inline void SerializationOp(Stream &s, Operation ser_action) {
         int nVersion = s.GetVersion();
         if (!(s.GetType() & SER_GETHASH)) {
             READWRITE(nVersion);
         }
 
         READWRITE(nTime);
         READWRITE(vchPubKey);
     }
 };
 
 /** Address book data */
 class CAddressBookData {
 public:
     std::string name;
     std::string purpose;
 
     CAddressBookData() { purpose = "unknown"; }
 
     typedef std::map<std::string, std::string> StringMap;
     StringMap destdata;
 };
 
 struct CRecipient {
     CScript scriptPubKey;
     CAmount nAmount;
     bool fSubtractFeeFromAmount;
 };
 
 typedef std::map<std::string, std::string> mapValue_t;
 
 static inline void ReadOrderPos(int64_t &nOrderPos, mapValue_t &mapValue) {
     if (!mapValue.count("n")) {
         // TODO: calculate elsewhere
         nOrderPos = -1;
         return;
     }
 
     nOrderPos = atoi64(mapValue["n"].c_str());
 }
 
 static inline void WriteOrderPos(const int64_t &nOrderPos,
                                  mapValue_t &mapValue) {
     if (nOrderPos == -1) return;
     mapValue["n"] = i64tostr(nOrderPos);
 }
 
 struct COutputEntry {
     CTxDestination destination;
     CAmount amount;
     int vout;
 };
 
 /** A transaction with a merkle branch linking it to the block chain. */
 class CMerkleTx {
 private:
     /** Constant used in hashBlock to indicate tx has been abandoned */
     static const uint256 ABANDON_HASH;
 
 public:
     CTransactionRef tx;
     uint256 hashBlock;
 
     /**
      * An nIndex == -1 means that hashBlock (in nonzero) refers to the earliest
      * block in the chain we know this or any in-wallet dependency conflicts
      * with. Older clients interpret nIndex == -1 as unconfirmed for backward
      * compatibility.
      */
     int nIndex;
 
     CMerkleTx() {
         SetTx(MakeTransactionRef());
         Init();
     }
 
     CMerkleTx(CTransactionRef arg) {
         SetTx(std::move(arg));
         Init();
     }
 
     /**
      * Helper conversion operator to allow passing CMerkleTx where CTransaction
      * is expected.
      * TODO: adapt callers and remove this operator.
      */
     operator const CTransaction &() const { return *tx; }
 
     void Init() {
         hashBlock = uint256();
         nIndex = -1;
     }
 
     void SetTx(CTransactionRef arg) { tx = std::move(arg); }
 
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
     inline void SerializationOp(Stream &s, Operation ser_action) {
         // For compatibility with older versions.
         std::vector<uint256> vMerkleBranch;
         READWRITE(tx);
         READWRITE(hashBlock);
         READWRITE(vMerkleBranch);
         READWRITE(nIndex);
     }
 
     void SetMerkleBranch(const CBlockIndex *pIndex, int posInBlock);
 
     /**
      * Return depth of transaction in blockchain:
      * <0  : conflicts with a transaction this deep in the blockchain
      *  0  : in memory pool, waiting to be included in a block
      * >=1 : this many blocks deep in the main chain
      */
     int GetDepthInMainChain(const CBlockIndex *&pindexRet) const;
     int GetDepthInMainChain() const {
         const CBlockIndex *pindexRet;
         return GetDepthInMainChain(pindexRet);
     }
     bool IsInMainChain() const {
         const CBlockIndex *pindexRet;
         return GetDepthInMainChain(pindexRet) > 0;
     }
     int GetBlocksToMaturity() const;
     /**
      * Pass this transaction to the mempool. Fails if absolute fee exceeds
      * absurd fee.
      */
     bool AcceptToMemoryPool(const CAmount &nAbsurdFee, CValidationState &state);
     bool hashUnset() const {
         return (hashBlock.IsNull() || hashBlock == ABANDON_HASH);
     }
     bool isAbandoned() const { return (hashBlock == ABANDON_HASH); }
     void setAbandoned() { hashBlock = ABANDON_HASH; }
 
     const uint256 &GetId() const { return tx->GetId(); }
     bool IsCoinBase() const { return tx->IsCoinBase(); }
 };
 
 /**
  * A transaction with a bunch of additional info that only the owner cares
  * about. It includes any unrecorded transactions needed to link it back to the
  * block chain.
  */
 class CWalletTx : public CMerkleTx {
 private:
     const CWallet *pwallet;
 
 public:
     mapValue_t mapValue;
     std::vector<std::pair<std::string, std::string>> vOrderForm;
     unsigned int fTimeReceivedIsTxTime;
     //!< time received by this node
     unsigned int nTimeReceived;
     unsigned int nTimeSmart;
     /**
      * From me flag is set to 1 for transactions that were created by the wallet
      * on this bitcoin node, and set to 0 for transactions that were created
      * externally and came in through the network or sendrawtransaction RPC.
      */
     char fFromMe;
     std::string strFromAccount;
     //!< position in ordered transaction list
     int64_t nOrderPos;
 
     // memory only
     mutable bool fDebitCached;
     mutable bool fCreditCached;
     mutable bool fImmatureCreditCached;
     mutable bool fAvailableCreditCached;
     mutable bool fWatchDebitCached;
     mutable bool fWatchCreditCached;
     mutable bool fImmatureWatchCreditCached;
     mutable bool fAvailableWatchCreditCached;
     mutable bool fChangeCached;
     mutable CAmount nDebitCached;
     mutable CAmount nCreditCached;
     mutable CAmount nImmatureCreditCached;
     mutable CAmount nAvailableCreditCached;
     mutable CAmount nWatchDebitCached;
     mutable CAmount nWatchCreditCached;
     mutable CAmount nImmatureWatchCreditCached;
     mutable CAmount nAvailableWatchCreditCached;
     mutable CAmount nChangeCached;
 
     CWalletTx() { Init(nullptr); }
 
     CWalletTx(const CWallet *pwalletIn, CTransactionRef arg)
         : CMerkleTx(std::move(arg)) {
         Init(pwalletIn);
     }
 
     void Init(const CWallet *pwalletIn) {
         pwallet = pwalletIn;
         mapValue.clear();
         vOrderForm.clear();
         fTimeReceivedIsTxTime = false;
         nTimeReceived = 0;
         nTimeSmart = 0;
         fFromMe = false;
         strFromAccount.clear();
         fDebitCached = false;
         fCreditCached = false;
         fImmatureCreditCached = false;
         fAvailableCreditCached = false;
         fWatchDebitCached = false;
         fWatchCreditCached = false;
         fImmatureWatchCreditCached = false;
         fAvailableWatchCreditCached = false;
         fChangeCached = false;
         nDebitCached = 0;
         nCreditCached = 0;
         nImmatureCreditCached = 0;
         nAvailableCreditCached = 0;
         nWatchDebitCached = 0;
         nWatchCreditCached = 0;
         nAvailableWatchCreditCached = 0;
         nImmatureWatchCreditCached = 0;
         nChangeCached = 0;
         nOrderPos = -1;
     }
 
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
     inline void SerializationOp(Stream &s, Operation ser_action) {
         if (ser_action.ForRead()) Init(nullptr);
         char fSpent = false;
 
         if (!ser_action.ForRead()) {
             mapValue["fromaccount"] = strFromAccount;
 
             WriteOrderPos(nOrderPos, mapValue);
 
             if (nTimeSmart) mapValue["timesmart"] = strprintf("%u", nTimeSmart);
         }
 
         READWRITE(*(CMerkleTx *)this);
         //!< Used to be vtxPrev
         std::vector<CMerkleTx> vUnused;
         READWRITE(vUnused);
         READWRITE(mapValue);
         READWRITE(vOrderForm);
         READWRITE(fTimeReceivedIsTxTime);
         READWRITE(nTimeReceived);
         READWRITE(fFromMe);
         READWRITE(fSpent);
 
         if (ser_action.ForRead()) {
             strFromAccount = mapValue["fromaccount"];
 
             ReadOrderPos(nOrderPos, mapValue);
 
             nTimeSmart = mapValue.count("timesmart")
                              ? (unsigned int)atoi64(mapValue["timesmart"])
                              : 0;
         }
 
         mapValue.erase("fromaccount");
         mapValue.erase("version");
         mapValue.erase("spent");
         mapValue.erase("n");
         mapValue.erase("timesmart");
     }
 
     //! make sure balances are recalculated
     void MarkDirty() {
         fCreditCached = false;
         fAvailableCreditCached = false;
         fImmatureCreditCached = false;
         fWatchDebitCached = false;
         fWatchCreditCached = false;
         fAvailableWatchCreditCached = false;
         fImmatureWatchCreditCached = false;
         fDebitCached = false;
         fChangeCached = false;
     }
 
     void BindWallet(CWallet *pwalletIn) {
         pwallet = pwalletIn;
         MarkDirty();
     }
 
     //! filter decides which addresses will count towards the debit
     CAmount GetDebit(const isminefilter &filter) const;
     CAmount GetCredit(const isminefilter &filter) const;
     CAmount GetImmatureCredit(bool fUseCache = true) const;
     CAmount GetAvailableCredit(bool fUseCache = true) const;
     CAmount GetImmatureWatchOnlyCredit(const bool &fUseCache = true) const;
     CAmount GetAvailableWatchOnlyCredit(const bool &fUseCache = true) const;
     CAmount GetChange() const;
 
     void GetAmounts(std::list<COutputEntry> &listReceived,
                     std::list<COutputEntry> &listSent, CAmount &nFee,
                     std::string &strSentAccount,
                     const isminefilter &filter) const;
 
     void GetAccountAmounts(const std::string &strAccount, CAmount &nReceived,
                            CAmount &nSent, CAmount &nFee,
                            const isminefilter &filter) const;
 
     bool IsFromMe(const isminefilter &filter) const {
         return (GetDebit(filter) > 0);
     }
 
     // True if only scriptSigs are different
     bool IsEquivalentTo(const CWalletTx &tx) const;
 
     bool InMempool() const;
     bool IsTrusted() const;
 
     int64_t GetTxTime() const;
     int GetRequestCount() const;
 
     bool RelayWalletTransaction(CConnman *connman);
 
     std::set<uint256> GetConflicts() const;
 };
 
 class COutput {
 public:
     const CWalletTx *tx;
     int i;
     int nDepth;
     bool fSpendable;
     bool fSolvable;
 
     COutput(const CWalletTx *txIn, int iIn, int nDepthIn, bool fSpendableIn,
             bool fSolvableIn) {
         tx = txIn;
         i = iIn;
         nDepth = nDepthIn;
         fSpendable = fSpendableIn;
         fSolvable = fSolvableIn;
     }
 
     std::string ToString() const;
 };
 
 /** Private key that includes an expiration date in case it never gets used. */
 class CWalletKey {
 public:
     CPrivKey vchPrivKey;
     int64_t nTimeCreated;
     int64_t nTimeExpires;
     std::string strComment;
     //! todo: add something to note what created it (user, getnewaddress,
     //! change) maybe should have a map<string, string> property map
 
     CWalletKey(int64_t nExpires = 0);
 
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
     inline void SerializationOp(Stream &s, Operation ser_action) {
         int nVersion = s.GetVersion();
         if (!(s.GetType() & SER_GETHASH)) READWRITE(nVersion);
         READWRITE(vchPrivKey);
         READWRITE(nTimeCreated);
         READWRITE(nTimeExpires);
         READWRITE(LIMITED_STRING(strComment, 65536));
     }
 };
 
 /**
  * Internal transfers.
  * Database key is acentry<account><counter>.
  */
 class CAccountingEntry {
 public:
     std::string strAccount;
     CAmount nCreditDebit;
     int64_t nTime;
     std::string strOtherAccount;
     std::string strComment;
     mapValue_t mapValue;
     //!< position in ordered transaction list
     int64_t nOrderPos;
     uint64_t nEntryNo;
 
     CAccountingEntry() { SetNull(); }
 
     void SetNull() {
         nCreditDebit = 0;
         nTime = 0;
         strAccount.clear();
         strOtherAccount.clear();
         strComment.clear();
         nOrderPos = -1;
         nEntryNo = 0;
     }
 
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
     inline void SerializationOp(Stream &s, Operation ser_action) {
         int nVersion = s.GetVersion();
         if (!(s.GetType() & SER_GETHASH)) READWRITE(nVersion);
         //! Note: strAccount is serialized as part of the key, not here.
         READWRITE(nCreditDebit);
         READWRITE(nTime);
         READWRITE(LIMITED_STRING(strOtherAccount, 65536));
 
         if (!ser_action.ForRead()) {
             WriteOrderPos(nOrderPos, mapValue);
 
             if (!(mapValue.empty() && _ssExtra.empty())) {
                 CDataStream ss(s.GetType(), s.GetVersion());
                 ss.insert(ss.begin(), '\0');
                 ss << mapValue;
                 ss.insert(ss.end(), _ssExtra.begin(), _ssExtra.end());
                 strComment.append(ss.str());
             }
         }
 
         READWRITE(LIMITED_STRING(strComment, 65536));
 
         size_t nSepPos = strComment.find("\0", 0, 1);
         if (ser_action.ForRead()) {
             mapValue.clear();
             if (std::string::npos != nSepPos) {
                 CDataStream ss(
                     std::vector<char>(strComment.begin() + nSepPos + 1,
                                       strComment.end()),
                     s.GetType(), s.GetVersion());
                 ss >> mapValue;
                 _ssExtra = std::vector<char>(ss.begin(), ss.end());
             }
             ReadOrderPos(nOrderPos, mapValue);
         }
         if (std::string::npos != nSepPos) strComment.erase(nSepPos);
 
         mapValue.erase("n");
     }
 
 private:
     std::vector<char> _ssExtra;
 };
 
 /**
  * A CWallet is an extension of a keystore, which also maintains a set of
  * transactions and balances, and provides the ability to create new
  * transactions.
  */
 class CWallet : public CCryptoKeyStore, public CValidationInterface {
 private:
     static std::atomic<bool> fFlushThreadRunning;
 
     /**
      * Select a set of coins such that nValueRet >= nTargetValue and at least
      * all coins from coinControl are selected; Never select unconfirmed coins
      * if they are not ours.
      */
     bool SelectCoins(
         const std::vector<COutput> &vAvailableCoins,
         const CAmount &nTargetValue,
         std::set<std::pair<const CWalletTx *, unsigned int>> &setCoinsRet,
         CAmount &nValueRet, const CCoinControl *coinControl = nullptr) const;
 
     CWalletDB *pwalletdbEncryption;
 
     //! the current wallet version: clients below this version are not able to
     //! load the wallet
     int nWalletVersion;
 
     //! the maximum wallet format version: memory-only variable that specifies
     //! to what version this wallet may be upgraded
     int nWalletMaxVersion;
 
     int64_t nNextResend;
     int64_t nLastResend;
     bool fBroadcastTransactions;
 
     /**
      * Used to keep track of spent outpoints, and detect and report conflicts
      * (double-spends or mutated transactions where the mutant gets mined).
      */
     typedef std::multimap<COutPoint, uint256> TxSpends;
     TxSpends mapTxSpends;
     void AddToSpends(const COutPoint &outpoint, const uint256 &wtxid);
     void AddToSpends(const uint256 &wtxid);
 
     /* Mark a transaction (and its in-wallet descendants) as conflicting with a
      * particular block. */
     void MarkConflicted(const uint256 &hashBlock, const uint256 &hashTx);
 
     void SyncMetaData(std::pair<TxSpends::iterator, TxSpends::iterator>);
 
     /* the HD chain data model (external chain counters) */
     CHDChain hdChain;
 
     bool fFileBacked;
 
     std::set<int64_t> setKeyPool;
 
     int64_t nTimeFirstKey;
 
     /**
      * Private version of AddWatchOnly method which does not accept a timestamp,
      * and which will reset the wallet's nTimeFirstKey value to 1 if the watch
      * key did not previously have a timestamp associated with it. Because this
      * is an inherited virtual method, it is accessible despite being marked
      * private, but it is marked private anyway to encourage use of the other
      * AddWatchOnly which accepts a timestamp and sets nTimeFirstKey more
      * intelligently for more efficient rescans.
      */
     bool AddWatchOnly(const CScript &dest) override;
 
 public:
     /*
      * Main wallet lock.
      * This lock protects all the fields added by CWallet
      *   except for:
      *      fFileBacked (immutable after instantiation)
      *      strWalletFile (immutable after instantiation)
      */
     mutable CCriticalSection cs_wallet;
 
     const std::string strWalletFile;
 
     void LoadKeyPool(int nIndex, const CKeyPool &keypool) {
         setKeyPool.insert(nIndex);
 
         // If no metadata exists yet, create a default with the pool key's
         // creation time. Note that this may be overwritten by actually stored
         // metadata for that key later, which is fine.
         CKeyID keyid = keypool.vchPubKey.GetID();
         if (mapKeyMetadata.count(keyid) == 0)
             mapKeyMetadata[keyid] = CKeyMetadata(keypool.nTime);
     }
 
     // Map from Key ID (for regular keys) or Script ID (for watch-only keys) to
     // key metadata.
     std::map<CTxDestination, CKeyMetadata> mapKeyMetadata;
 
     typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
     MasterKeyMap mapMasterKeys;
     unsigned int nMasterKeyMaxID;
 
     CWallet() { SetNull(); }
 
     CWallet(const std::string &strWalletFileIn)
         : strWalletFile(strWalletFileIn) {
         SetNull();
         fFileBacked = true;
     }
 
     ~CWallet() {
         delete pwalletdbEncryption;
         pwalletdbEncryption = nullptr;
     }
 
     void SetNull() {
         nWalletVersion = FEATURE_BASE;
         nWalletMaxVersion = FEATURE_BASE;
         fFileBacked = false;
         nMasterKeyMaxID = 0;
         pwalletdbEncryption = nullptr;
         nOrderPosNext = 0;
         nNextResend = 0;
         nLastResend = 0;
         nTimeFirstKey = 0;
         fBroadcastTransactions = false;
     }
 
     std::map<uint256, CWalletTx> mapWallet;
     std::list<CAccountingEntry> laccentries;
 
     typedef std::pair<CWalletTx *, CAccountingEntry *> TxPair;
     typedef std::multimap<int64_t, TxPair> TxItems;
     TxItems wtxOrdered;
 
     int64_t nOrderPosNext;
     std::map<uint256, int> mapRequestCount;
 
     std::map<CTxDestination, CAddressBookData> mapAddressBook;
 
     CPubKey vchDefaultKey;
 
     std::set<COutPoint> setLockedCoins;
 
     const CWalletTx *GetWalletTx(const uint256 &hash) const;
 
     //! check whether we are allowed to upgrade (or already support) to the
     //! named feature
     bool CanSupportFeature(enum WalletFeature wf) {
         AssertLockHeld(cs_wallet);
         return nWalletMaxVersion >= wf;
     }
 
     /**
      * populate vCoins with vector of available COutputs.
      */
     void AvailableCoins(std::vector<COutput> &vCoins,
                         bool fOnlyConfirmed = true,
                         const CCoinControl *coinControl = nullptr,
                         bool fIncludeZeroValue = false) const;
 
     /**
      * Shuffle and select coins until nTargetValue is reached while avoiding
      * small change; This method is stochastic for some inputs and upon
      * completion the coin set and corresponding actual target value is
      * assembled.
      */
     bool SelectCoinsMinConf(
         const CAmount &nTargetValue, int nConfMine, int nConfTheirs,
         uint64_t nMaxAncestors, std::vector<COutput> vCoins,
         std::set<std::pair<const CWalletTx *, unsigned int>> &setCoinsRet,
         CAmount &nValueRet) const;
 
     bool IsSpent(const uint256 &hash, unsigned int n) const;
 
     bool IsLockedCoin(uint256 hash, unsigned int n) const;
     void LockCoin(const COutPoint &output);
     void UnlockCoin(const COutPoint &output);
     void UnlockAllCoins();
     void ListLockedCoins(std::vector<COutPoint> &vOutpts);
 
     /**
      * keystore implementation
      * Generate a new key
      */
     CPubKey GenerateNewKey();
     void DeriveNewChildKey(CKeyMetadata &metadata, CKey &secret);
     //! Adds a key to the store, and saves it to disk.
     bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey) override;
     //! Adds a key to the store, without saving it to disk (used by LoadWallet)
     bool LoadKey(const CKey &key, const CPubKey &pubkey) {
         return CCryptoKeyStore::AddKeyPubKey(key, pubkey);
     }
 
     //! Load metadata (used by LoadWallet)
     bool LoadKeyMetadata(const CTxDestination &pubKey,
                          const CKeyMetadata &metadata);
 
     bool LoadMinVersion(int nVersion) {
         AssertLockHeld(cs_wallet);
         nWalletVersion = nVersion;
         nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion);
         return true;
     }
     void UpdateTimeFirstKey(int64_t nCreateTime);
 
     //! Adds an encrypted key to the store, and saves it to disk.
-    bool
-    AddCryptedKey(const CPubKey &vchPubKey,
-                  const std::vector<unsigned char> &vchCryptedSecret) override;
+    bool AddCryptedKey(const CPubKey &vchPubKey,
+                       const std::vector<uint8_t> &vchCryptedSecret) override;
     //! Adds an encrypted key to the store, without saving it to disk (used by
     //! LoadWallet)
     bool LoadCryptedKey(const CPubKey &vchPubKey,
-                        const std::vector<unsigned char> &vchCryptedSecret);
+                        const std::vector<uint8_t> &vchCryptedSecret);
     bool AddCScript(const CScript &redeemScript) override;
     bool LoadCScript(const CScript &redeemScript);
 
     //! Adds a destination data tuple to the store, and saves it to disk
     bool AddDestData(const CTxDestination &dest, const std::string &key,
                      const std::string &value);
     //! Erases a destination data tuple in the store and on disk
     bool EraseDestData(const CTxDestination &dest, const std::string &key);
     //! Adds a destination data tuple to the store, without saving it to disk
     bool LoadDestData(const CTxDestination &dest, const std::string &key,
                       const std::string &value);
     //! Look up a destination data tuple in the store, return true if found
     //! false otherwise
     bool GetDestData(const CTxDestination &dest, const std::string &key,
                      std::string *value) const;
 
     //! Adds a watch-only address to the store, and saves it to disk.
     bool AddWatchOnly(const CScript &dest, int64_t nCreateTime);
     bool RemoveWatchOnly(const CScript &dest) override;
     //! Adds a watch-only address to the store, without saving it to disk (used
     //! by LoadWallet)
     bool LoadWatchOnly(const CScript &dest);
 
     bool Unlock(const SecureString &strWalletPassphrase);
     bool ChangeWalletPassphrase(const SecureString &strOldWalletPassphrase,
                                 const SecureString &strNewWalletPassphrase);
     bool EncryptWallet(const SecureString &strWalletPassphrase);
 
     void GetKeyBirthTimes(std::map<CTxDestination, int64_t> &mapKeyBirth) const;
 
     /**
      * Increment the next transaction order id
      * @return next transaction order id
      */
     int64_t IncOrderPosNext(CWalletDB *pwalletdb = nullptr);
     DBErrors ReorderTransactions();
     bool AccountMove(std::string strFrom, std::string strTo, CAmount nAmount,
                      std::string strComment = "");
     bool GetAccountPubkey(CPubKey &pubKey, std::string strAccount,
                           bool bForceNew = false);
 
     void MarkDirty();
     bool AddToWallet(const CWalletTx &wtxIn, bool fFlushOnClose = true);
     bool LoadToWallet(const CWalletTx &wtxIn);
     void SyncTransaction(const CTransaction &tx, const CBlockIndex *pindex,
                          int posInBlock) override;
     bool AddToWalletIfInvolvingMe(const CTransaction &tx,
                                   const CBlockIndex *pIndex, int posInBlock,
                                   bool fUpdate);
     CBlockIndex *ScanForWalletTransactions(CBlockIndex *pindexStart,
                                            bool fUpdate = false);
     void ReacceptWalletTransactions();
     void ResendWalletTransactions(int64_t nBestBlockTime,
                                   CConnman *connman) override;
     std::vector<uint256> ResendWalletTransactionsBefore(int64_t nTime,
                                                         CConnman *connman);
     CAmount GetBalance() const;
     CAmount GetUnconfirmedBalance() const;
     CAmount GetImmatureBalance() const;
     CAmount GetWatchOnlyBalance() const;
     CAmount GetUnconfirmedWatchOnlyBalance() const;
     CAmount GetImmatureWatchOnlyBalance() const;
 
     /**
      * Insert additional inputs into the transaction by calling
      * CreateTransaction();
      */
     bool FundTransaction(CMutableTransaction &tx, CAmount &nFeeRet,
                          bool overrideEstimatedFeeRate,
                          const CFeeRate &specificFeeRate, int &nChangePosInOut,
                          std::string &strFailReason, bool includeWatching,
                          bool lockUnspents,
                          const std::set<int> &setSubtractFeeFromOutputs,
                          bool keepReserveKey = true,
                          const CTxDestination &destChange = CNoDestination());
 
     /**
      * Create a new transaction paying the recipients with a set of coins
      * selected by SelectCoins(); Also create the change output, when needed
      * @note passing nChangePosInOut as -1 will result in setting a random
      * position
      */
     bool CreateTransaction(const std::vector<CRecipient> &vecSend,
                            CWalletTx &wtxNew, CReserveKey &reservekey,
                            CAmount &nFeeRet, int &nChangePosInOut,
                            std::string &strFailReason,
                            const CCoinControl *coinControl = nullptr,
                            bool sign = true);
     bool CommitTransaction(CWalletTx &wtxNew, CReserveKey &reservekey,
                            CConnman *connman, CValidationState &state);
 
     void ListAccountCreditDebit(const std::string &strAccount,
                                 std::list<CAccountingEntry> &entries);
     bool AddAccountingEntry(const CAccountingEntry &);
     bool AddAccountingEntry(const CAccountingEntry &, CWalletDB *pwalletdb);
     template <typename ContainerType>
     bool DummySignTx(CMutableTransaction &txNew, const ContainerType &coins);
 
     static CFeeRate minTxFee;
     static CFeeRate fallbackFee;
     /**
      * Estimate the minimum fee considering user set parameters and the required
      * fee
      */
     static CAmount GetMinimumFee(unsigned int nTxBytes,
                                  unsigned int nConfirmTarget,
                                  const CTxMemPool &pool);
     /**
      * Estimate the minimum fee considering required fee and targetFee or if 0
      * then fee estimation for nConfirmTarget
      */
     static CAmount GetMinimumFee(unsigned int nTxBytes,
                                  unsigned int nConfirmTarget,
                                  const CTxMemPool &pool, CAmount targetFee);
     /**
      * Return the minimum required fee taking into account the floating relay
      * fee and user set minimum transaction fee
      */
     static CAmount GetRequiredFee(unsigned int nTxBytes);
 
     bool NewKeyPool();
     bool TopUpKeyPool(unsigned int kpSize = 0);
     void ReserveKeyFromKeyPool(int64_t &nIndex, CKeyPool &keypool);
     void KeepKey(int64_t nIndex);
     void ReturnKey(int64_t nIndex);
     bool GetKeyFromPool(CPubKey &key);
     int64_t GetOldestKeyPoolTime();
     void GetAllReserveKeys(std::set<CKeyID> &setAddress) const;
 
     std::set<std::set<CTxDestination>> GetAddressGroupings();
     std::map<CTxDestination, CAmount> GetAddressBalances();
 
     CAmount GetAccountBalance(const std::string &strAccount, int nMinDepth,
                               const isminefilter &filter);
     CAmount GetAccountBalance(CWalletDB &walletdb,
                               const std::string &strAccount, int nMinDepth,
                               const isminefilter &filter);
     std::set<CTxDestination>
     GetAccountAddresses(const std::string &strAccount) const;
 
     isminetype IsMine(const CTxIn &txin) const;
     /**
      * Returns amount of debit if the input matches the filter, otherwise
      * returns 0
      */
     CAmount GetDebit(const CTxIn &txin, const isminefilter &filter) const;
     isminetype IsMine(const CTxOut &txout) const;
     CAmount GetCredit(const CTxOut &txout, const isminefilter &filter) const;
     bool IsChange(const CTxOut &txout) const;
     CAmount GetChange(const CTxOut &txout) const;
     bool IsMine(const CTransaction &tx) const;
     /** should probably be renamed to IsRelevantToMe */
     bool IsFromMe(const CTransaction &tx) const;
     CAmount GetDebit(const CTransaction &tx, const isminefilter &filter) const;
     /** Returns whether all of the inputs match the filter */
     bool IsAllFromMe(const CTransaction &tx, const isminefilter &filter) const;
     CAmount GetCredit(const CTransaction &tx, const isminefilter &filter) const;
     CAmount GetChange(const CTransaction &tx) const;
     void SetBestChain(const CBlockLocator &loc) override;
 
     DBErrors LoadWallet(bool &fFirstRunRet);
     DBErrors ZapWalletTx(std::vector<CWalletTx> &vWtx);
     DBErrors ZapSelectTx(std::vector<uint256> &vHashIn,
                          std::vector<uint256> &vHashOut);
 
     bool SetAddressBook(const CTxDestination &address,
                         const std::string &strName, const std::string &purpose);
 
     bool DelAddressBook(const CTxDestination &address);
 
     void UpdatedTransaction(const uint256 &hashTx) override;
 
     void Inventory(const uint256 &hash) override {
         LOCK(cs_wallet);
         std::map<uint256, int>::iterator mi = mapRequestCount.find(hash);
         if (mi != mapRequestCount.end()) {
             (*mi).second++;
         }
     }
 
     void GetScriptForMining(boost::shared_ptr<CReserveScript> &script) override;
     void ResetRequestCount(const uint256 &hash) override {
         LOCK(cs_wallet);
         mapRequestCount[hash] = 0;
     };
 
     unsigned int GetKeyPoolSize() {
         // setKeyPool
         AssertLockHeld(cs_wallet);
         return setKeyPool.size();
     }
 
     bool SetDefaultKey(const CPubKey &vchPubKey);
 
     //! signify that a particular wallet feature is now used. this may change
     //! nWalletVersion and nWalletMaxVersion if those are lower
     bool SetMinVersion(enum WalletFeature, CWalletDB *pwalletdbIn = nullptr,
                        bool fExplicit = false);
 
     //! change which version we're allowed to upgrade to (note that this does
     //! not immediately imply upgrading to that format)
     bool SetMaxVersion(int nVersion);
 
     //! get the current wallet format (the oldest client version guaranteed to
     //! understand this wallet)
     int GetVersion() {
         LOCK(cs_wallet);
         return nWalletVersion;
     }
 
     //! Get wallet transactions that conflict with given transaction (spend same
     //! outputs)
     std::set<uint256> GetConflicts(const uint256 &txid) const;
 
     //! Check if a given transaction has any of its outputs spent by another
     //! transaction in the wallet
     bool HasWalletSpend(const uint256 &txid) const;
 
     //! Flush wallet (bitdb flush)
     void Flush(bool shutdown = false);
 
     //! Verify the wallet database and perform salvage if required
     static bool Verify();
 
     /**
      * Address book entry changed.
      * @note called with lock cs_wallet held.
      */
     boost::signals2::signal<void(CWallet *wallet, const CTxDestination &address,
                                  const std::string &label, bool isMine,
                                  const std::string &purpose, ChangeType status)>
         NotifyAddressBookChanged;
 
     /**
      * Wallet transaction added, removed or updated.
      * @note called with lock cs_wallet held.
      */
     boost::signals2::signal<void(CWallet *wallet, const uint256 &hashTx,
                                  ChangeType status)>
         NotifyTransactionChanged;
 
     /** Show progress e.g. for rescan */
     boost::signals2::signal<void(const std::string &title, int nProgress)>
         ShowProgress;
 
     /** Watch-only address added */
     boost::signals2::signal<void(bool fHaveWatchOnly)> NotifyWatchonlyChanged;
 
     /** Inquire whether this wallet broadcasts transactions. */
     bool GetBroadcastTransactions() const { return fBroadcastTransactions; }
     /** Set whether this wallet broadcasts transactions. */
     void SetBroadcastTransactions(bool broadcast) {
         fBroadcastTransactions = broadcast;
     }
 
     /**
      * Mark a transaction (and it in-wallet descendants) as abandoned so its
      * inputs may be respent.
      */
     bool AbandonTransaction(const uint256 &hashTx);
 
     /**
      * Mark a transaction as replaced by another transaction (e.g., BIP 125).
      */
     bool MarkReplaced(const uint256 &originalHash, const uint256 &newHash);
 
     /* Returns the wallets help message */
     static std::string GetWalletHelpString(bool showDebug);
 
     /**
      * Initializes the wallet, returns a new CWallet instance or a null pointer
      * in case of an error.
      */
     static CWallet *CreateWalletFromFile(const std::string walletFile);
     static bool InitLoadWallet();
 
     /**
      * Wallet post-init setup
      * Gives the wallet a chance to register repetitive tasks and complete
      * post-init tasks
      */
     void postInitProcess(boost::thread_group &threadGroup);
 
     /* Wallets parameter interaction */
     static bool ParameterInteraction();
 
     bool BackupWallet(const std::string &strDest);
 
     /* Set the HD chain model (chain child index counters) */
     bool SetHDChain(const CHDChain &chain, bool memonly);
     const CHDChain &GetHDChain() { return hdChain; }
 
     /* Returns true if HD is enabled */
     bool IsHDEnabled();
 
     /* Generates a new HD master key (will not be activated) */
     CPubKey GenerateNewHDMasterKey();
 
     /* Set the current HD master key (will reset the chain child index counters)
      */
     bool SetHDMasterKey(const CPubKey &key);
 };
 
 /** A key allocated from the key pool. */
 class CReserveKey : public CReserveScript {
 protected:
     CWallet *pwallet;
     int64_t nIndex;
     CPubKey vchPubKey;
 
 public:
     CReserveKey(CWallet *pwalletIn) {
         nIndex = -1;
         pwallet = pwalletIn;
     }
 
     ~CReserveKey() { ReturnKey(); }
 
     void ReturnKey();
     bool GetReservedKey(CPubKey &pubkey);
     void KeepKey();
     void KeepScript() { KeepKey(); }
 };
 
 /**
  * Account information.
  * Stored in wallet with key "acc"+string account name.
  */
 class CAccount {
 public:
     CPubKey vchPubKey;
 
     CAccount() { SetNull(); }
 
     void SetNull() { vchPubKey = CPubKey(); }
 
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
     inline void SerializationOp(Stream &s, Operation ser_action) {
         int nVersion = s.GetVersion();
         if (!(s.GetType() & SER_GETHASH)) {
             READWRITE(nVersion);
         }
 
         READWRITE(vchPubKey);
     }
 };
 
 // Helper for producing a bunch of max-sized low-S signatures (eg 72 bytes)
 // ContainerType is meant to hold pair<CWalletTx *, int>, and be iterable so
 // that each entry corresponds to each vIn, in order.
 template <typename ContainerType>
 bool CWallet::DummySignTx(CMutableTransaction &txNew,
                           const ContainerType &coins) {
     // Fill in dummy signatures for fee calculation.
     int nIn = 0;
     for (const auto &coin : coins) {
         const CScript &scriptPubKey =
             coin.first->tx->vout[coin.second].scriptPubKey;
         SignatureData sigdata;
 
         if (!ProduceSignature(DummySignatureCreator(this), scriptPubKey,
                               sigdata)) {
             return false;
         } else {
             UpdateTransaction(txNew, nIn, sigdata);
         }
 
         nIn++;
     }
 
     return true;
 }
 
 #endif // BITCOIN_WALLET_WALLET_H
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
index bf3eb96cc..5951e4180 100644
--- a/src/wallet/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -1,877 +1,883 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #include "wallet/walletdb.h"
 
 #include "base58.h"
 #include "consensus/validation.h"
 #include "protocol.h"
 #include "serialize.h"
 #include "sync.h"
 #include "util.h"
 #include "utiltime.h"
 #include "validation.h" // For CheckRegularTransaction
 #include "wallet/wallet.h"
 
 #include <atomic>
 
 #include <boost/filesystem.hpp>
 #include <boost/thread.hpp>
 #include <boost/version.hpp>
 
 static uint64_t nAccountingEntryNumber = 0;
 
 static std::atomic<unsigned int> nWalletDBUpdateCounter;
 
 //
 // CWalletDB
 //
 
-bool CWalletDB::WriteName(const std::string &strAddress, const std::string &strName) {
+bool CWalletDB::WriteName(const std::string &strAddress,
+                          const std::string &strName) {
     nWalletDBUpdateCounter++;
     return Write(make_pair(std::string("name"), strAddress), strName);
 }
 
 bool CWalletDB::EraseName(const std::string &strAddress) {
     // This should only be used for sending addresses, never for receiving
     // addresses, receiving addresses must always have an address book entry if
     // they're not change return.
     nWalletDBUpdateCounter++;
     return Erase(make_pair(std::string("name"), strAddress));
 }
 
 bool CWalletDB::WritePurpose(const std::string &strAddress,
                              const std::string &strPurpose) {
     nWalletDBUpdateCounter++;
     return Write(make_pair(std::string("purpose"), strAddress), strPurpose);
 }
 
 bool CWalletDB::ErasePurpose(const std::string &strPurpose) {
     nWalletDBUpdateCounter++;
     return Erase(make_pair(std::string("purpose"), strPurpose));
 }
 
 bool CWalletDB::WriteTx(const CWalletTx &wtx) {
     nWalletDBUpdateCounter++;
     return Write(std::make_pair(std::string("tx"), wtx.GetId()), wtx);
 }
 
 bool CWalletDB::EraseTx(uint256 hash) {
     nWalletDBUpdateCounter++;
     return Erase(std::make_pair(std::string("tx"), hash));
 }
 
 bool CWalletDB::WriteKey(const CPubKey &vchPubKey, const CPrivKey &vchPrivKey,
                          const CKeyMetadata &keyMeta) {
     nWalletDBUpdateCounter++;
 
     if (!Write(std::make_pair(std::string("keymeta"), vchPubKey), keyMeta,
                false))
         return false;
 
     // hash pubkey/privkey to accelerate wallet load
-    std::vector<unsigned char> vchKey;
+    std::vector<uint8_t> vchKey;
     vchKey.reserve(vchPubKey.size() + vchPrivKey.size());
     vchKey.insert(vchKey.end(), vchPubKey.begin(), vchPubKey.end());
     vchKey.insert(vchKey.end(), vchPrivKey.begin(), vchPrivKey.end());
 
     return Write(std::make_pair(std::string("key"), vchPubKey),
                  std::make_pair(vchPrivKey, Hash(vchKey.begin(), vchKey.end())),
                  false);
 }
 
-bool CWalletDB::WriteCryptedKey(
-    const CPubKey &vchPubKey,
-    const std::vector<unsigned char> &vchCryptedSecret,
-    const CKeyMetadata &keyMeta) {
+bool CWalletDB::WriteCryptedKey(const CPubKey &vchPubKey,
+                                const std::vector<uint8_t> &vchCryptedSecret,
+                                const CKeyMetadata &keyMeta) {
     const bool fEraseUnencryptedKey = true;
     nWalletDBUpdateCounter++;
 
     if (!Write(std::make_pair(std::string("keymeta"), vchPubKey), keyMeta))
         return false;
 
     if (!Write(std::make_pair(std::string("ckey"), vchPubKey), vchCryptedSecret,
                false))
         return false;
     if (fEraseUnencryptedKey) {
         Erase(std::make_pair(std::string("key"), vchPubKey));
         Erase(std::make_pair(std::string("wkey"), vchPubKey));
     }
     return true;
 }
 
 bool CWalletDB::WriteMasterKey(unsigned int nID, const CMasterKey &kMasterKey) {
     nWalletDBUpdateCounter++;
     return Write(std::make_pair(std::string("mkey"), nID), kMasterKey, true);
 }
 
 bool CWalletDB::WriteCScript(const uint160 &hash, const CScript &redeemScript) {
     nWalletDBUpdateCounter++;
     return Write(std::make_pair(std::string("cscript"), hash),
                  *(const CScriptBase *)(&redeemScript), false);
 }
 
 bool CWalletDB::WriteWatchOnly(const CScript &dest,
                                const CKeyMetadata &keyMeta) {
     nWalletDBUpdateCounter++;
     if (!Write(std::make_pair(std::string("watchmeta"),
                               *(const CScriptBase *)(&dest)),
                keyMeta))
         return false;
     return Write(
         std::make_pair(std::string("watchs"), *(const CScriptBase *)(&dest)),
         '1');
 }
 
 bool CWalletDB::EraseWatchOnly(const CScript &dest) {
     nWalletDBUpdateCounter++;
     if (!Erase(std::make_pair(std::string("watchmeta"),
                               *(const CScriptBase *)(&dest))))
         return false;
     return Erase(
         std::make_pair(std::string("watchs"), *(const CScriptBase *)(&dest)));
 }
 
 bool CWalletDB::WriteBestBlock(const CBlockLocator &locator) {
     nWalletDBUpdateCounter++;
     // Write empty block locator so versions that require a merkle branch
     // automatically rescan.
     Write(std::string("bestblock"), CBlockLocator());
     return Write(std::string("bestblock_nomerkle"), locator);
 }
 
 bool CWalletDB::ReadBestBlock(CBlockLocator &locator) {
     if (Read(std::string("bestblock"), locator) && !locator.vHave.empty())
         return true;
     return Read(std::string("bestblock_nomerkle"), locator);
 }
 
 bool CWalletDB::WriteOrderPosNext(int64_t nOrderPosNext) {
     nWalletDBUpdateCounter++;
     return Write(std::string("orderposnext"), nOrderPosNext);
 }
 
 bool CWalletDB::WriteDefaultKey(const CPubKey &vchPubKey) {
     nWalletDBUpdateCounter++;
     return Write(std::string("defaultkey"), vchPubKey);
 }
 
 bool CWalletDB::ReadPool(int64_t nPool, CKeyPool &keypool) {
     return Read(std::make_pair(std::string("pool"), nPool), keypool);
 }
 
 bool CWalletDB::WritePool(int64_t nPool, const CKeyPool &keypool) {
     nWalletDBUpdateCounter++;
     return Write(std::make_pair(std::string("pool"), nPool), keypool);
 }
 
 bool CWalletDB::ErasePool(int64_t nPool) {
     nWalletDBUpdateCounter++;
     return Erase(std::make_pair(std::string("pool"), nPool));
 }
 
 bool CWalletDB::WriteMinVersion(int nVersion) {
     return Write(std::string("minversion"), nVersion);
 }
 
 bool CWalletDB::ReadAccount(const std::string &strAccount, CAccount &account) {
     account.SetNull();
     return Read(make_pair(std::string("acc"), strAccount), account);
 }
 
 bool CWalletDB::WriteAccount(const std::string &strAccount,
                              const CAccount &account) {
     return Write(make_pair(std::string("acc"), strAccount), account);
 }
 
 bool CWalletDB::WriteAccountingEntry(const uint64_t nAccEntryNum,
                                      const CAccountingEntry &acentry) {
     return Write(
         std::make_pair(std::string("acentry"),
                        std::make_pair(acentry.strAccount, nAccEntryNum)),
         acentry);
 }
 
 bool CWalletDB::WriteAccountingEntry_Backend(const CAccountingEntry &acentry) {
     return WriteAccountingEntry(++nAccountingEntryNumber, acentry);
 }
 
 CAmount CWalletDB::GetAccountCreditDebit(const std::string &strAccount) {
     std::list<CAccountingEntry> entries;
     ListAccountCreditDebit(strAccount, entries);
 
     CAmount nCreditDebit = 0;
     for (const CAccountingEntry &entry : entries) {
         nCreditDebit += entry.nCreditDebit;
     }
 
     return nCreditDebit;
 }
 
 void CWalletDB::ListAccountCreditDebit(const std::string &strAccount,
                                        std::list<CAccountingEntry> &entries) {
     bool fAllAccounts = (strAccount == "*");
 
     Dbc *pcursor = GetCursor();
     if (!pcursor)
         throw std::runtime_error(std::string(__func__) +
-                            ": cannot create DB cursor");
+                                 ": cannot create DB cursor");
     bool setRange = true;
     while (true) {
         // Read next record
         CDataStream ssKey(SER_DISK, CLIENT_VERSION);
         if (setRange)
             ssKey << std::make_pair(
                 std::string("acentry"),
                 std::make_pair((fAllAccounts ? std::string("") : strAccount),
                                uint64_t(0)));
         CDataStream ssValue(SER_DISK, CLIENT_VERSION);
         int ret = ReadAtCursor(pcursor, ssKey, ssValue, setRange);
         setRange = false;
         if (ret == DB_NOTFOUND)
             break;
         else if (ret != 0) {
             pcursor->close();
-            throw std::runtime_error(std::string(__func__) + ": error scanning DB");
+            throw std::runtime_error(std::string(__func__) +
+                                     ": error scanning DB");
         }
 
         // Unserialize
         std::string strType;
         ssKey >> strType;
         if (strType != "acentry") break;
         CAccountingEntry acentry;
         ssKey >> acentry.strAccount;
         if (!fAllAccounts && acentry.strAccount != strAccount) break;
 
         ssValue >> acentry;
         ssKey >> acentry.nEntryNo;
         entries.push_back(acentry);
     }
 
     pcursor->close();
 }
 
 class CWalletScanState {
 public:
     unsigned int nKeys;
     unsigned int nCKeys;
     unsigned int nWatchKeys;
     unsigned int nKeyMeta;
     bool fIsEncrypted;
     bool fAnyUnordered;
     int nFileVersion;
     std::vector<uint256> vWalletUpgrade;
 
     CWalletScanState() {
         nKeys = nCKeys = nWatchKeys = nKeyMeta = 0;
         fIsEncrypted = false;
         fAnyUnordered = false;
         nFileVersion = 0;
     }
 };
 
 bool ReadKeyValue(CWallet *pwallet, CDataStream &ssKey, CDataStream &ssValue,
-                  CWalletScanState &wss, std::string &strType, std::string &strErr) {
+                  CWalletScanState &wss, std::string &strType,
+                  std::string &strErr) {
     try {
         // Unserialize
         // Taking advantage of the fact that pair serialization is just the two
         // items serialized one after the other.
         ssKey >> strType;
         if (strType == "name") {
             std::string strAddress;
             ssKey >> strAddress;
             ssValue >>
                 pwallet->mapAddressBook[CBitcoinAddress(strAddress).Get()].name;
         } else if (strType == "purpose") {
             std::string strAddress;
             ssKey >> strAddress;
             ssValue >>
                 pwallet->mapAddressBook[CBitcoinAddress(strAddress).Get()]
                     .purpose;
         } else if (strType == "tx") {
             uint256 hash;
             ssKey >> hash;
             CWalletTx wtx;
             ssValue >> wtx;
             CValidationState state;
             bool isValid = wtx.IsCoinBase()
                                ? CheckCoinbase(wtx, state)
                                : CheckRegularTransaction(wtx, state);
             if (wtx.GetId() != hash || !isValid) return false;
 
             // Undo serialize changes in 31600
             if (31404 <= wtx.fTimeReceivedIsTxTime &&
                 wtx.fTimeReceivedIsTxTime <= 31703) {
                 if (!ssValue.empty()) {
                     char fTmp;
                     char fUnused;
                     ssValue >> fTmp >> fUnused >> wtx.strFromAccount;
                     strErr =
                         strprintf("LoadWallet() upgrading tx ver=%d %d '%s' %s",
                                   wtx.fTimeReceivedIsTxTime, fTmp,
                                   wtx.strFromAccount, hash.ToString());
                     wtx.fTimeReceivedIsTxTime = fTmp;
                 } else {
                     strErr =
                         strprintf("LoadWallet() repairing tx ver=%d %s",
                                   wtx.fTimeReceivedIsTxTime, hash.ToString());
                     wtx.fTimeReceivedIsTxTime = 0;
                 }
                 wss.vWalletUpgrade.push_back(hash);
             }
 
             if (wtx.nOrderPos == -1) wss.fAnyUnordered = true;
 
             pwallet->LoadToWallet(wtx);
         } else if (strType == "acentry") {
             std::string strAccount;
             ssKey >> strAccount;
             uint64_t nNumber;
             ssKey >> nNumber;
             if (nNumber > nAccountingEntryNumber)
                 nAccountingEntryNumber = nNumber;
 
             if (!wss.fAnyUnordered) {
                 CAccountingEntry acentry;
                 ssValue >> acentry;
                 if (acentry.nOrderPos == -1) wss.fAnyUnordered = true;
             }
         } else if (strType == "watchs") {
             wss.nWatchKeys++;
             CScript script;
             ssKey >> *(CScriptBase *)(&script);
             char fYes;
             ssValue >> fYes;
             if (fYes == '1') pwallet->LoadWatchOnly(script);
         } else if (strType == "key" || strType == "wkey") {
             CPubKey vchPubKey;
             ssKey >> vchPubKey;
             if (!vchPubKey.IsValid()) {
                 strErr = "Error reading wallet database: CPubKey corrupt";
                 return false;
             }
             CKey key;
             CPrivKey pkey;
             uint256 hash;
 
             if (strType == "key") {
                 wss.nKeys++;
                 ssValue >> pkey;
             } else {
                 CWalletKey wkey;
                 ssValue >> wkey;
                 pkey = wkey.vchPrivKey;
             }
 
             // Old wallets store keys as "key" [pubkey] => [privkey]
             // ... which was slow for wallets with lots of keys, because the
             // public key is re-derived from the private key using EC operations
             // as a checksum. Newer wallets store keys as "key"[pubkey] =>
             // [privkey][hash(pubkey,privkey)], which is much faster while
             // remaining backwards-compatible.
             try {
                 ssValue >> hash;
             } catch (...) {
             }
 
             bool fSkipCheck = false;
 
             if (!hash.IsNull()) {
                 // hash pubkey/privkey to accelerate wallet load
-                std::vector<unsigned char> vchKey;
+                std::vector<uint8_t> vchKey;
                 vchKey.reserve(vchPubKey.size() + pkey.size());
                 vchKey.insert(vchKey.end(), vchPubKey.begin(), vchPubKey.end());
                 vchKey.insert(vchKey.end(), pkey.begin(), pkey.end());
 
                 if (Hash(vchKey.begin(), vchKey.end()) != hash) {
                     strErr = "Error reading wallet database: CPubKey/CPrivKey "
                              "corrupt";
                     return false;
                 }
 
                 fSkipCheck = true;
             }
 
             if (!key.Load(pkey, vchPubKey, fSkipCheck)) {
                 strErr = "Error reading wallet database: CPrivKey corrupt";
                 return false;
             }
             if (!pwallet->LoadKey(key, vchPubKey)) {
                 strErr = "Error reading wallet database: LoadKey failed";
                 return false;
             }
         } else if (strType == "mkey") {
             unsigned int nID;
             ssKey >> nID;
             CMasterKey kMasterKey;
             ssValue >> kMasterKey;
             if (pwallet->mapMasterKeys.count(nID) != 0) {
                 strErr = strprintf(
                     "Error reading wallet database: duplicate CMasterKey id %u",
                     nID);
                 return false;
             }
             pwallet->mapMasterKeys[nID] = kMasterKey;
             if (pwallet->nMasterKeyMaxID < nID) pwallet->nMasterKeyMaxID = nID;
         } else if (strType == "ckey") {
             CPubKey vchPubKey;
             ssKey >> vchPubKey;
             if (!vchPubKey.IsValid()) {
                 strErr = "Error reading wallet database: CPubKey corrupt";
                 return false;
             }
-            std::vector<unsigned char> vchPrivKey;
+            std::vector<uint8_t> vchPrivKey;
             ssValue >> vchPrivKey;
             wss.nCKeys++;
 
             if (!pwallet->LoadCryptedKey(vchPubKey, vchPrivKey)) {
                 strErr = "Error reading wallet database: LoadCryptedKey failed";
                 return false;
             }
             wss.fIsEncrypted = true;
         } else if (strType == "keymeta" || strType == "watchmeta") {
             CTxDestination keyID;
             if (strType == "keymeta") {
                 CPubKey vchPubKey;
                 ssKey >> vchPubKey;
                 keyID = vchPubKey.GetID();
             } else if (strType == "watchmeta") {
                 CScript script;
                 ssKey >> *(CScriptBase *)(&script);
                 keyID = CScriptID(script);
             }
 
             CKeyMetadata keyMeta;
             ssValue >> keyMeta;
             wss.nKeyMeta++;
 
             pwallet->LoadKeyMetadata(keyID, keyMeta);
         } else if (strType == "defaultkey") {
             ssValue >> pwallet->vchDefaultKey;
         } else if (strType == "pool") {
             int64_t nIndex;
             ssKey >> nIndex;
             CKeyPool keypool;
             ssValue >> keypool;
 
             pwallet->LoadKeyPool(nIndex, keypool);
         } else if (strType == "version") {
             ssValue >> wss.nFileVersion;
             if (wss.nFileVersion == 10300) wss.nFileVersion = 300;
         } else if (strType == "cscript") {
             uint160 hash;
             ssKey >> hash;
             CScript script;
             ssValue >> *(CScriptBase *)(&script);
             if (!pwallet->LoadCScript(script)) {
                 strErr = "Error reading wallet database: LoadCScript failed";
                 return false;
             }
         } else if (strType == "orderposnext") {
             ssValue >> pwallet->nOrderPosNext;
         } else if (strType == "destdata") {
             std::string strAddress, strKey, strValue;
             ssKey >> strAddress;
             ssKey >> strKey;
             ssValue >> strValue;
             if (!pwallet->LoadDestData(CBitcoinAddress(strAddress).Get(),
                                        strKey, strValue)) {
                 strErr = "Error reading wallet database: LoadDestData failed";
                 return false;
             }
         } else if (strType == "hdchain") {
             CHDChain chain;
             ssValue >> chain;
             if (!pwallet->SetHDChain(chain, true)) {
                 strErr = "Error reading wallet database: SetHDChain failed";
                 return false;
             }
         }
     } catch (...) {
         return false;
     }
     return true;
 }
 
 static bool IsKeyType(std::string strType) {
     return (strType == "key" || strType == "wkey" || strType == "mkey" ||
             strType == "ckey");
 }
 
 DBErrors CWalletDB::LoadWallet(CWallet *pwallet) {
     pwallet->vchDefaultKey = CPubKey();
     CWalletScanState wss;
     bool fNoncriticalErrors = false;
     DBErrors result = DB_LOAD_OK;
 
     LOCK(pwallet->cs_wallet);
     try {
         int nMinVersion = 0;
         if (Read((std::string) "minversion", nMinVersion)) {
             if (nMinVersion > CLIENT_VERSION) return DB_TOO_NEW;
             pwallet->LoadMinVersion(nMinVersion);
         }
 
         // Get cursor
         Dbc *pcursor = GetCursor();
         if (!pcursor) {
             LogPrintf("Error getting wallet database cursor\n");
             return DB_CORRUPT;
         }
 
         while (true) {
             // Read next record
             CDataStream ssKey(SER_DISK, CLIENT_VERSION);
             CDataStream ssValue(SER_DISK, CLIENT_VERSION);
             int ret = ReadAtCursor(pcursor, ssKey, ssValue);
             if (ret == DB_NOTFOUND)
                 break;
             else if (ret != 0) {
                 LogPrintf("Error reading next record from wallet database\n");
                 return DB_CORRUPT;
             }
 
             // Try to be tolerant of single corrupt records:
             std::string strType, strErr;
             if (!ReadKeyValue(pwallet, ssKey, ssValue, wss, strType, strErr)) {
                 // losing keys is considered a catastrophic error, anything else
                 // we assume the user can live with:
                 if (IsKeyType(strType))
                     result = DB_CORRUPT;
                 else {
                     // Leave other errors alone, if we try to fix them we might
                     // make things worse. But do warn the user there is
                     // something wrong.
                     fNoncriticalErrors = true;
                     if (strType == "tx")
                         // Rescan if there is a bad transaction record:
                         SoftSetBoolArg("-rescan", true);
                 }
             }
             if (!strErr.empty()) LogPrintf("%s\n", strErr);
         }
         pcursor->close();
     } catch (const boost::thread_interrupted &) {
         throw;
     } catch (...) {
         result = DB_CORRUPT;
     }
 
     if (fNoncriticalErrors && result == DB_LOAD_OK)
         result = DB_NONCRITICAL_ERROR;
 
     // Any wallet corruption at all: skip any rewriting or upgrading, we don't
     // want to make it worse.
     if (result != DB_LOAD_OK) return result;
 
     LogPrintf("nFileVersion = %d\n", wss.nFileVersion);
 
     LogPrintf("Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total\n",
               wss.nKeys, wss.nCKeys, wss.nKeyMeta, wss.nKeys + wss.nCKeys);
 
     // nTimeFirstKey is only reliable if all keys have metadata
     if ((wss.nKeys + wss.nCKeys + wss.nWatchKeys) != wss.nKeyMeta)
         pwallet->UpdateTimeFirstKey(1);
 
     for (uint256 hash : wss.vWalletUpgrade) {
         WriteTx(pwallet->mapWallet[hash]);
     }
 
     // Rewrite encrypted wallets of versions 0.4.0 and 0.5.0rc:
     if (wss.fIsEncrypted &&
         (wss.nFileVersion == 40000 || wss.nFileVersion == 50000))
         return DB_NEED_REWRITE;
 
     if (wss.nFileVersion < CLIENT_VERSION) // Update
         WriteVersion(CLIENT_VERSION);
 
     if (wss.fAnyUnordered) result = pwallet->ReorderTransactions();
 
     pwallet->laccentries.clear();
     ListAccountCreditDebit("*", pwallet->laccentries);
     for (CAccountingEntry &entry : pwallet->laccentries) {
         pwallet->wtxOrdered.insert(make_pair(
             entry.nOrderPos, CWallet::TxPair((CWalletTx *)0, &entry)));
     }
 
     return result;
 }
 
-DBErrors CWalletDB::FindWalletTx(CWallet *pwallet, std::vector<uint256> &vTxHash,
+DBErrors CWalletDB::FindWalletTx(CWallet *pwallet,
+                                 std::vector<uint256> &vTxHash,
                                  std::vector<CWalletTx> &vWtx) {
     pwallet->vchDefaultKey = CPubKey();
     bool fNoncriticalErrors = false;
     DBErrors result = DB_LOAD_OK;
 
     try {
         LOCK(pwallet->cs_wallet);
         int nMinVersion = 0;
         if (Read((std::string) "minversion", nMinVersion)) {
             if (nMinVersion > CLIENT_VERSION) return DB_TOO_NEW;
             pwallet->LoadMinVersion(nMinVersion);
         }
 
         // Get cursor
         Dbc *pcursor = GetCursor();
         if (!pcursor) {
             LogPrintf("Error getting wallet database cursor\n");
             return DB_CORRUPT;
         }
 
         while (true) {
             // Read next record
             CDataStream ssKey(SER_DISK, CLIENT_VERSION);
             CDataStream ssValue(SER_DISK, CLIENT_VERSION);
             int ret = ReadAtCursor(pcursor, ssKey, ssValue);
             if (ret == DB_NOTFOUND)
                 break;
             else if (ret != 0) {
                 LogPrintf("Error reading next record from wallet database\n");
                 return DB_CORRUPT;
             }
 
             std::string strType;
             ssKey >> strType;
             if (strType == "tx") {
                 uint256 hash;
                 ssKey >> hash;
 
                 CWalletTx wtx;
                 ssValue >> wtx;
 
                 vTxHash.push_back(hash);
                 vWtx.push_back(wtx);
             }
         }
         pcursor->close();
     } catch (const boost::thread_interrupted &) {
         throw;
     } catch (...) {
         result = DB_CORRUPT;
     }
 
     if (fNoncriticalErrors && result == DB_LOAD_OK)
         result = DB_NONCRITICAL_ERROR;
 
     return result;
 }
 
-DBErrors CWalletDB::ZapSelectTx(CWallet *pwallet, std::vector<uint256> &vTxHashIn,
+DBErrors CWalletDB::ZapSelectTx(CWallet *pwallet,
+                                std::vector<uint256> &vTxHashIn,
                                 std::vector<uint256> &vTxHashOut) {
     // Build list of wallet TXs and hashes.
     std::vector<uint256> vTxHash;
     std::vector<CWalletTx> vWtx;
     DBErrors err = FindWalletTx(pwallet, vTxHash, vWtx);
     if (err != DB_LOAD_OK) {
         return err;
     }
 
     std::sort(vTxHash.begin(), vTxHash.end());
     std::sort(vTxHashIn.begin(), vTxHashIn.end());
 
     // Erase each matching wallet TX.
     bool delerror = false;
     std::vector<uint256>::iterator it = vTxHashIn.begin();
     for (uint256 hash : vTxHash) {
         while (it < vTxHashIn.end() && (*it) < hash) {
             it++;
         }
         if (it == vTxHashIn.end()) {
             break;
         } else if ((*it) == hash) {
             pwallet->mapWallet.erase(hash);
             if (!EraseTx(hash)) {
                 LogPrint("db", "Transaction was found for deletion but "
                                "returned database error: %s\n",
                          hash.GetHex());
                 delerror = true;
             }
             vTxHashOut.push_back(hash);
         }
     }
 
     if (delerror) {
         return DB_CORRUPT;
     }
     return DB_LOAD_OK;
 }
 
-DBErrors CWalletDB::ZapWalletTx(CWallet *pwallet, std::vector<CWalletTx> &vWtx) {
+DBErrors CWalletDB::ZapWalletTx(CWallet *pwallet,
+                                std::vector<CWalletTx> &vWtx) {
     // Build list of wallet TXs.
     std::vector<uint256> vTxHash;
     DBErrors err = FindWalletTx(pwallet, vTxHash, vWtx);
     if (err != DB_LOAD_OK) return err;
 
     // Erase each wallet TX.
     for (uint256 &hash : vTxHash) {
         if (!EraseTx(hash)) return DB_CORRUPT;
     }
 
     return DB_LOAD_OK;
 }
 
 void ThreadFlushWalletDB() {
     // Make this thread recognisable as the wallet flushing thread.
     RenameThread("bitcoin-wallet");
 
     static bool fOneThread;
     if (fOneThread) return;
     fOneThread = true;
     if (!GetBoolArg("-flushwallet", DEFAULT_FLUSHWALLET)) return;
 
     unsigned int nLastSeen = CWalletDB::GetUpdateCounter();
     unsigned int nLastFlushed = CWalletDB::GetUpdateCounter();
     int64_t nLastWalletUpdate = GetTime();
     while (true) {
         MilliSleep(500);
 
         if (nLastSeen != CWalletDB::GetUpdateCounter()) {
             nLastSeen = CWalletDB::GetUpdateCounter();
             nLastWalletUpdate = GetTime();
         }
 
         if (nLastFlushed != CWalletDB::GetUpdateCounter() &&
             GetTime() - nLastWalletUpdate >= 2) {
             TRY_LOCK(bitdb.cs_db, lockDb);
             if (lockDb) {
                 // Don't do this if any databases are in use.
                 int nRefCount = 0;
-                std::map<std::string, int>::iterator mi = bitdb.mapFileUseCount.begin();
+                std::map<std::string, int>::iterator mi =
+                    bitdb.mapFileUseCount.begin();
                 while (mi != bitdb.mapFileUseCount.end()) {
                     nRefCount += (*mi).second;
                     mi++;
                 }
 
                 if (nRefCount == 0) {
                     boost::this_thread::interruption_point();
                     const std::string &strFile = pwalletMain->strWalletFile;
                     std::map<std::string, int>::iterator _mi =
                         bitdb.mapFileUseCount.find(strFile);
                     if (_mi != bitdb.mapFileUseCount.end()) {
                         LogPrint("db", "Flushing %s\n", strFile);
                         nLastFlushed = CWalletDB::GetUpdateCounter();
                         int64_t nStart = GetTimeMillis();
 
                         // Flush wallet file so it's self contained.
                         bitdb.CloseDb(strFile);
                         bitdb.CheckpointLSN(strFile);
 
                         bitdb.mapFileUseCount.erase(_mi++);
                         LogPrint("db", "Flushed %s %dms\n", strFile,
                                  GetTimeMillis() - nStart);
                     }
                 }
             }
         }
     }
 }
 
 //
 // Try to (very carefully!) recover wallet file if there is a problem.
 //
 bool CWalletDB::Recover(CDBEnv &dbenv, const std::string &filename,
                         bool fOnlyKeys) {
     // Recovery procedure:
     // move wallet file to wallet.timestamp.bak . Call Salvage with
     // fAggressive=true to get as much data as possible. Rewrite salvaged data
     // to fresh wallet file. Set -rescan so any missing transactions will be
     // found.
     int64_t now = GetTime();
     std::string newFilename = strprintf("wallet.%d.bak", now);
 
     int result = dbenv.dbenv->dbrename(nullptr, filename.c_str(), nullptr,
                                        newFilename.c_str(), DB_AUTO_COMMIT);
     if (result == 0)
         LogPrintf("Renamed %s to %s\n", filename, newFilename);
     else {
         LogPrintf("Failed to rename %s to %s\n", filename, newFilename);
         return false;
     }
 
     std::vector<CDBEnv::KeyValPair> salvagedData;
     bool fSuccess = dbenv.Salvage(newFilename, true, salvagedData);
     if (salvagedData.empty()) {
         LogPrintf("Salvage(aggressive) found no records in %s.\n", newFilename);
         return false;
     }
     LogPrintf("Salvage(aggressive) found %u records\n", salvagedData.size());
 
     std::unique_ptr<Db> pdbCopy(new Db(dbenv.dbenv, 0));
     int ret = pdbCopy->open(nullptr,          // Txn pointer
                             filename.c_str(), // Filename
                             "main",           // Logical db name
                             DB_BTREE,         // Database type
                             DB_CREATE,        // Flags
                             0);
     if (ret > 0) {
         LogPrintf("Cannot create database file %s\n", filename);
         return false;
     }
     CWallet dummyWallet;
     CWalletScanState wss;
 
     DbTxn *ptxn = dbenv.TxnBegin();
     for (CDBEnv::KeyValPair &row : salvagedData) {
         if (fOnlyKeys) {
             CDataStream ssKey(row.first, SER_DISK, CLIENT_VERSION);
             CDataStream ssValue(row.second, SER_DISK, CLIENT_VERSION);
             std::string strType, strErr;
             bool fReadOK;
             {
                 // Required in LoadKeyMetadata():
                 LOCK(dummyWallet.cs_wallet);
                 fReadOK = ReadKeyValue(&dummyWallet, ssKey, ssValue, wss,
                                        strType, strErr);
             }
             if (!IsKeyType(strType) && strType != "hdchain") continue;
             if (!fReadOK) {
                 LogPrintf("WARNING: CWalletDB::Recover skipping %s: %s\n",
                           strType, strErr);
                 continue;
             }
         }
         Dbt datKey(&row.first[0], row.first.size());
         Dbt datValue(&row.second[0], row.second.size());
         int ret2 = pdbCopy->put(ptxn, &datKey, &datValue, DB_NOOVERWRITE);
         if (ret2 > 0) fSuccess = false;
     }
     ptxn->commit(0);
     pdbCopy->close(0);
 
     return fSuccess;
 }
 
 bool CWalletDB::Recover(CDBEnv &dbenv, const std::string &filename) {
     return CWalletDB::Recover(dbenv, filename, false);
 }
 
 bool CWalletDB::WriteDestData(const std::string &address,
                               const std::string &key,
                               const std::string &value) {
     nWalletDBUpdateCounter++;
     return Write(
         std::make_pair(std::string("destdata"), std::make_pair(address, key)),
         value);
 }
 
 bool CWalletDB::EraseDestData(const std::string &address,
                               const std::string &key) {
     nWalletDBUpdateCounter++;
     return Erase(
         std::make_pair(std::string("destdata"), std::make_pair(address, key)));
 }
 
 bool CWalletDB::WriteHDChain(const CHDChain &chain) {
     nWalletDBUpdateCounter++;
     return Write(std::string("hdchain"), chain);
 }
 
 void CWalletDB::IncrementUpdateCounter() {
     nWalletDBUpdateCounter++;
 }
 
 unsigned int CWalletDB::GetUpdateCounter() {
     return nWalletDBUpdateCounter;
 }
diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h
index 1ad7ff227..b3dc3b219 100644
--- a/src/wallet/walletdb.h
+++ b/src/wallet/walletdb.h
@@ -1,192 +1,192 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-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.
 
 #ifndef BITCOIN_WALLET_WALLETDB_H
 #define BITCOIN_WALLET_WALLETDB_H
 
 #include "amount.h"
 #include "key.h"
 #include "primitives/transaction.h"
 #include "wallet/db.h"
 
 #include <cstdint>
 #include <list>
 #include <string>
 #include <utility>
 #include <vector>
 
 static const bool DEFAULT_FLUSHWALLET = true;
 
 class CAccount;
 class CAccountingEntry;
 struct CBlockLocator;
 class CKeyPool;
 class CMasterKey;
 class CScript;
 class CWallet;
 class CWalletTx;
 class uint160;
 class uint256;
 
 /** Error statuses for the wallet database */
 enum DBErrors {
     DB_LOAD_OK,
     DB_CORRUPT,
     DB_NONCRITICAL_ERROR,
     DB_TOO_NEW,
     DB_LOAD_FAIL,
     DB_NEED_REWRITE
 };
 
 /* simple HD chain data model */
 class CHDChain {
 public:
     uint32_t nExternalChainCounter;
     //!< master key hash160
     CKeyID masterKeyID;
 
     static const int CURRENT_VERSION = 1;
     int nVersion;
 
     CHDChain() { SetNull(); }
     ADD_SERIALIZE_METHODS;
     template <typename Stream, typename Operation>
     inline void SerializationOp(Stream &s, Operation ser_action) {
         READWRITE(this->nVersion);
         READWRITE(nExternalChainCounter);
         READWRITE(masterKeyID);
     }
 
     void SetNull() {
         nVersion = CHDChain::CURRENT_VERSION;
         nExternalChainCounter = 0;
         masterKeyID.SetNull();
     }
 };
 
 class CKeyMetadata {
 public:
     static const int VERSION_BASIC = 1;
     static const int VERSION_WITH_HDDATA = 10;
     static const int CURRENT_VERSION = VERSION_WITH_HDDATA;
     int nVersion;
     // 0 means unknown.
     int64_t nCreateTime;
     // optional HD/bip32 keypath.
     std::string hdKeypath;
     // Id of the HD masterkey used to derive this key.
     CKeyID hdMasterKeyID;
 
     CKeyMetadata() { SetNull(); }
     CKeyMetadata(int64_t nCreateTime_) {
         SetNull();
         nCreateTime = nCreateTime_;
     }
 
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
     inline void SerializationOp(Stream &s, Operation ser_action) {
         READWRITE(this->nVersion);
         READWRITE(nCreateTime);
         if (this->nVersion >= VERSION_WITH_HDDATA) {
             READWRITE(hdKeypath);
             READWRITE(hdMasterKeyID);
         }
     }
 
     void SetNull() {
         nVersion = CKeyMetadata::CURRENT_VERSION;
         nCreateTime = 0;
         hdKeypath.clear();
         hdMasterKeyID.SetNull();
     }
 };
 
 /** Access to the wallet database */
 class CWalletDB : public CDB {
 public:
     CWalletDB(const std::string &strFilename, const char *pszMode = "r+",
               bool fFlushOnClose = true)
         : CDB(strFilename, pszMode, fFlushOnClose) {}
 
     bool WriteName(const std::string &strAddress, const std::string &strName);
     bool EraseName(const std::string &strAddress);
 
     bool WritePurpose(const std::string &strAddress,
                       const std::string &purpose);
     bool ErasePurpose(const std::string &strAddress);
 
     bool WriteTx(const CWalletTx &wtx);
     bool EraseTx(uint256 hash);
 
     bool WriteKey(const CPubKey &vchPubKey, const CPrivKey &vchPrivKey,
                   const CKeyMetadata &keyMeta);
     bool WriteCryptedKey(const CPubKey &vchPubKey,
-                         const std::vector<unsigned char> &vchCryptedSecret,
+                         const std::vector<uint8_t> &vchCryptedSecret,
                          const CKeyMetadata &keyMeta);
     bool WriteMasterKey(unsigned int nID, const CMasterKey &kMasterKey);
 
     bool WriteCScript(const uint160 &hash, const CScript &redeemScript);
 
     bool WriteWatchOnly(const CScript &script, const CKeyMetadata &keymeta);
     bool EraseWatchOnly(const CScript &script);
 
     bool WriteBestBlock(const CBlockLocator &locator);
     bool ReadBestBlock(CBlockLocator &locator);
 
     bool WriteOrderPosNext(int64_t nOrderPosNext);
 
     bool WriteDefaultKey(const CPubKey &vchPubKey);
 
     bool ReadPool(int64_t nPool, CKeyPool &keypool);
     bool WritePool(int64_t nPool, const CKeyPool &keypool);
     bool ErasePool(int64_t nPool);
 
     bool WriteMinVersion(int nVersion);
 
     /// This writes directly to the database, and will not update the CWallet's
     /// cached accounting entries!
     /// Use wallet.AddAccountingEntry instead, to write *and* update its caches.
     bool WriteAccountingEntry(const uint64_t nAccEntryNum,
                               const CAccountingEntry &acentry);
     bool WriteAccountingEntry_Backend(const CAccountingEntry &acentry);
     bool ReadAccount(const std::string &strAccount, CAccount &account);
     bool WriteAccount(const std::string &strAccount, const CAccount &account);
 
     /// Write destination data key,value tuple to database.
     bool WriteDestData(const std::string &address, const std::string &key,
                        const std::string &value);
     /// Erase destination data tuple from wallet database.
     bool EraseDestData(const std::string &address, const std::string &key);
 
     CAmount GetAccountCreditDebit(const std::string &strAccount);
     void ListAccountCreditDebit(const std::string &strAccount,
                                 std::list<CAccountingEntry> &acentries);
 
     DBErrors LoadWallet(CWallet *pwallet);
     DBErrors FindWalletTx(CWallet *pwallet, std::vector<uint256> &vTxHash,
                           std::vector<CWalletTx> &vWtx);
     DBErrors ZapWalletTx(CWallet *pwallet, std::vector<CWalletTx> &vWtx);
     DBErrors ZapSelectTx(CWallet *pwallet, std::vector<uint256> &vHashIn,
                          std::vector<uint256> &vHashOut);
     static bool Recover(CDBEnv &dbenv, const std::string &filename,
                         bool fOnlyKeys);
     static bool Recover(CDBEnv &dbenv, const std::string &filename);
 
     //! write the hdchain model (external chain child index counter)
     bool WriteHDChain(const CHDChain &chain);
 
     static void IncrementUpdateCounter();
     static unsigned int GetUpdateCounter();
 
 private:
     CWalletDB(const CWalletDB &);
     void operator=(const CWalletDB &);
 };
 
 void ThreadFlushWalletDB();
 
 #endif // BITCOIN_WALLET_WALLETDB_H
diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp
index 70ac4b696..2c741f181 100644
--- a/src/zmq/zmqpublishnotifier.cpp
+++ b/src/zmq/zmqpublishnotifier.cpp
@@ -1,183 +1,183 @@
 // Copyright (c) 2015-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.
 
 #include "zmqpublishnotifier.h"
 #include "chainparams.h"
 #include "rpc/server.h"
 #include "streams.h"
 #include "util.h"
 #include "validation.h"
 
 #include <cstdarg>
 
 static std::multimap<std::string, CZMQAbstractPublishNotifier *>
     mapPublishNotifiers;
 
 static const char *MSG_HASHBLOCK = "hashblock";
 static const char *MSG_HASHTX = "hashtx";
 static const char *MSG_RAWBLOCK = "rawblock";
 static const char *MSG_RAWTX = "rawtx";
 
 // Internal function to send multipart message
 static int zmq_send_multipart(void *sock, const void *data, size_t size, ...) {
     va_list args;
     va_start(args, size);
 
     while (1) {
         zmq_msg_t msg;
 
         int rc = zmq_msg_init_size(&msg, size);
         if (rc != 0) {
             zmqError("Unable to initialize ZMQ msg");
             return -1;
         }
 
         void *buf = zmq_msg_data(&msg);
         memcpy(buf, data, size);
 
         data = va_arg(args, const void *);
 
         rc = zmq_msg_send(&msg, sock, data ? ZMQ_SNDMORE : 0);
         if (rc == -1) {
             zmqError("Unable to send ZMQ msg");
             zmq_msg_close(&msg);
             return -1;
         }
 
         zmq_msg_close(&msg);
 
         if (!data) break;
 
         size = va_arg(args, size_t);
     }
     return 0;
 }
 
 bool CZMQAbstractPublishNotifier::Initialize(void *pcontext) {
     assert(!psocket);
 
     // check if address is being used by other publish notifier
     std::multimap<std::string, CZMQAbstractPublishNotifier *>::iterator i =
         mapPublishNotifiers.find(address);
 
     if (i == mapPublishNotifiers.end()) {
         psocket = zmq_socket(pcontext, ZMQ_PUB);
         if (!psocket) {
             zmqError("Failed to create socket");
             return false;
         }
 
         int rc = zmq_bind(psocket, address.c_str());
         if (rc != 0) {
             zmqError("Failed to bind address");
             zmq_close(psocket);
             return false;
         }
 
         // register this notifier for the address, so it can be reused for other
         // publish notifier
         mapPublishNotifiers.insert(std::make_pair(address, this));
         return true;
     } else {
         LogPrint("zmq", "zmq: Reusing socket for address %s\n", address);
 
         psocket = i->second->psocket;
         mapPublishNotifiers.insert(std::make_pair(address, this));
 
         return true;
     }
 }
 
 void CZMQAbstractPublishNotifier::Shutdown() {
     assert(psocket);
 
     int count = mapPublishNotifiers.count(address);
 
     // remove this notifier from the list of publishers using this address
     typedef std::multimap<std::string, CZMQAbstractPublishNotifier *>::iterator
         iterator;
     std::pair<iterator, iterator> iterpair =
         mapPublishNotifiers.equal_range(address);
 
     for (iterator it = iterpair.first; it != iterpair.second; ++it) {
         if (it->second == this) {
             mapPublishNotifiers.erase(it);
             break;
         }
     }
 
     if (count == 1) {
         LogPrint("zmq", "Close socket at address %s\n", address);
         int linger = 0;
         zmq_setsockopt(psocket, ZMQ_LINGER, &linger, sizeof(linger));
         zmq_close(psocket);
     }
 
     psocket = 0;
 }
 
 bool CZMQAbstractPublishNotifier::SendMessage(const char *command,
                                               const void *data, size_t size) {
     assert(psocket);
 
     /* send three parts, command & data & a LE 4byte sequence number */
-    unsigned char msgseq[sizeof(uint32_t)];
+    uint8_t msgseq[sizeof(uint32_t)];
     WriteLE32(&msgseq[0], nSequence);
     int rc = zmq_send_multipart(psocket, command, strlen(command), data, size,
                                 msgseq, (size_t)sizeof(uint32_t), (void *)0);
     if (rc == -1) return false;
 
     /* increment memory only sequence number after sending */
     nSequence++;
 
     return true;
 }
 
 bool CZMQPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex) {
     uint256 hash = pindex->GetBlockHash();
     LogPrint("zmq", "zmq: Publish hashblock %s\n", hash.GetHex());
     char data[32];
     for (unsigned int i = 0; i < 32; i++)
         data[31 - i] = hash.begin()[i];
     return SendMessage(MSG_HASHBLOCK, data, 32);
 }
 
 bool CZMQPublishHashTransactionNotifier::NotifyTransaction(
     const CTransaction &transaction) {
     uint256 txid = transaction.GetId();
     LogPrint("zmq", "zmq: Publish hashtx %s\n", txid.GetHex());
     char data[32];
     for (unsigned int i = 0; i < 32; i++)
         data[31 - i] = txid.begin()[i];
     return SendMessage(MSG_HASHTX, data, 32);
 }
 
 bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) {
     LogPrint("zmq", "zmq: Publish rawblock %s\n",
              pindex->GetBlockHash().GetHex());
 
     const Consensus::Params &consensusParams = Params().GetConsensus();
     CDataStream ss(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
     {
         LOCK(cs_main);
         CBlock block;
         if (!ReadBlockFromDisk(block, pindex, consensusParams)) {
             zmqError("Can't read block from disk");
             return false;
         }
 
         ss << block;
     }
 
     return SendMessage(MSG_RAWBLOCK, &(*ss.begin()), ss.size());
 }
 
 bool CZMQPublishRawTransactionNotifier::NotifyTransaction(
     const CTransaction &transaction) {
     uint256 txid = transaction.GetId();
     LogPrint("zmq", "zmq: Publish rawtx %s\n", txid.GetHex());
     CDataStream ss(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
     ss << transaction;
     return SendMessage(MSG_RAWTX, &(*ss.begin()), ss.size());
 }