diff options
Diffstat (limited to 'src')
51 files changed, 320 insertions, 330 deletions
diff --git a/src/addrdb.cpp b/src/addrdb.cpp index a3743cd0d4..7f85c16585 100644 --- a/src/addrdb.cpp +++ b/src/addrdb.cpp @@ -15,25 +15,31 @@ #include "tinyformat.h" #include "util.h" +namespace { -CBanDB::CBanDB() +template <typename Stream, typename Data> +bool SerializeDB(Stream& stream, const Data& data) { - pathBanlist = GetDataDir() / "banlist.dat"; + // Write and commit header, data + try { + CHashWriter hasher(SER_DISK, CLIENT_VERSION); + stream << FLATDATA(Params().MessageStart()) << data; + hasher << FLATDATA(Params().MessageStart()) << data; + stream << hasher.GetHash(); + } catch (const std::exception& e) { + return error("%s: Serialize or I/O error - %s", __func__, e.what()); + } + + return true; } -bool CBanDB::Write(const banmap_t& banSet) +template <typename Data> +bool SerializeFileDB(const std::string& prefix, const fs::path& path, const Data& data) { // Generate random temporary filename unsigned short randv = 0; GetRandBytes((unsigned char*)&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; + std::string tmpfn = strprintf("%s.%04x", prefix, randv); // open temp output file, and associate with CAutoFile fs::path pathTmp = GetDataDir() / tmpfn; @@ -42,69 +48,41 @@ bool CBanDB::Write(const banmap_t& banSet) 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()); - } + // Serialize + if (!SerializeDB(fileout, data)) return false; FileCommit(fileout.Get()); fileout.fclose(); - // replace existing banlist.dat, if any, with new banlist.dat.XXXX - if (!RenameOver(pathTmp, pathBanlist)) + // replace existing file, if any, with new file + if (!RenameOver(pathTmp, path)) return error("%s: Rename-into-place failed", __func__); return true; } -bool CBanDB::Read(banmap_t& banSet) +template <typename Stream, typename Data> +bool DeserializeDB(Stream& stream, Data& data, bool fCheckSum = true) { - // open input file, and associate with CAutoFile - FILE *file = fsbridge::fopen(pathBanlist, "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 = fs::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; - 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]; try { + CHashVerifier<Stream> verifier(&stream); // de-serialize file header (network specific magic number) and .. - ssBanlist >> FLATDATA(pchMsgTmp); - + unsigned char pchMsgTmp[4]; + verifier >> 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; + // de-serialize data + verifier >> data; + + // verify checksum + if (fCheckSum) { + uint256 hashTmp; + stream >> hashTmp; + if (hashTmp != verifier.GetHash()) { + return error("%s: Checksum mismatch, data corrupted", __func__); + } + } } catch (const std::exception& e) { return error("%s: Deserialize or I/O error - %s", __func__, e.what()); @@ -113,106 +91,56 @@ bool CBanDB::Read(banmap_t& banSet) return true; } -CAddrDB::CAddrDB() +template <typename Data> +bool DeserializeFileDB(const fs::path& path, Data& data) { - pathAddr = GetDataDir() / "peers.dat"; + // open input file, and associate with CAutoFile + FILE *file = fsbridge::fopen(path, "rb"); + CAutoFile filein(file, SER_DISK, CLIENT_VERSION); + if (filein.IsNull()) + return error("%s: Failed to open file %s", __func__, path.string()); + + return DeserializeDB(filein, data); } -bool CAddrDB::Write(const CAddrMan& addr) -{ - // Generate random temporary filename - unsigned short randv = 0; - GetRandBytes((unsigned char*)&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; +CBanDB::CBanDB() +{ + pathBanlist = GetDataDir() / "banlist.dat"; +} - // open temp output file, and associate with CAutoFile - fs::path pathTmp = GetDataDir() / tmpfn; - FILE *file = fsbridge::fopen(pathTmp, "wb"); - CAutoFile fileout(file, SER_DISK, CLIENT_VERSION); - if (fileout.IsNull()) - return error("%s: Failed to open file %s", __func__, pathTmp.string()); +bool CBanDB::Write(const banmap_t& banSet) +{ + return SerializeFileDB("banlist", pathBanlist, banSet); +} - // 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(); +bool CBanDB::Read(banmap_t& banSet) +{ + return DeserializeFileDB(pathBanlist, banSet); +} - // replace existing peers.dat, if any, with new peers.dat.XXXX - if (!RenameOver(pathTmp, pathAddr)) - return error("%s: Rename-into-place failed", __func__); +CAddrDB::CAddrDB() +{ + pathAddr = GetDataDir() / "peers.dat"; +} - return true; +bool CAddrDB::Write(const CAddrMan& addr) +{ + return SerializeFileDB("peers", pathAddr, addr); } bool CAddrDB::Read(CAddrMan& addr) { - // open input file, and associate with CAutoFile - FILE *file = fsbridge::fopen(pathAddr, "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 = fs::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; - 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); + return DeserializeFileDB(pathAddr, addr); } bool CAddrDB::Read(CAddrMan& addr, CDataStream& ssPeers) { - unsigned char 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 + bool ret = DeserializeDB(ssPeers, addr, false); + if (!ret) { + // Ensure addrman is left in a clean state addr.Clear(); - return error("%s: Deserialize or I/O error - %s", __func__, e.what()); } - - return true; + return ret; } diff --git a/src/addrdb.h b/src/addrdb.h index c3d509bd3a..6cb36dfac4 100644 --- a/src/addrdb.h +++ b/src/addrdb.h @@ -85,7 +85,7 @@ public: CAddrDB(); bool Write(const CAddrMan& addr); bool Read(CAddrMan& addr); - bool Read(CAddrMan& addr, CDataStream& ssPeers); + static bool Read(CAddrMan& addr, CDataStream& ssPeers); }; /** Access to the banlist database (banlist.dat) */ diff --git a/src/arith_uint256.cpp b/src/arith_uint256.cpp index dd34a313b7..b4952af6f4 100644 --- a/src/arith_uint256.cpp +++ b/src/arith_uint256.cpp @@ -15,6 +15,8 @@ template <unsigned int BITS> base_uint<BITS>::base_uint(const std::string& str) { + static_assert(BITS/32 > 0 && BITS%32 == 0, "Template parameter BITS must be a positive multiple of 32."); + SetHex(str); } diff --git a/src/arith_uint256.h b/src/arith_uint256.h index 0f6b3d4fba..c7734035df 100644 --- a/src/arith_uint256.h +++ b/src/arith_uint256.h @@ -31,12 +31,16 @@ public: base_uint() { + static_assert(BITS/32 > 0 && BITS%32 == 0, "Template parameter BITS must be a positive multiple of 32."); + for (int i = 0; i < WIDTH; i++) pn[i] = 0; } base_uint(const base_uint& b) { + static_assert(BITS/32 > 0 && BITS%32 == 0, "Template parameter BITS must be a positive multiple of 32."); + for (int i = 0; i < WIDTH; i++) pn[i] = b.pn[i]; } @@ -50,6 +54,8 @@ public: base_uint(uint64_t b) { + static_assert(BITS/32 > 0 && BITS%32 == 0, "Template parameter BITS must be a positive multiple of 32."); + pn[0] = (unsigned int)b; pn[1] = (unsigned int)(b >> 32); for (int i = 2; i < WIDTH; i++) @@ -174,7 +180,7 @@ public: { // prefix operator int i = 0; - while (++pn[i] == 0 && i < WIDTH-1) + while (i < WIDTH && ++pn[i] == 0) i++; return *this; } @@ -191,7 +197,7 @@ public: { // prefix operator int i = 0; - while (--pn[i] == (uint32_t)-1 && i < WIDTH-1) + while (i < WIDTH && --pn[i] == (uint32_t)-1) i++; return *this; } diff --git a/src/bench/bench_bitcoin.cpp b/src/bench/bench_bitcoin.cpp index 61a0b31aed..226861aa7f 100644 --- a/src/bench/bench_bitcoin.cpp +++ b/src/bench/bench_bitcoin.cpp @@ -7,10 +7,12 @@ #include "key.h" #include "validation.h" #include "util.h" +#include "random.h" int main(int argc, char** argv) { + RandomInit(); ECC_Start(); SetupEnvironment(); fPrintToDebugLog = false; // don't want to write to debug.log file diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 714ee555ec..6093f78fb1 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -299,7 +299,6 @@ static void MutateTxAddOutPubKey(CMutableTransaction& tx, const std::string& str if (!pubkey.IsFullyValid()) throw std::runtime_error("invalid TX output pubkey"); CScript scriptPubKey = GetScriptForRawPubKey(pubkey); - CBitcoinAddress addr(scriptPubKey); // Extract and validate FLAGS bool bSegWit = false; diff --git a/src/chain.cpp b/src/chain.cpp index a5b369c4fc..8d4c4e7dea 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -126,7 +126,7 @@ arith_uint256 GetBlockProof(const CBlockIndex& block) if (fNegative || fOverflow || bnTarget == 0) return 0; // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256 - // as it's too large for a arith_uint256. However, as 2**256 is at least as large + // as it's too large for an arith_uint256. However, as 2**256 is at least as large // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1, // or ~bnTarget / (nTarget+1) + 1. return (~bnTarget / (bnTarget + 1)) + 1; diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 3b42c5fb23..dc4d2621ee 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -124,12 +124,12 @@ public: assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); // Note that of those with the service bits flag, most only support a subset of possible options - vSeeds.push_back(CDNSSeedData("bitcoin.sipa.be", "seed.bitcoin.sipa.be", true)); // Pieter Wuille, only supports x1, x5, x9, and xd - vSeeds.push_back(CDNSSeedData("bluematt.me", "dnsseed.bluematt.me", true)); // Matt Corallo, only supports x9 - vSeeds.push_back(CDNSSeedData("dashjr.org", "dnsseed.bitcoin.dashjr.org")); // Luke Dashjr - vSeeds.push_back(CDNSSeedData("bitcoinstats.com", "seed.bitcoinstats.com", true)); // Christian Decker, supports x1 - xf - vSeeds.push_back(CDNSSeedData("bitcoin.jonasschnelli.ch", "seed.bitcoin.jonasschnelli.ch", true)); // Jonas Schnelli, only supports x1, x5, x9, and xd - vSeeds.push_back(CDNSSeedData("petertodd.org", "seed.btc.petertodd.org", true)); // Peter Todd, only supports x1, x5, x9, and xd + vSeeds.emplace_back("seed.bitcoin.sipa.be", true); // Pieter Wuille, only supports x1, x5, x9, and xd + vSeeds.emplace_back("dnsseed.bluematt.me", true); // Matt Corallo, only supports x9 + vSeeds.emplace_back("dnsseed.bitcoin.dashjr.org", false); // Luke Dashjr + vSeeds.emplace_back("seed.bitcoinstats.com", true); // Christian Decker, supports x1 - xf + vSeeds.emplace_back("seed.bitcoin.jonasschnelli.ch", true); // Jonas Schnelli, only supports x1, x5, x9, and xd + vSeeds.emplace_back("seed.btc.petertodd.org", true); // Peter Todd, only supports x1, x5, x9, and xd base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,0); base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,5); @@ -225,10 +225,10 @@ public: vFixedSeeds.clear(); vSeeds.clear(); // nodes with support for servicebits filtering should be at the top - vSeeds.push_back(CDNSSeedData("testnetbitcoin.jonasschnelli.ch", "testnet-seed.bitcoin.jonasschnelli.ch", true)); - vSeeds.push_back(CDNSSeedData("petertodd.org", "seed.tbtc.petertodd.org", true)); - vSeeds.push_back(CDNSSeedData("bluematt.me", "testnet-seed.bluematt.me")); - vSeeds.push_back(CDNSSeedData("bitcoin.schildbach.de", "testnet-seed.bitcoin.schildbach.de")); + vSeeds.emplace_back("testnet-seed.bitcoin.jonasschnelli.ch", true); + vSeeds.emplace_back("seed.tbtc.petertodd.org", true); + vSeeds.emplace_back("testnet-seed.bluematt.me", false); + vSeeds.emplace_back("testnet-seed.bitcoin.schildbach.de", false); base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,111); base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196); diff --git a/src/chainparams.h b/src/chainparams.h index a2f136171b..f55ae4cf7f 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -15,9 +15,9 @@ #include <vector> struct CDNSSeedData { - std::string name, host; + std::string host; bool supportsServiceBitsFiltering; - CDNSSeedData(const std::string &strName, const std::string &strHost, bool supportsServiceBitsFilteringIn = false) : name(strName), host(strHost), supportsServiceBitsFiltering(supportsServiceBitsFilteringIn) {} + CDNSSeedData(const std::string &strHost, bool supportsServiceBitsFilteringIn) : host(strHost), supportsServiceBitsFiltering(supportsServiceBitsFilteringIn) {} }; struct SeedSpec6 { diff --git a/src/coins.cpp b/src/coins.cpp index b45fc76338..2dceaf09b6 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -91,9 +91,9 @@ void AddCoins(CCoinsViewCache& cache, const CTransaction &tx, int nHeight) { } } -void CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) { +bool CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) { CCoinsMap::iterator it = FetchCoin(outpoint); - if (it == cacheCoins.end()) return; + if (it == cacheCoins.end()) return false; cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage(); if (moveout) { *moveout = std::move(it->second.coin); @@ -104,6 +104,7 @@ void CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) { it->second.flags |= CCoinsCacheEntry::DIRTY; it->second.coin.Clear(); } + return true; } static const Coin coinEmpty; diff --git a/src/coins.h b/src/coins.h index dc3210b8ac..4774c9f6a6 100644 --- a/src/coins.h +++ b/src/coins.h @@ -224,8 +224,13 @@ public: /** * Return a reference to 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. + * more efficient than GetCoin. + * + * Generally, do not hold the reference returned for more than a short scope. + * While the current implementation allows for modifications to the contents + * of the cache while holding the reference, this behavior should not be relied + * on! To be safe, best to not hold the returned reference through any other + * calls to this cache. */ const Coin& AccessCoin(const COutPoint &output) const; @@ -240,7 +245,7 @@ public: * If no unspent output exists for the passed outpoint, this call * has no effect. */ - void SpendCoin(const COutPoint &outpoint, Coin* moveto = nullptr); + bool SpendCoin(const COutPoint &outpoint, Coin* moveto = nullptr); /** * Push the modifications applied to this cache to its base. diff --git a/src/consensus/tx_verify.cpp b/src/consensus/tx_verify.cpp index bf68f8754b..0671cbc132 100644 --- a/src/consensus/tx_verify.cpp +++ b/src/consensus/tx_verify.cpp @@ -126,7 +126,9 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in unsigned int nSigOps = 0; for (unsigned int i = 0; i < tx.vin.size(); i++) { - const CTxOut &prevout = inputs.AccessCoin(tx.vin[i].prevout).out; + const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout); + assert(!coin.IsSpent()); + const CTxOut &prevout = coin.out; if (prevout.scriptPubKey.IsPayToScriptHash()) nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig); } @@ -146,7 +148,9 @@ int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& i for (unsigned int i = 0; i < tx.vin.size(); i++) { - const CTxOut &prevout = inputs.AccessCoin(tx.vin[i].prevout).out; + const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout); + assert(!coin.IsSpent()); + const CTxOut &prevout = coin.out; nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, prevout.scriptPubKey, &tx.vin[i].scriptWitness, flags); } return nSigOps; diff --git a/src/cuckoocache.h b/src/cuckoocache.h index 5837549455..fd24d05ee7 100644 --- a/src/cuckoocache.h +++ b/src/cuckoocache.h @@ -176,7 +176,7 @@ private: */ mutable std::vector<bool> epoch_flags; - /** epoch_heuristic_counter is used to determine when a epoch might be aged + /** epoch_heuristic_counter is used to determine when an epoch might be aged * & an expensive scan should be done. epoch_heuristic_counter is * decremented on insert and reset to the new number of inserts which would * cause the epoch to reach epoch_size when it reaches zero. @@ -184,7 +184,7 @@ private: uint32_t epoch_heuristic_counter; /** epoch_size is set to be the number of elements supposed to be in a - * epoch. When the number of non-erased elements in a epoch + * epoch. When the number of non-erased elements in an epoch * exceeds epoch_size, a new epoch should be started and all * current entries demoted. epoch_size is set to be 45% of size because * we want to keep load around 90%, and we support 3 epochs at once -- @@ -206,6 +206,37 @@ private: /** compute_hashes is convenience for not having to write out this * expression everywhere we use the hash values of an Element. * + * We need to map the 32-bit input hash onto a hash bucket in a range [0, size) in a + * manner which preserves as much of the hash's uniformity as possible. Ideally + * this would be done by bitmasking but the size is usually not a power of two. + * + * The naive approach would be to use a mod -- which isn't perfectly uniform but so + * long as the hash is much larger than size it is not that bad. Unfortunately, + * mod/division is fairly slow on ordinary microprocessors (e.g. 90-ish cycles on + * haswell, ARM doesn't even have an instruction for it.); when the divisor is a + * constant the compiler will do clever tricks to turn it into a multiply+add+shift, + * but size is a run-time value so the compiler can't do that here. + * + * One option would be to implement the same trick the compiler uses and compute the + * constants for exact division based on the size, as described in "{N}-bit Unsigned + * Division via {N}-bit Multiply-Add" by Arch D. Robison in 2005. But that code is + * somewhat complicated and the result is still slower than other options: + * + * Instead we treat the 32-bit random number as a Q32 fixed-point number in the range + * [0,1) and simply multiply it by the size. Then we just shift the result down by + * 32-bits to get our bucket number. The results has non-uniformity the same as a + * mod, but it is much faster to compute. More about this technique can be found at + * http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/ + * + * The resulting non-uniformity is also more equally distributed which would be + * advantageous for something like linear probing, though it shouldn't matter + * one way or the other for a cuckoo table. + * + * The primary disadvantage of this approach is increased intermediate precision is + * required but for a 32-bit random number we only need the high 32 bits of a + * 32*32->64 multiply, which means the operation is reasonably fast even on a + * typical 32-bit processor. + * * @param e the element whose hashes will be returned * @returns std::array<uint32_t, 8> of deterministic hashes derived from e */ diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 0d1cba3fd2..1557cf98f8 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -21,13 +21,13 @@ #include <signal.h> #include <future> -#include <event2/event.h> -#include <event2/http.h> #include <event2/thread.h> #include <event2/buffer.h> #include <event2/util.h> #include <event2/keyvalq_struct.h> +#include "support/events.h" + #ifdef EVENT__HAVE_NETINET_IN_H #include <netinet/in.h> #ifdef _XOPEN_SOURCE_EXTENDED @@ -367,9 +367,6 @@ static void libevent_log_cb(int severity, const char *msg) bool InitHTTPServer() { - struct evhttp* http = 0; - struct event_base* base = 0; - if (!InitHTTPAllowList()) return false; @@ -395,17 +392,13 @@ bool InitHTTPServer() evthread_use_pthreads(); #endif - base = event_base_new(); // XXX RAII - if (!base) { - LogPrintf("Couldn't create an event_base: exiting\n"); - return false; - } + raii_event_base base_ctr = obtain_event_base(); /* Create a new evhttp object to handle requests. */ - http = evhttp_new(base); // XXX RAII + raii_evhttp http_ctr = obtain_evhttp(base_ctr.get()); + struct evhttp* http = http_ctr.get(); if (!http) { LogPrintf("couldn't create evhttp. Exiting.\n"); - event_base_free(base); return false; } @@ -416,8 +409,6 @@ bool InitHTTPServer() if (!HTTPBindAddresses(http)) { LogPrintf("Unable to bind any endpoint for RPC server\n"); - evhttp_free(http); - event_base_free(base); return false; } @@ -426,8 +417,9 @@ bool InitHTTPServer() LogPrintf("HTTP: creating work queue of depth %d\n", workQueueDepth); workQueue = new WorkQueue<HTTPClosure>(workQueueDepth); - eventBase = base; - eventHTTP = http; + // tranfer ownership to eventBase/HTTP via .release() + eventBase = base_ctr.release(); + eventHTTP = http_ctr.release(); return true; } diff --git a/src/httpserver.h b/src/httpserver.h index 6be9950682..9df56e5fc5 100644 --- a/src/httpserver.h +++ b/src/httpserver.h @@ -86,7 +86,7 @@ public: /** * Get the request header specified by hdr, or an empty string. - * Return an pair (isPresent,string). + * Return a pair (isPresent,string). */ std::pair<bool, std::string> GetHeader(const std::string& hdr); @@ -125,7 +125,7 @@ public: virtual ~HTTPClosure() {} }; -/** Event class. This can be used either as an cross-thread trigger or as a timer. +/** Event class. This can be used either as a cross-thread trigger or as a timer. */ class HTTPEvent { diff --git a/src/init.cpp b/src/init.cpp index ed7695344d..686a31b0f4 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -844,8 +844,6 @@ bool AppInitBasicSetup() // Turn off Microsoft heap dump noise _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); -#endif -#if _MSC_VER >= 1400 // Disable confusing "helpful" text message on abort, Ctrl-C _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); #endif @@ -1030,14 +1028,7 @@ bool AppInitParameterInteraction() if (nConnectTimeout <= 0) nConnectTimeout = DEFAULT_CONNECT_TIMEOUT; - // Fee-per-kilobyte amount required for mempool acceptance and relay - // If you are mining, be careful setting this: - // if you set it to zero then - // a transaction spammer can cheaply fill blocks using - // 0-fee transactions. It should be set above the real - // cost to you of processing a transaction. - if (IsArgSet("-minrelaytxfee")) - { + if (IsArgSet("-minrelaytxfee")) { CAmount n = 0; if (!ParseMoney(GetArg("-minrelaytxfee", ""), n)) { return InitError(AmountErrMsg("minrelaytxfee", GetArg("-minrelaytxfee", ""))); diff --git a/src/leveldb/db/version_set.h b/src/leveldb/db/version_set.h index c4e7ac360b..7935a965a7 100644 --- a/src/leveldb/db/version_set.h +++ b/src/leveldb/db/version_set.h @@ -376,7 +376,7 @@ class Compaction { // Each compaction reads inputs from "level_" and "level_+1" std::vector<FileMetaData*> inputs_[2]; // The two sets of inputs - // State used to check for number of of overlapping grandparent files + // State used to check for number of overlapping grandparent files // (parent == level_ + 1, grandparent == level_ + 2) std::vector<FileMetaData*> grandparents_; size_t grandparent_index_; // Index in grandparent_starts_ diff --git a/src/net.cpp b/src/net.cpp index 73f020273b..43bd0eb0d5 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -240,7 +240,7 @@ bool RemoveLocal(const CService& addr) /** Make a particular network entirely off-limits (no automatic connects to it) */ void SetLimited(enum Network net, bool fLimited) { - if (net == NET_UNROUTABLE) + if (net == NET_UNROUTABLE || net == NET_INTERNAL) return; LOCK(cs_mapLocalHost); vfLimited[net] = fLimited; @@ -1604,7 +1604,12 @@ void CConnman::ThreadDNSAddressSeed() std::vector<CNetAddr> vIPs; std::vector<CAddress> vAdd; ServiceFlags requiredServiceBits = nRelevantServices; - if (LookupHost(GetDNSHost(seed, &requiredServiceBits).c_str(), vIPs, 0, true)) + std::string host = GetDNSHost(seed, &requiredServiceBits); + CNetAddr resolveSource; + if (!resolveSource.SetInternal(host)) { + continue; + } + if (LookupHost(host.c_str(), vIPs, 0, true)) { for (const CNetAddr& ip : vIPs) { @@ -1614,18 +1619,7 @@ void CConnman::ThreadDNSAddressSeed() vAdd.push_back(addr); found++; } - } - if (interruptNet) { - return; - } - // 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); + addrman.Add(vAdd, resolveSource); } } } @@ -1724,7 +1718,7 @@ void CConnman::ThreadOpenConnections() 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); + local.SetInternal("fixedseeds"); addrman.Add(convertSeed6(Params().FixedSeeds()), local); done = true; } diff --git a/src/net_processing.cpp b/src/net_processing.cpp index b9357440e9..91681265b1 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -342,7 +342,9 @@ bool MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, const CBlockIndex* // 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; + if (pit) { + *pit = &itInFlight->second.second; + } return false; } diff --git a/src/netaddress.cpp b/src/netaddress.cpp index 34a7029862..89f257c642 100644 --- a/src/netaddress.cpp +++ b/src/netaddress.cpp @@ -15,6 +15,9 @@ 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}; +// 0xFD + sha256("bitcoin")[0:5] +static const unsigned char g_internal_prefix[] = { 0xFD, 0x6B, 0x88, 0xC0, 0x87, 0x24 }; + void CNetAddr::Init() { memset(ip, 0, sizeof(ip)); @@ -42,6 +45,18 @@ void CNetAddr::SetRaw(Network network, const uint8_t *ip_in) } } +bool CNetAddr::SetInternal(const std::string &name) +{ + if (name.empty()) { + return false; + } + unsigned char hash[32] = {}; + CSHA256().Write((const unsigned char*)name.data(), name.size()).Finalize(hash); + memcpy(ip, g_internal_prefix, sizeof(g_internal_prefix)); + memcpy(ip + sizeof(g_internal_prefix), hash, sizeof(ip) - sizeof(g_internal_prefix)); + return true; +} + bool CNetAddr::SetSpecial(const std::string &strName) { if (strName.size()>6 && strName.substr(strName.size() - 6, 6) == ".onion") { @@ -84,7 +99,7 @@ bool CNetAddr::IsIPv4() const bool CNetAddr::IsIPv6() const { - return (!IsIPv4() && !IsTor()); + return (!IsIPv4() && !IsTor() && !IsInternal()); } bool CNetAddr::IsRFC1918() const @@ -199,6 +214,9 @@ bool CNetAddr::IsValid() const if (IsRFC3849()) return false; + if (IsInternal()) + return false; + if (IsIPv4()) { // INADDR_NONE @@ -217,11 +235,19 @@ bool CNetAddr::IsValid() const bool CNetAddr::IsRoutable() const { - return IsValid() && !(IsRFC1918() || IsRFC2544() || IsRFC3927() || IsRFC4862() || IsRFC6598() || IsRFC5737() || (IsRFC4193() && !IsTor()) || IsRFC4843() || IsLocal()); + return IsValid() && !(IsRFC1918() || IsRFC2544() || IsRFC3927() || IsRFC4862() || IsRFC6598() || IsRFC5737() || (IsRFC4193() && !IsTor()) || IsRFC4843() || IsLocal() || IsInternal()); +} + +bool CNetAddr::IsInternal() const +{ + return memcmp(ip, g_internal_prefix, sizeof(g_internal_prefix)) == 0; } enum Network CNetAddr::GetNetwork() const { + if (IsInternal()) + return NET_INTERNAL; + if (!IsRoutable()) return NET_UNROUTABLE; @@ -238,6 +264,8 @@ std::string CNetAddr::ToStringIP() const { if (IsTor()) return EncodeBase32(&ip[6], 10) + ".onion"; + if (IsInternal()) + return EncodeBase32(ip + sizeof(g_internal_prefix), sizeof(ip) - sizeof(g_internal_prefix)) + ".internal"; CService serv(*this, 0); struct sockaddr_storage sockaddr; socklen_t socklen = sizeof(sockaddr); @@ -305,9 +333,15 @@ std::vector<unsigned char> CNetAddr::GetGroup() const nClass = 255; nBits = 0; } - - // all unroutable addresses belong to the same group - if (!IsRoutable()) + // all internal-usage addresses get their own group + if (IsInternal()) + { + nClass = NET_INTERNAL; + nStartByte = sizeof(g_internal_prefix); + nBits = (sizeof(ip) - sizeof(g_internal_prefix)) * 8; + } + // all other unroutable addresses belong to the same group + else if (!IsRoutable()) { nClass = NET_UNROUTABLE; nBits = 0; @@ -393,7 +427,7 @@ int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const REACH_PRIVATE }; - if (!IsRoutable()) + if (!IsRoutable() || IsInternal()) return REACH_UNREACHABLE; int ourNet = GetExtNetwork(this); @@ -552,7 +586,7 @@ std::string CService::ToStringPort() const std::string CService::ToStringIPPort() const { - if (IsIPv4() || IsTor()) { + if (IsIPv4() || IsTor() || IsInternal()) { return ToStringIP() + ":" + ToStringPort(); } else { return "[" + ToStringIP() + "]:" + ToStringPort(); diff --git a/src/netaddress.h b/src/netaddress.h index fbc4d1a65f..80716600d1 100644 --- a/src/netaddress.h +++ b/src/netaddress.h @@ -22,6 +22,7 @@ enum Network NET_IPV4, NET_IPV6, NET_TOR, + NET_INTERNAL, NET_MAX, }; @@ -45,6 +46,12 @@ class CNetAddr */ void SetRaw(Network network, const uint8_t *data); + /** + * Transform an arbitrary string into a non-routable ipv6 address. + * Useful for mapping resolved addresses back to their source. + */ + bool SetInternal(const std::string& name); + bool SetSpecial(const std::string &strName); // for Tor addresses bool IsIPv4() const; // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0) bool IsIPv6() const; // IPv6 address (not mapped IPv4, not Tor) @@ -64,6 +71,7 @@ class CNetAddr bool IsTor() const; bool IsLocal() const; bool IsRoutable() const; + bool IsInternal() const; bool IsValid() const; enum Network GetNetwork() const; std::string ToString() const; diff --git a/src/netbase.cpp b/src/netbase.cpp index 32557dd179..a23f92e1ed 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -108,17 +108,22 @@ bool static LookupIntern(const char *pszName, std::vector<CNetAddr>& vIP, unsign struct addrinfo *aiTrav = aiRes; while (aiTrav != NULL && (nMaxSolutions == 0 || vIP.size() < nMaxSolutions)) { + CNetAddr resolved; if (aiTrav->ai_family == AF_INET) { assert(aiTrav->ai_addrlen >= sizeof(sockaddr_in)); - vIP.push_back(CNetAddr(((struct sockaddr_in*)(aiTrav->ai_addr))->sin_addr)); + resolved = CNetAddr(((struct sockaddr_in*)(aiTrav->ai_addr))->sin_addr); } if (aiTrav->ai_family == AF_INET6) { assert(aiTrav->ai_addrlen >= sizeof(sockaddr_in6)); struct sockaddr_in6* s6 = (struct sockaddr_in6*) aiTrav->ai_addr; - vIP.push_back(CNetAddr(s6->sin6_addr, s6->sin6_scope_id)); + resolved = CNetAddr(s6->sin6_addr, s6->sin6_scope_id); + } + /* Never allow resolving to an internal address. Consider any such result invalid */ + if (!resolved.IsInternal()) { + vIP.push_back(resolved); } aiTrav = aiTrav->ai_next; diff --git a/src/policy/fees.h b/src/policy/fees.h index 7125a74f03..2029ce3744 100644 --- a/src/policy/fees.h +++ b/src/policy/fees.h @@ -48,7 +48,7 @@ class TxConfirmStats; * in each bucket and the total amount of feerate paid in each bucket. Then we * calculate how many blocks Y it took each transaction to be mined. We convert * from a number of blocks to a number of periods Y' each encompassing "scale" - * blocks. This is is tracked in 3 different data sets each up to a maximum + * blocks. This is tracked in 3 different data sets each up to a maximum * number of periods. Within each data set we have an array of counters in each * feerate bucket and we increment all the counters from Y' up to max periods * representing that a tx was successfully confirmed in less than or equal to diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index de00eacdb9..3dfb51ccfa 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -303,7 +303,7 @@ static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CB } // if we are in-sync, update the UI regardless of last update time if (!initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) { - //pass a async signal to the UI thread + //pass an async signal to the UI thread QMetaObject::invokeMethod(clientmodel, "numBlocksChanged", Qt::QueuedConnection, Q_ARG(int, pIndex->nHeight), Q_ARG(QDateTime, QDateTime::fromTime_t(pIndex->GetBlockTime())), diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index b9da48ee1d..af9a888d94 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -499,7 +499,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) { // there is some fudging in these numbers related to the actual virtual transaction size calculation that will keep this estimate from being exact. // usually, the result will be an overestimate within a couple of satoshis so that the confirmation dialog ends up displaying a slightly smaller fee. - // also, the witness stack size value value is a variable sized integer. usually, the number of stack items will be well under the single byte var int limit. + // also, the witness stack size value is a variable sized integer. usually, the number of stack items will be well under the single byte var int limit. nBytes += 2; // account for the serialized marker and flag bytes nBytes += nQuantity; // account for the witness byte that holds the number of stack items for each input. } @@ -524,13 +524,10 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) CTxOut txout(nChange, (CScript)std::vector<unsigned char>(24, 0)); if (IsDust(txout, ::dustRelayFee)) { - if (CoinControlDialog::fSubtractFeeFromAmount) // dust-change will be raised until no dust - nChange = GetDustThreshold(txout, ::dustRelayFee); - else - { - nPayFee += nChange; - nChange = 0; - } + nPayFee += nChange; + nChange = 0; + if (CoinControlDialog::fSubtractFeeFromAmount) + nBytes -= 34; // we didn't detect lack of change above } } diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui index 0f1b3f4a73..14078b9ee8 100644 --- a/src/qt/forms/optionsdialog.ui +++ b/src/qt/forms/optionsdialog.ui @@ -315,7 +315,7 @@ <bool>false</bool> </property> <property name="toolTip"> - <string>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</string> + <string>Shows if the supplied default SOCKS5 proxy is used to reach peers via this network type.</string> </property> <property name="text"> <string/> @@ -338,7 +338,7 @@ <bool>false</bool> </property> <property name="toolTip"> - <string>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</string> + <string>Shows if the supplied default SOCKS5 proxy is used to reach peers via this network type.</string> </property> <property name="text"> <string/> @@ -361,7 +361,7 @@ <bool>false</bool> </property> <property name="toolTip"> - <string>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</string> + <string>Shows if the supplied default SOCKS5 proxy is used to reach peers via this network type.</string> </property> <property name="text"> <string/> diff --git a/src/qt/modaloverlay.cpp b/src/qt/modaloverlay.cpp index 4779ffa43f..a83f285034 100644 --- a/src/qt/modaloverlay.cpp +++ b/src/qt/modaloverlay.cpp @@ -126,7 +126,7 @@ void ModalOverlay::tipUpdate(int count, const QDateTime& blockDate, double nVeri return; // estimate the number of headers left based on nPowTargetSpacing - // and check if the gui is not aware of the the best header (happens rarely) + // and check if the gui is not aware of the best header (happens rarely) int estimateNumHeadersLeft = bestHeaderDate.secsTo(currentDate) / Params().GetConsensus().nPowTargetSpacing; bool hasBestHeader = bestHeaderHeight >= count; diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index b17693e1ca..ec0580b81c 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -672,7 +672,7 @@ void RPCConsole::setFontSize(int newSize) { QSettings settings; - //don't allow a insane font size + //don't allow an insane font size if (newSize < FONT_RANGE.width() || newSize > FONT_RANGE.height()) return; @@ -738,7 +738,7 @@ void RPCConsole::clear(bool clearHistory) tr("Use up and down arrows to navigate history, and %1 to clear screen.").arg("<b>"+clsKey+"</b>") + "<br>" + tr("Type <b>help</b> for an overview of available commands.")) + "<br><span class=\"secwarning\">" + - tr("WARNING: Scammers have been active, telling users to type commands here, stealing their wallet contents. Do not use this console without fully understanding the ramification of a command.") + + tr("WARNING: Scammers have been active, telling users to type commands here, stealing their wallet contents. Do not use this console without fully understanding the ramifications of a command.") + "</span>", true); } diff --git a/src/qt/test/rpcnestedtests.cpp b/src/qt/test/rpcnestedtests.cpp index dada689731..26dec3c610 100644 --- a/src/qt/test/rpcnestedtests.cpp +++ b/src/qt/test/rpcnestedtests.cpp @@ -33,8 +33,6 @@ static const CRPCCommand vRPCCommands[] = void RPCNestedTests::rpcNestedTests() { - UniValue jsonRPCError; - // do some test setup // could be moved to a more generic place when we add more tests on QT level const CChainParams& chainparams = Params(); diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 449eb1ae58..6538a80233 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -339,7 +339,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran transaction_array.append(&(ssTx[0]), ssTx.size()); } - // Add addresses / update labels that we've sent to to the address book, + // Add addresses / update labels that we've sent to the address book, // and emit coinsSent signal for each recipient for (const SendCoinsRecipient &rcp : transaction.getRecipients()) { diff --git a/src/rest.cpp b/src/rest.cpp index 8fb0c13fa5..33e3fb4529 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -413,7 +413,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) boost::split(uriParts, strUriParams, boost::is_any_of("/")); } - // throw exception in case of a empty request + // throw exception in case of an empty request std::string strRequestMutable = req->ReadBody(); if (strRequestMutable.length() == 0 && uriParts.size() == 0) return RESTERR(req, HTTP_BAD_REQUEST, "Error: empty request"); diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 3b212dc0e4..8c682592c5 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -722,19 +722,16 @@ protected: UniValue submitblock(const JSONRPCRequest& request) { + // We allow 2 arguments for compliance with BIP22. Argument 2 is ignored. if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { throw std::runtime_error( - "submitblock \"hexdata\" ( \"jsonparametersobject\" )\n" + "submitblock \"hexdata\" ( \"dummy\" )\n" "\nAttempts to submit new block to network.\n" - "The 'jsonparametersobject' parameter is currently ignored.\n" "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n" "\nArguments\n" "1. \"hexdata\" (string, required) the hex-encoded block data to submit\n" - "2. \"parameters\" (string, optional) object of optional parameters\n" - " {\n" - " \"workid\" : \"id\" (string, optional) if the server provided a workid, it MUST be included with submissions\n" - " }\n" + "2. \"dummy\" (optional) dummy value, for compatibility with BIP22. This value is ignored.\n" "\nResult:\n" "\nExamples:\n" + HelpExampleCli("submitblock", "\"mydata\"") @@ -963,7 +960,7 @@ static const CRPCCommand commands[] = { "mining", "getmininginfo", &getmininginfo, true, {} }, { "mining", "prioritisetransaction", &prioritisetransaction, true, {"txid","dummy","fee_delta"} }, { "mining", "getblocktemplate", &getblocktemplate, true, {"template_request"} }, - { "mining", "submitblock", &submitblock, true, {"hexdata","parameters"} }, + { "mining", "submitblock", &submitblock, true, {"hexdata","dummy"} }, { "generating", "generate", &generate, true, {"nblocks","maxtries"} }, { "generating", "generatetoaddress", &generatetoaddress, true, {"nblocks","address","maxtries"} }, diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index d6f9f0059c..5cab0ad5bd 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -75,7 +75,7 @@ UniValue getpeerinfo(const JSONRPCRequest& request) "[\n" " {\n" " \"id\": n, (numeric) Peer index\n" - " \"addr\":\"host:port\", (string) The ip address and port of the peer\n" + " \"addr\":\"host:port\", (string) The IP address and port of the peer\n" " \"addrbind\":\"ip:port\", (string) Bind address of the connection to the peer\n" " \"addrlocal\":\"ip:port\", (string) Local address as reported by the peer\n" " \"services\":\"xxxxxxxxxxxxxxxx\", (string) The services offered\n" @@ -199,7 +199,7 @@ UniValue addnode(const JSONRPCRequest& request) (strCommand != "onetry" && strCommand != "add" && strCommand != "remove")) throw std::runtime_error( "addnode \"node\" \"add|remove|onetry\"\n" - "\nAttempts add or remove a node from the addnode list.\n" + "\nAttempts to add or remove a node from the addnode list.\n" "Or try a connection to a node once.\n" "\nArguments:\n" "1. \"node\" (string, required) The node (see getpeerinfo for nodes)\n" @@ -290,7 +290,7 @@ UniValue getaddednodeinfo(const JSONRPCRequest& request) "\nResult:\n" "[\n" " {\n" - " \"addednode\" : \"192.168.0.201\", (string) The node ip address or name (as provided to addnode)\n" + " \"addednode\" : \"192.168.0.201\", (string) The node IP address or name (as provided to addnode)\n" " \"connected\" : true|false, (boolean) If connected\n" " \"addresses\" : [ (list of objects) Only when connected = true\n" " {\n" @@ -397,7 +397,7 @@ static UniValue GetNetworksInfo() for(int n=0; n<NET_MAX; ++n) { enum Network network = static_cast<enum Network>(n); - if(network == NET_UNROUTABLE) + if(network == NET_UNROUTABLE || network == NET_INTERNAL) continue; proxyType proxy; UniValue obj(UniValue::VOBJ); @@ -497,12 +497,12 @@ UniValue setban(const JSONRPCRequest& request) (strCommand != "add" && strCommand != "remove")) throw std::runtime_error( "setban \"subnet\" \"add|remove\" (bantime) (absolute)\n" - "\nAttempts add or remove a IP/Subnet from the banned list.\n" + "\nAttempts to add or remove an IP/Subnet from the banned list.\n" "\nArguments:\n" - "1. \"subnet\" (string, required) The IP/Subnet (see getpeerinfo for nodes ip) with a optional netmask (default is /32 = single ip)\n" - "2. \"command\" (string, required) 'add' to add a IP/Subnet to the list, 'remove' to remove a IP/Subnet from the list\n" - "3. \"bantime\" (numeric, optional) time in seconds how long (or until when if [absolute] is set) the ip is banned (0 or empty means using the default time of 24h which can also be overwritten by the -bantime startup argument)\n" - "4. \"absolute\" (boolean, optional) If set, the bantime must be a absolute timestamp in seconds since epoch (Jan 1 1970 GMT)\n" + "1. \"subnet\" (string, required) The IP/Subnet (see getpeerinfo for nodes IP) with an optional netmask (default is /32 = single IP)\n" + "2. \"command\" (string, required) 'add' to add an IP/Subnet to the list, 'remove' to remove an IP/Subnet from the list\n" + "3. \"bantime\" (numeric, optional) time in seconds how long (or until when if [absolute] is set) the IP is banned (0 or empty means using the default time of 24h which can also be overwritten by the -bantime startup argument)\n" + "4. \"absolute\" (boolean, optional) If set, the bantime must be an absolute timestamp in seconds since epoch (Jan 1 1970 GMT)\n" "\nExamples:\n" + HelpExampleCli("setban", "\"192.168.0.6\" \"add\" 86400") + HelpExampleCli("setban", "\"192.168.0.0/24\" \"add\"") diff --git a/src/secp256k1/sage/group_prover.sage b/src/secp256k1/sage/group_prover.sage index ab580c5b23..5198724bea 100644 --- a/src/secp256k1/sage/group_prover.sage +++ b/src/secp256k1/sage/group_prover.sage @@ -3,7 +3,7 @@ # to independently set assumptions on input or intermediary variables. # # The general approach is: -# * A constraint is a tuple of two sets of of symbolic expressions: +# * A constraint is a tuple of two sets of symbolic expressions: # the first of which are required to evaluate to zero, the second of which # are required to evaluate to nonzero. # - A constraint is said to be conflicting if any of its nonzero expressions diff --git a/src/secp256k1/src/asm/field_10x26_arm.s b/src/secp256k1/src/asm/field_10x26_arm.s index 5df561f2fc..bd2b629e1c 100644 --- a/src/secp256k1/src/asm/field_10x26_arm.s +++ b/src/secp256k1/src/asm/field_10x26_arm.s @@ -11,7 +11,7 @@ Note: - To avoid unnecessary loads and make use of available registers, two 'passes' have every time been interleaved, with the odd passes accumulating c' and d' - which will be added to c and d respectively in the the even passes + which will be added to c and d respectively in the even passes */ diff --git a/src/support/events.h b/src/support/events.h index 4f2f3cf9ef..90690876ee 100644 --- a/src/support/events.h +++ b/src/support/events.h @@ -27,26 +27,26 @@ MAKE_RAII(evhttp); MAKE_RAII(evhttp_request); MAKE_RAII(evhttp_connection); -raii_event_base obtain_event_base() { +inline raii_event_base obtain_event_base() { auto result = raii_event_base(event_base_new()); if (!result.get()) throw std::runtime_error("cannot create event_base"); return result; } -raii_event obtain_event(struct event_base* base, evutil_socket_t s, short events, event_callback_fn cb, void* arg) { +inline raii_event obtain_event(struct event_base* base, evutil_socket_t s, short events, event_callback_fn cb, void* arg) { return raii_event(event_new(base, s, events, cb, arg)); } -raii_evhttp obtain_evhttp(struct event_base* base) { +inline raii_evhttp obtain_evhttp(struct event_base* base) { return raii_evhttp(evhttp_new(base)); } -raii_evhttp_request obtain_evhttp_request(void(*cb)(struct evhttp_request *, void *), void *arg) { +inline raii_evhttp_request obtain_evhttp_request(void(*cb)(struct evhttp_request *, void *), void *arg) { return raii_evhttp_request(evhttp_request_new(cb, arg)); } -raii_evhttp_connection obtain_evhttp_connection_base(struct event_base* base, std::string host, uint16_t port) { +inline raii_evhttp_connection obtain_evhttp_connection_base(struct event_base* base, std::string host, uint16_t port) { auto result = raii_evhttp_connection(evhttp_connection_base_new(base, NULL, host.c_str(), port)); if (!result.get()) throw std::runtime_error("create connection failed"); diff --git a/src/test/arith_uint256_tests.cpp b/src/test/arith_uint256_tests.cpp index 45ae7d4636..2c98fbcfd6 100644 --- a/src/test/arith_uint256_tests.cpp +++ b/src/test/arith_uint256_tests.cpp @@ -219,7 +219,7 @@ BOOST_AUTO_TEST_CASE( unaryOperators ) // ! ~ - // 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. +// element of Aarray and Barray, and then converting the result into an 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>(TmpArray,TmpArray+32)) == (_A_##L _OP_ _B_##L)); diff --git a/src/test/data/script_tests.json b/src/test/data/script_tests.json index e35a7ce569..0390d6806d 100644 --- a/src/test/data/script_tests.json +++ b/src/test/data/script_tests.json @@ -2506,7 +2506,7 @@ ], ["CHECKSEQUENCEVERIFY tests"], -["", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "INVALID_STACK_OPERATION", "CSV automatically fails on a empty stack"], +["", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "INVALID_STACK_OPERATION", "CSV automatically fails on an empty stack"], ["-1", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "NEGATIVE_LOCKTIME", "CSV automatically fails if stack top is negative"], ["0x0100", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY,MINIMALDATA", "UNKNOWN_ERROR", "CSV fails if stack top is not minimally encoded"], ["0", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "UNSATISFIED_LOCKTIME", "CSV fails if stack top bit 1 << 31 is set and the tx version < 2"], diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json index d70fa54333..e6b382af13 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -174,7 +174,7 @@ [[["5a6b0021a6042a686b6b94abc36b387bef9109847774e8b1e51eb8cc55c53921", 1, "DUP HASH160 0x14 0xee5a6aa40facefb2655ac23c0c28c57c65c41f9b EQUALVERIFY CHECKSIG"]], "01000000012139c555ccb81ee5b1e87477840991ef7b386bc3ab946b6b682a04a621006b5a01000000fdb40148304502201723e692e5f409a7151db386291b63524c5eb2030df652b1f53022fd8207349f022100b90d9bbf2f3366ce176e5e780a00433da67d9e5c79312c6388312a296a5800390148304502201723e692e5f409a7151db386291b63524c5eb2030df652b1f53022fd8207349f022100b90d9bbf2f3366ce176e5e780a00433da67d9e5c79312c6388312a296a5800390121038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f2204148304502201723e692e5f409a7151db386291b63524c5eb2030df652b1f53022fd8207349f022100b90d9bbf2f3366ce176e5e780a00433da67d9e5c79312c6388312a296a5800390175ac4830450220646b72c35beeec51f4d5bc1cbae01863825750d7f490864af354e6ea4f625e9c022100f04b98432df3a9641719dbced53393022e7249fb59db993af1118539830aab870148304502201723e692e5f409a7151db386291b63524c5eb2030df652b1f53022fd8207349f022100b90d9bbf2f3366ce176e5e780a00433da67d9e5c79312c6388312a296a580039017521038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ffffffff010000000000000000016a00000000", "P2SH"], -["Finally CHECKMULTISIG removes all signatures prior to hashing the script containing those signatures. In conjunction with the SIGHASH_SINGLE bug this lets us test whether or not FindAndDelete() is actually present in scriptPubKey/redeemScript evaluation by including a signature of the digest 0x01 We can compute in advance for our pubkey, embed it it in the scriptPubKey, and then also using a normal SIGHASH_ALL signature. If FindAndDelete() wasn't run, the 'bugged' signature would still be in the hashed script, and the normal signature would fail."], +["Finally CHECKMULTISIG removes all signatures prior to hashing the script containing those signatures. In conjunction with the SIGHASH_SINGLE bug this lets us test whether or not FindAndDelete() is actually present in scriptPubKey/redeemScript evaluation by including a signature of the digest 0x01 We can compute in advance for our pubkey, embed it in the scriptPubKey, and then also using a normal SIGHASH_ALL signature. If FindAndDelete() wasn't run, the 'bugged' signature would still be in the hashed script, and the normal signature would fail."], ["Here's an example on mainnet within a P2SH redeemScript. Remarkably it's a standard transaction in <0.9"], [[["b5b598de91787439afd5938116654e0b16b7a0d0f82742ba37564219c5afcbf9", 0, "DUP HASH160 0x14 0xf6f365c40f0739b61de827a44751e5e99032ed8f EQUALVERIFY CHECKSIG"], diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index e4b4b85720..b45a7fcc57 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -25,6 +25,13 @@ static CSubNet ResolveSubNet(const char* subnet) return ret; } +static CNetAddr CreateInternal(const char* host) +{ + CNetAddr addr; + addr.SetInternal(host); + return addr; +} + BOOST_AUTO_TEST_CASE(netbase_networks) { BOOST_CHECK(ResolveIP("127.0.0.1").GetNetwork() == NET_UNROUTABLE); @@ -32,6 +39,7 @@ BOOST_AUTO_TEST_CASE(netbase_networks) 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_CHECK(CreateInternal("foo.com").GetNetwork() == NET_INTERNAL); } @@ -58,6 +66,8 @@ BOOST_AUTO_TEST_CASE(netbase_properties) BOOST_CHECK(ResolveIP("8.8.8.8").IsRoutable()); BOOST_CHECK(ResolveIP("2001::1").IsRoutable()); BOOST_CHECK(ResolveIP("127.0.0.1").IsValid()); + BOOST_CHECK(CreateInternal("FD6B:88C0:8724:edb1:8e4:3588:e546:35ca").IsInternal()); + BOOST_CHECK(CreateInternal("bar.com").IsInternal()); } @@ -103,6 +113,11 @@ BOOST_AUTO_TEST_CASE(netbase_lookupnumeric) BOOST_CHECK(TestParse("[::]:8333", "[::]:8333")); BOOST_CHECK(TestParse("[127.0.0.1]", "127.0.0.1:65535")); BOOST_CHECK(TestParse(":::", "[::]:0")); + + // verify that an internal address fails to resolve + BOOST_CHECK(TestParse("[fd6b:88c0:8724:1:2:3:4:5]", "[::]:0")); + // and that a one-off resolves correctly + BOOST_CHECK(TestParse("[fd6c:88c0:8724:1:2:3:4:5]", "[fd6c:88c0:8724:1:2:3:4:5]:65535")); } BOOST_AUTO_TEST_CASE(onioncat_test) @@ -281,6 +296,9 @@ BOOST_AUTO_TEST_CASE(netbase_getgroup) BOOST_CHECK(ResolveIP("2001:470:abcd:9999:9999:9999:9999:9999").GetGroup() == std::vector<unsigned char>({(unsigned char)NET_IPV6, 32, 1, 4, 112, 175})); //he.net BOOST_CHECK(ResolveIP("2001:2001:9999:9999:9999:9999:9999:9999").GetGroup() == std::vector<unsigned char>({(unsigned char)NET_IPV6, 32, 1, 32, 1})); //IPv6 + // baz.net sha256 hash: 12929400eb4607c4ac075f087167e75286b179c693eb059a01774b864e8fe505 + std::vector<unsigned char> internal_group = {NET_INTERNAL, 0x12, 0x92, 0x94, 0x00, 0xeb, 0x46, 0x07, 0xc4, 0xac, 0x07}; + BOOST_CHECK(CreateInternal("baz.net").GetGroup() == internal_group); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index eb0722cd81..4cd64bf028 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -407,7 +407,7 @@ static bool WriteBinaryFile(const fs::path &filename, const std::string &data) /****** Bitcoin specific TorController implementation ********/ /** Controller that connects to Tor control socket, authenticate, then create - * and maintain a ephemeral hidden service. + * and maintain an ephemeral hidden service. */ class TorController { diff --git a/src/txmempool.cpp b/src/txmempool.cpp index afafc695f4..f49fd391da 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -122,7 +122,7 @@ void CTxMemPool::UpdateTransactionsFromBlock(const std::vector<uint256> &vHashes // accounted for in the state of their ancestors) std::set<uint256> setAlreadyIncluded(vHashesToUpdate.begin(), vHashesToUpdate.end()); - // Iterate in reverse, so that whenever we are looking at at a transaction + // Iterate in reverse, so that whenever we are looking at a transaction // we are sure that all in-mempool descendants have already been processed. // This maximizes the benefit of the descendant cache and guarantees that // setMemPoolChildren will be updated, an assumption made in @@ -1050,9 +1050,7 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector<COutPoint>* pvNoSpends for (const CTransaction& tx : txn) { for (const CTxIn& txin : tx.vin) { if (exists(txin.prevout.hash)) continue; - if (!mapNextTx.count(txin.prevout)) { - pvNoSpendsRemaining->push_back(txin.prevout); - } + pvNoSpendsRemaining->push_back(txin.prevout); } } } diff --git a/src/util.h b/src/util.h index f40db84a10..a4d7aa4db8 100644 --- a/src/util.h +++ b/src/util.h @@ -122,6 +122,17 @@ int LogPrintStr(const std::string &str); /** Get format string from VA_ARGS for error reporting */ template<typename... Args> std::string FormatStringFromLogArgs(const char *fmt, const Args&... args) { return fmt; } +static inline void MarkUsed() {} +template<typename T, typename... Args> static inline void MarkUsed(const T& t, const Args&... args) +{ + (void)t; + MarkUsed(args...); +} + +#ifdef USE_COVERAGE +#define LogPrintf(...) do { MarkUsed(__VA_ARGS__); } while(0) +#define LogPrint(category, ...) do { MarkUsed(__VA_ARGS__); } while(0) +#else #define LogPrintf(...) do { \ std::string _log_msg_; /* Unlikely name to avoid shadowing variables */ \ try { \ @@ -138,6 +149,7 @@ template<typename... Args> std::string FormatStringFromLogArgs(const char *fmt, LogPrintf(__VA_ARGS__); \ } \ } while(0) +#endif template<typename... Args> bool error(const char* fmt, const Args&... args) diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index 74bf66fbf6..93abaec04b 100644 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -437,7 +437,7 @@ bool ParseInt32(const std::string& str, int32_t *out) errno = 0; // strtol will not set errno if valid 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 + // Note that strtol returns a *long int*, so even if strtol doesn't report an 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 && @@ -453,7 +453,7 @@ bool ParseInt64(const std::string& str, int64_t *out) errno = 0; // strtoll will not set errno if valid 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 + // Note that strtoll returns a *long long int*, so even if strtol doesn't report an 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() && @@ -470,7 +470,7 @@ bool ParseUInt32(const std::string& str, uint32_t *out) errno = 0; // strtoul will not set errno if valid 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 + // Note that strtoul returns a *unsigned long int*, so even if it doesn't report an 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 && @@ -487,7 +487,7 @@ bool ParseUInt64(const std::string& str, uint64_t *out) errno = 0; // strtoull will not set errno if valid 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 + // Note that strtoull returns a *unsigned long long int*, so even if it doesn't report an 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(); diff --git a/src/validation.cpp b/src/validation.cpp index bef17337b9..59542e8f98 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -430,8 +430,9 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool return state.DoS(0, false, REJECT_NONSTANDARD, "non-final"); // is it already in the memory pool? - if (pool.exists(hash)) - return state.Invalid(false, REJECT_ALREADY_KNOWN, "txn-already-in-mempool"); + if (pool.exists(hash)) { + return state.Invalid(false, REJECT_DUPLICATE, "txn-already-in-mempool"); + } // Check for conflicts with in-memory transactions std::set<uint256> setConflicts; @@ -469,8 +470,9 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool } } } - if (fReplacementOptOut) - return state.Invalid(false, REJECT_CONFLICT, "txn-mempool-conflict"); + if (fReplacementOptOut) { + return state.Invalid(false, REJECT_DUPLICATE, "txn-mempool-conflict"); + } setConflicts.insert(ptxConflicting->GetHash()); } @@ -497,7 +499,7 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool if (!had_coin_in_cache) { coins_to_uncache.push_back(outpoint); } - return state.Invalid(false, REJECT_ALREADY_KNOWN, "txn-already-known"); + return state.Invalid(false, REJECT_DUPLICATE, "txn-already-known"); } } @@ -1123,7 +1125,8 @@ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txund txundo.vprevout.reserve(tx.vin.size()); for (const CTxIn &txin : tx.vin) { txundo.vprevout.emplace_back(); - inputs.SpendCoin(txin.prevout, &txundo.vprevout.back()); + bool is_spent = inputs.SpendCoin(txin.prevout, &txundo.vprevout.back()); + assert(is_spent); } } // add outputs @@ -1206,7 +1209,7 @@ static bool CheckInputs(const CTransaction& tx, CValidationState &state, const C 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 + // invalid in new blocks, e.g. an 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 @@ -1368,8 +1371,8 @@ static DisconnectResult DisconnectBlock(const CBlock& block, const CBlockIndex* if (!tx.vout[o].scriptPubKey.IsUnspendable()) { COutPoint out(hash, o); Coin coin; - view.SpendCoin(out, &coin); - if (tx.vout[o] != coin.out) { + bool is_spent = view.SpendCoin(out, &coin); + if (!is_spent || tx.vout[o] != coin.out) { fClean = false; // transaction output mismatch } } diff --git a/src/validation.h b/src/validation.h index 15e19bc511..82df4cb170 100644 --- a/src/validation.h +++ b/src/validation.h @@ -469,10 +469,6 @@ int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Para static const unsigned int REJECT_INTERNAL = 0x100; /** Too high fee. Can not be triggered by P2P transactions */ static const unsigned int REJECT_HIGHFEE = 0x100; -/** Transaction is already known (either in mempool or blockchain) */ -static const unsigned int REJECT_ALREADY_KNOWN = 0x101; -/** Transaction conflicts with a transaction already known */ -static const unsigned int REJECT_CONFLICT = 0x102; /** Get block file info entry for one block file */ CBlockFileInfo* GetBlockFileInfo(size_t n); diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp index 836c15b82c..6fa685628f 100644 --- a/src/wallet/crypter.cpp +++ b/src/wallet/crypter.cpp @@ -274,7 +274,6 @@ bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) co // Check for watch-only pubkeys return CBasicKeyStore::GetPubKey(address, vchPubKeyOut); } - return false; } bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn) diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 3c25364648..09aaf4f747 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -1049,7 +1049,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) " \"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" + " \"internal\": <true> , (boolean, optional, default: false) Stating whether matching outputs should 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" diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 2e4105a569..5bbb5088e2 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1064,7 +1064,6 @@ public: bool operator()(const CNoDestination &dest) const { return false; } bool operator()(const CKeyID &keyID) { - CPubKey pubkey; if (pwallet) { CScript basescript = GetScriptForDestination(keyID); isminetype typ; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 2c5c38eb94..f07a6cb5a5 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -205,7 +205,6 @@ bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, vchCryptedSecret, mapKeyMetadata[vchPubKey.GetID()]); } - return false; } bool CWallet::LoadKeyMetadata(const CTxDestination& keyID, const CKeyMetadata &meta) @@ -2634,28 +2633,6 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT 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 && IsDust(newTxOut, ::dustRelayFee)) - { - CAmount nDust = GetDustThreshold(newTxOut, ::dustRelayFee) - newTxOut.nValue; - newTxOut.nValue += nDust; // raise change until no more dust - for (unsigned int i = 0; i < vecSend.size(); i++) // subtract from first recipient - { - if (vecSend[i].fSubtractFeeFromAmount) - { - txNew.vout[i].nValue -= nDust; - if (IsDust(txNew.vout[i], ::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 (IsDust(newTxOut, ::dustRelayFee)) @@ -2709,8 +2686,6 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT nBytes = GetVirtualTransactionSize(txNew); - CTransaction txNewConst(txNew); - // Remove scriptSigs to eliminate the fee calculation dummy signatures for (auto& vin : txNew.vin) { vin.scriptSig = CScript(); @@ -3866,11 +3841,11 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) 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)); + InitError(strprintf(_("Error loading %s: You can't disable HD on an already existing HD wallet"), walletFile)); return NULL; } if (!walletInstance->IsHDEnabled() && useHD) { - InitError(strprintf(_("Error loading %s: You can't enable HD on a already existing non-HD wallet"), walletFile)); + InitError(strprintf(_("Error loading %s: You can't enable HD on an already existing non-HD wallet"), walletFile)); return NULL; } } @@ -3890,7 +3865,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) 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 + //this might happen if a user uses an old wallet within a pruned node // or if he ran -disablewallet for a longer time, then decided to re-enable if (fPruneMode) { diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index eca6706c06..8321719b56 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -76,8 +76,6 @@ bool CWalletDB::WriteCryptedKey(const CPubKey& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret, const CKeyMetadata &keyMeta) { - const bool fEraseUnencryptedKey = true; - if (!WriteIC(std::make_pair(std::string("keymeta"), vchPubKey), keyMeta)) { return false; } @@ -85,12 +83,8 @@ bool CWalletDB::WriteCryptedKey(const CPubKey& vchPubKey, if (!WriteIC(std::make_pair(std::string("ckey"), vchPubKey), vchCryptedSecret, false)) { return false; } - if (fEraseUnencryptedKey) - { - EraseIC(std::make_pair(std::string("key"), vchPubKey)); - EraseIC(std::make_pair(std::string("wkey"), vchPubKey)); - } - + EraseIC(std::make_pair(std::string("key"), vchPubKey)); + EraseIC(std::make_pair(std::string("wkey"), vchPubKey)); return true; } |