From cd619ac244ae16dde882c2fad372ca68f4c5d5d6 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 19 Oct 2016 10:41:49 +0200 Subject: [PATCH 01/75] =?UTF-8?q?Merge=20bitcoin#8949:=20Be=20more=20agres?= =?UTF-8?q?sive=20in=20getting=20connections=20to=20peers=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/net.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/net.cpp b/src/net.cpp index 0e739b4912913..b1647ee867627 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1563,13 +1563,20 @@ static std::string GetDNSHost(const CDNSSeedData& data, ServiceFlags* requiredSe 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); - if (vNodes.size() >= 2) { + 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; } @@ -1775,6 +1782,10 @@ void CConnman::ThreadOpenConnections() 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; From ec1548a5b0ac3c849f406596fb2974f3487dab75 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 17 Feb 2017 21:47:30 +0100 Subject: [PATCH 02/75] Merge bitcoin#9785: Avoid variable length arrays --- src/httprpc.cpp | 2 +- src/qt/paymentserver.cpp | 2 -- src/qt/paymentserver.h | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 805e9e364ee63..fe6dfd6afc87e 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -112,7 +112,7 @@ static bool multiUserAuthorized(std::string strUserPass) std::string strSalt = vFields[1]; std::string strHash = vFields[2]; - unsigned int KEY_SIZE = 32; + static const unsigned int KEY_SIZE = 32; unsigned char out[KEY_SIZE]; CHMAC_SHA256(reinterpret_cast(strSalt.c_str()), strSalt.size()).Write(reinterpret_cast(strPass.c_str()), strPass.size()).Finalize(out); diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 1555dd643647b..4e02cdac99338 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -57,8 +57,6 @@ const char* BIP70_MESSAGE_PAYMENTREQUEST = "PaymentRequest"; const char* BIP71_MIMETYPE_PAYMENT = "application/absolute-payment"; const char* BIP71_MIMETYPE_PAYMENTACK = "application/absolute-paymentack"; const char* BIP71_MIMETYPE_PAYMENTREQUEST = "application/absolute-paymentrequest"; -// BIP70 max payment request size in bytes (DoS protection) -const qint64 BIP70_MAX_PAYMENTREQUEST_SIZE = 50000; struct X509StoreDeleter { void operator()(X509_STORE* b) { diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h index 52c3be9bb9c20..13aa5550b2166 100644 --- a/src/qt/paymentserver.h +++ b/src/qt/paymentserver.h @@ -53,7 +53,7 @@ class QUrl; QT_END_NAMESPACE // BIP70 max payment request size in bytes (DoS protection) -extern const qint64 BIP70_MAX_PAYMENTREQUEST_SIZE; +static const qint64 BIP70_MAX_PAYMENTREQUEST_SIZE = 50000; class PaymentServer : public QObject { From 6401f101cf31ed831a438bcf0c963ee1cd8c2e9a Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 17 Feb 2017 21:48:29 +0100 Subject: [PATCH 03/75] Merge #9786: boost: remove iostreams includes 3301587 boost: remove iostreams includes (Cory Fields) --- src/rpc/server.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index d1f90fb59b85a..5c8e551812802 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -20,8 +20,6 @@ #include #include #include -#include -#include #include #include #include From 3a1113845114764c59408487b8e4e52e1f42e803 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sun, 19 Feb 2017 13:23:50 +0100 Subject: [PATCH 04/75] Merge #9791: Avoid VLA in hash.h 5c8fd50 Avoid VLA in hash.h (Pieter Wuille) --- src/hash.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hash.h b/src/hash.h index b0222771a7ffa..a02112d840580 100644 --- a/src/hash.h +++ b/src/hash.h @@ -79,9 +79,9 @@ class CHash256 { static const size_t OUTPUT_SIZE = CSHA256::OUTPUT_SIZE; void Finalize(unsigned char hash[OUTPUT_SIZE]) { - unsigned char buf[sha.OUTPUT_SIZE]; + unsigned char buf[CSHA256::OUTPUT_SIZE]; sha.Finalize(buf); - sha.Reset().Write(buf, sha.OUTPUT_SIZE).Finalize(hash); + sha.Reset().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(hash); } CHash256& Write(const unsigned char *data, size_t len) { @@ -103,9 +103,9 @@ class CHash160 { static const size_t OUTPUT_SIZE = CRIPEMD160::OUTPUT_SIZE; void Finalize(unsigned char hash[OUTPUT_SIZE]) { - unsigned char buf[sha.OUTPUT_SIZE]; + unsigned char buf[CSHA256::OUTPUT_SIZE]; sha.Finalize(buf); - CRIPEMD160().Write(buf, sha.OUTPUT_SIZE).Finalize(hash); + CRIPEMD160().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(hash); } CHash160& Write(const unsigned char *data, size_t len) { From c8073b19301c0f5357efb7d3096e0d26d31c5cc2 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 20 Feb 2017 17:29:58 +0100 Subject: [PATCH 05/75] Merge #9760: [wallet] Remove importmulti always-true check ec1267f [wallet] Remove importmulti always-true check (Russell Yanofsky) --- src/wallet/rpcdump.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 259ad7924eaaa..3e38c84060bb3 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -1285,7 +1285,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) } } - if (fRescan && fRunScan && requests.size() && nLowestTimestamp <= chainActive.Tip()->GetBlockTimeMax()) { + if (fRescan && fRunScan && requests.size()) { CBlockIndex* pindex = nLowestTimestamp > minimumTimestamp ? chainActive.FindEarliestAtLeast(nLowestTimestamp) : chainActive.Genesis(); if (pindex) { From 10d9ae5da5ecbc29bf4152f9517b978a0e3cbe39 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 21 Feb 2017 09:50:37 +0100 Subject: [PATCH 06/75] Merge #9813: Read/write mempool.dat as a binary. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 171fc91 Read/write mempool.dat as a binary. (Pavel Janík) --- src/validation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/validation.cpp b/src/validation.cpp index af8b532c98bcb..a21029c12b7ed 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -4505,7 +4505,7 @@ static const uint64_t MEMPOOL_DUMP_VERSION = 1; bool LoadMempool(void) { int64_t nExpiryTimeout = GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60; - FILE* filestr = fopen((GetDataDir() / "mempool.dat").string().c_str(), "r"); + 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"); @@ -4586,7 +4586,7 @@ void DumpMempool(void) int64_t mid = GetTimeMicros(); try { - FILE* filestr = fopen((GetDataDir() / "mempool.dat.new").string().c_str(), "w"); + FILE* filestr = fopen((GetDataDir() / "mempool.dat.new").string().c_str(), "wb"); if (!filestr) { return; } From 0865c59b79d7641ef4af06959bd0febcd13065b6 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 21 Feb 2017 14:32:44 +0100 Subject: [PATCH 07/75] Merge #9798: Fix Issue #9775 (Check returned value of fopen) 40f11f8 Fix for issue #9775. Added check for open() returning a NULL pointer. (kirit93) --- src/util.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/util.cpp b/src/util.cpp index 2395503015582..72cf6cb6e0512 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -233,12 +233,13 @@ void OpenDebugLog() assert(vMsgsBeforeOpenLog); boost::filesystem::path pathDebug = GetDataDir() / "debug.log"; fileout = fopen(pathDebug.string().c_str(), "a"); - if (fileout) setbuf(fileout, NULL); // unbuffered - - // dump buffered messages from before we opened the log - while (!vMsgsBeforeOpenLog->empty()) { - FileWriteStr(vMsgsBeforeOpenLog->front(), fileout); - vMsgsBeforeOpenLog->pop_front(); + if (fileout) { + setbuf(fileout, NULL); // unbuffered + // dump buffered messages from before we opened the log + while (!vMsgsBeforeOpenLog->empty()) { + FileWriteStr(vMsgsBeforeOpenLog->front(), fileout); + vMsgsBeforeOpenLog->pop_front(); + } } delete vMsgsBeforeOpenLog; From 9a0d4268905e39653d88d8a0980bd77e1185d8fe Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 21 Feb 2017 15:13:13 +0100 Subject: [PATCH 08/75] Merge #9817: Fix segfault crash when shutdown the GUI in disablewallet mode 312c4f1 Fix segfault crash when shutdown the GUI in disablewallet mode (Jonas Schnelli) --- src/qt/bitcoingui.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index a966cbdc986f0..c1acc1210edff 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -664,7 +664,10 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel) // Propagate cleared model to child objects rpcConsole->setClientModel(nullptr); #ifdef ENABLE_WALLET - walletFrame->setClientModel(nullptr); + if (walletFrame) + { + walletFrame->setClientModel(nullptr); + } #endif // ENABLE_WALLET unitDisplayControl->setOptionsModel(nullptr); From 597df87c6f5b2ecce276f8f55285472ee35c93b2 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 22 Feb 2017 12:42:55 +0100 Subject: [PATCH 09/75] Merge #9773: Return errors from importmulti if complete rescans are not successful e2e2f4c Return errors from importmulti if complete rescans are not successful (Russell Yanofsky) --- src/validation.cpp | 7 +++- src/validation.h | 10 +++++- src/wallet/rpcdump.cpp | 25 +++++++++++-- src/wallet/test/wallet_tests.cpp | 60 ++++++++++++++++++++++++++++++++ src/wallet/wallet.cpp | 23 +++++++----- src/wallet/wallet.h | 2 +- 6 files changed, 114 insertions(+), 13 deletions(-) diff --git a/src/validation.cpp b/src/validation.cpp index a21029c12b7ed..f5e5219a395ba 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -3705,7 +3705,7 @@ void PruneOneBlockFile(const int fileNumber) } -void UnlinkPrunedFiles(std::set& setFilesToPrune) +void UnlinkPrunedFiles(const std::set& setFilesToPrune) { for (std::set::iterator it = setFilesToPrune.begin(); it != setFilesToPrune.end(); ++it) { CDiskBlockPos pos(*it, 0); @@ -4488,6 +4488,11 @@ 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) { AssertLockHeld(cs_main); diff --git a/src/validation.h b/src/validation.h index cac23dc8fd553..b6d9a26937abd 100644 --- a/src/validation.h +++ b/src/validation.h @@ -313,10 +313,15 @@ double GuessVerificationProgress(const ChainTxData& data, CBlockIndex* pindex); */ void FindFilesToPrune(std::set& setFilesToPrune, uint64_t nPruneAfterHeight); +/** + * Mark one block file as pruned. + */ +void PruneOneBlockFile(const int fileNumber); + /** * Actually unlink the specified files */ -void UnlinkPrunedFiles(std::set& setFilesToPrune); +void UnlinkPrunedFiles(const std::set& setFilesToPrune); /** Create a new block index entry for a given block hash */ CBlockIndex * InsertBlockIndex(uint256 hash); @@ -559,6 +564,9 @@ 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); + /** Dump the mempool to disk. */ void DumpMempool(); diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 3e38c84060bb3..3791a5c3ccac9 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -1287,11 +1287,32 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) if (fRescan && fRunScan && requests.size()) { CBlockIndex* pindex = nLowestTimestamp > minimumTimestamp ? chainActive.FindEarliestAtLeast(nLowestTimestamp) : chainActive.Genesis(); - + CBlockIndex* scannedRange = nullptr; if (pindex) { - pwalletMain->ScanForWalletTransactions(pindex, true); + scannedRange = pwalletMain->ScanForWalletTransactions(pindex, true); pwalletMain->ReacceptWalletTransactions(); } + + if (!scannedRange || scannedRange->nHeight > pindex->nHeight) { + std::vector 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)); + } + } + } } return response; diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 9c06f94a17a5a..b95670b97bafc 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -9,10 +9,16 @@ #include #include +#include "rpc/server.h" +#include "test/test_bitcoin.h" +#include "validation.h" #include "wallet/test/wallet_test_fixture.h" #include #include +#include + +extern UniValue importmulti(const JSONRPCRequest& request); // how many times to run all the tests to have a chance to catch errors that only show up with particular random shuffles #define RUN_TESTS 100 @@ -355,4 +361,58 @@ BOOST_AUTO_TEST_CASE(ApproximateBestSubset) empty_wallet(); } +BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup) +{ + LOCK(cs_main); + + // Cap last block file size, and mine new block in a new block file. + CBlockIndex* oldTip = chainActive.Tip(); + GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE; + CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())); + CBlockIndex* newTip = chainActive.Tip(); + + // Verify ScanForWalletTransactions picks up transactions in both the old + // and new block files. + { + CWallet wallet; + LOCK(wallet.cs_wallet); + wallet.AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()); + BOOST_CHECK_EQUAL(oldTip, wallet.ScanForWalletTransactions(oldTip)); + BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 100 * COIN); + } + + // Prune the older block file. + PruneOneBlockFile(oldTip->GetBlockPos().nFile); + UnlinkPrunedFiles({oldTip->GetBlockPos().nFile}); + + // Verify ScanForWalletTransactions only picks transactions in the new block + // file. + { + CWallet wallet; + LOCK(wallet.cs_wallet); + wallet.AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()); + BOOST_CHECK_EQUAL(newTip, wallet.ScanForWalletTransactions(oldTip)); + BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 50 * COIN); + } + + { + CWallet wallet; + ::pwalletMain = &wallet; + UniValue key; + key.setObject(); + key.pushKV("scriptPubKey", HexStr(GetScriptForRawPubKey(coinbaseKey.GetPubKey()))); + key.pushKV("timestamp", 0); + key.pushKV("internal", UniValue(true)); + UniValue keys; + keys.setArray(); + keys.push_back(key); + JSONRPCRequest request; + request.params.setArray(); + request.params.push_back(keys); + + UniValue response = importmulti(request); + BOOST_CHECK_EQUAL(response.write(), strprintf("[{\"success\":false,\"error\":{\"code\":-1,\"message\":\"Failed to rescan before time %d, transactions may be missing.\"}}]", newTip->GetBlockTimeMax())); + } +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index e6b1a48fe2f95..3c41bf9374b5e 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1837,10 +1837,14 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, CAmount& nReceived, * 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. + * */ -int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) +CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) { - int ret = 0; + CBlockIndex* ret = nullptr; int64_t nNow = GetTime(); const CChainParams& chainParams = Params(); @@ -1862,12 +1866,15 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((GuessVerificationProgress(chainParams.TxData(), pindex) - dProgressStart) / (dProgressTip - dProgressStart) * 100)))); CBlock block; - ReadBlockFromDisk(block, pindex, Params().GetConsensus()); - int posInBlock; - for (posInBlock = 0; posInBlock < (int)block.vtx.size(); posInBlock++) - { - if (AddToWalletIfInvolvingMe(*block.vtx[posInBlock], pindex, posInBlock, fUpdate)) - ret++; + 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) { diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index df808dfa79548..cd781c76980c1 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -885,7 +885,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface bool LoadToWallet(const CWalletTx& wtxIn); void SyncTransaction(const CTransaction& tx, const CBlockIndex *pindex, int posInBlock); bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlockIndex* pIndex, int posInBlock, bool fUpdate); - int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false); + CBlockIndex* ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false); void ReacceptWalletTransactions(); void ResendWalletTransactions(int64_t nBestBlockTime, CConnman* connman); std::vector ResendWalletTransactionsBefore(int64_t nTime, CConnman* connman); From 02cfac2dc6d2445998ab6c4a8bd26a93557147dd Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 22 Feb 2017 13:03:37 +0100 Subject: [PATCH 10/75] Merge #9711: [Trivial] Remove incorrect help message from gettxoutproof() 9949ebf [Trivial] Remove incorrect help message from gettxoutproof() (John Newbery) --- src/rpc/rawtransaction.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 4a17ce71b83b2..1760cd5a65a22 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -261,7 +261,6 @@ UniValue gettxoutproof(const JSONRPCRequest& request) "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" - "\nReturn the raw transaction data.\n" "\nArguments:\n" "1. \"txids\" (string) A json array of txids to filter\n" " [\n" From c06d27d398b303f42e82913af47b35edd8518412 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 23 Feb 2017 10:38:09 +0100 Subject: [PATCH 11/75] Merge #9820: Fix pruning test broken by 2 hour manual prune window 874c736 Fix pruning test broken by 2 hour manual prune window (Russell Yanofsky) --- qa/rpc-tests/pruning.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/qa/rpc-tests/pruning.py b/qa/rpc-tests/pruning.py index 9d155478e251a..1e6d4191869fa 100755 --- a/qa/rpc-tests/pruning.py +++ b/qa/rpc-tests/pruning.py @@ -18,6 +18,11 @@ MIN_BLOCKS_TO_KEEP = 288 +# Rescans start at the earliest block up to 2 hours before a key timestamp, so +# the manual prune RPC avoids pruning blocks in the same window to be +# compatible with pruning based on key creation time. +RESCAN_WINDOW = 2 * 60 * 60 + def calc_usage(blockdir): return sum(os.path.getsize(blockdir+f) for f in os.listdir(blockdir) if os.path.isfile(blockdir+f)) / (1024. * 1024.) @@ -239,7 +244,7 @@ def manual_test(self, node_number, use_timestamp): def height(index): if use_timestamp: - return node.getblockheader(node.getblockhash(index))["time"] + return node.getblockheader(node.getblockhash(index))["time"] + RESCAN_WINDOW else: return index From 8bbb66f178567f8155f5da6b48adb9d1d1756923 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 23 Feb 2017 10:40:44 +0100 Subject: [PATCH 12/75] Merge #9824: qa: Check return code when stopping nodes fa4cd2e qa: Check return code when stopping nodes (MarcoFalke) --- qa/rpc-tests/fundrawtransaction-hd.py | 5 +++-- qa/rpc-tests/fundrawtransaction.py | 4 +++- qa/rpc-tests/rpcbind_test.py | 19 +++++++------------ qa/rpc-tests/test_framework/util.py | 19 +++++-------------- 4 files changed, 18 insertions(+), 29 deletions(-) diff --git a/qa/rpc-tests/fundrawtransaction-hd.py b/qa/rpc-tests/fundrawtransaction-hd.py index d4508933b12ab..7ec8796caa99d 100755 --- a/qa/rpc-tests/fundrawtransaction-hd.py +++ b/qa/rpc-tests/fundrawtransaction-hd.py @@ -441,8 +441,9 @@ def run_test(self): # locked wallet test self.nodes[1].encryptwallet("test") self.nodes.pop(1) - stop_nodes(self.nodes) - wait_bitcoinds() + stop_node(self.nodes[0], 0) + stop_node(self.nodes[1], 2) + stop_node(self.nodes[2], 3) self.nodes = start_nodes(4, self.options.tmpdir, [['-usehd=1'], ['-usehd=1'], ['-usehd=1'], ['-usehd=1']], redirect_stderr=True) # This test is not meant to test fee estimation and we'd like diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index 4fbe477af439a..440d46e5da3eb 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -468,7 +468,9 @@ def run_test(self): # locked wallet test self.nodes[1].encryptwallet("test") self.nodes.pop(1) - stop_nodes(self.nodes) + stop_node(self.nodes[0], 0) + stop_node(self.nodes[1], 2) + stop_node(self.nodes[2], 3) self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, [['-usehd=0'], ['-usehd=0'], ['-usehd=0'], ['-usehd=0']]) # This test is not meant to test fee estimation and we'd like diff --git a/qa/rpc-tests/rpcbind_test.py b/qa/rpc-tests/rpcbind_test.py index 29cfa1aff3d6d..54d4c05f0a9ec 100755 --- a/qa/rpc-tests/rpcbind_test.py +++ b/qa/rpc-tests/rpcbind_test.py @@ -35,11 +35,9 @@ def run_bind_test(self, allow_ips, connect_to, addresses, expected): base_args += ['-rpcallowip=' + x for x in allow_ips] binds = ['-rpcbind='+addr for addr in addresses] self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, [base_args + binds], connect_to) - try: - pid = bitcoind_processes[0].pid - assert_equal(set(get_bind_addrs(pid)), set(expected)) - finally: - stop_nodes(self.nodes) + pid = bitcoind_processes[0].pid + assert_equal(set(get_bind_addrs(pid)), set(expected)) + stop_nodes(self.nodes) def run_allowip_test(self, allow_ips, rpchost, rpcport): @@ -49,13 +47,10 @@ def run_allowip_test(self, allow_ips, rpchost, rpcport): ''' base_args = ['-disablewallet', '-nolisten'] + ['-rpcallowip='+x for x in allow_ips] self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, [base_args]) - try: - # connect to node through non-loopback interface - node = get_rpc_proxy(rpc_url(0, "%s:%d" % (rpchost, rpcport)), 0) - node.getnetworkinfo() - finally: - node = None # make sure connection will be garbage collected and closed - stop_nodes(self.nodes) + # connect to node through non-loopback interface + node = get_rpc_proxy(rpc_url(0, "%s:%d" % (rpchost, rpcport)), 0) + node.getnetworkinfo() + stop_nodes(self.nodes) def run_test(self): # due to OS-specific network stats queries, this test works only on Linux diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 42780cf47d0ae..2ecbcda2247c6 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -397,28 +397,19 @@ def stop_node(node, i): node.stop() except http.client.CannotSendRequest as e: print("WARN: Unable to stop node: " + repr(e)) - bitcoind_processes[i].wait(timeout=BITCOIND_PROC_WAIT_TIMEOUT) + return_code = bitcoind_processes[i].wait(timeout=BITCOIND_PROC_WAIT_TIMEOUT) + assert_equal(return_code, 0) del bitcoind_processes[i] def stop_nodes(nodes): - for node in nodes: - try: - node.stop() - except http.client.CannotSendRequest as e: - print("WARN: Unable to stop node: " + repr(e)) - del nodes[:] # Emptying array closes connections as a side effect - wait_bitcoinds() + for i, node in enumerate(nodes): + stop_node(node, i) + assert not bitcoind_processes.values() # All connections must be gone now def set_node_times(nodes, t): for node in nodes: node.setmocktime(t) -def wait_bitcoinds(): - # Wait for all bitcoinds to cleanly exit - for bitcoind in bitcoind_processes.values(): - bitcoind.wait(timeout=BITCOIND_PROC_WAIT_TIMEOUT) - bitcoind_processes.clear() - def connect_nodes(from_connection, node_num): ip_port = "127.0.0.1:"+str(p2p_port(node_num)) from_connection.addnode(ip_port, "onetry") From 7c3e0373c3a221e720b7d8de38dc32cac2560d30 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 23 Feb 2017 10:48:11 +0100 Subject: [PATCH 13/75] Merge #9789: build: add --enable-werror and warn on vla's 205830a build: add --enable-werror option (Cory Fields) b602fe0 build: warn about variable length arrays (Cory Fields) --- configure.ac | 18 ++++++++++++++++++ src/Makefile.am | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index ebf0b983d53d4..85bd7a6a5a023 100644 --- a/configure.ac +++ b/configure.ac @@ -190,6 +190,13 @@ AC_ARG_ENABLE([debug], [enable_debug=$enableval], [enable_debug=no]) +# Turn warnings into errors +AC_ARG_ENABLE([werror], + [AS_HELP_STRING([--enable-werror], + [Treat certain compiler warnings as errors (default is no)])], + [enable_werror=$enableval], + [enable_werror=no]) + AC_LANG_PUSH([C++]) AX_CHECK_COMPILE_FLAG([-Werror],[CXXFLAG_WERROR="-Werror"],[CXXFLAG_WERROR=""]) @@ -204,10 +211,19 @@ if test "x$enable_debug" = xyes; then fi fi +ERROR_CXXFLAGS= +if test "x$enable_werror" = "xyes"; then + if test "x$CXXFLAG_WERROR" = "x"; then + AC_MSG_ERROR("enable-werror set but -Werror is not usable") + fi + AX_CHECK_COMPILE_FLAG([-Werror=vla],[ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=vla"],,[[$CXXFLAG_WERROR]]) +fi + if test "x$CXXFLAGS_overridden" = "xno"; then AX_CHECK_COMPILE_FLAG([-Wall],[CXXFLAGS="$CXXFLAGS -Wall"],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-Wextra],[CXXFLAGS="$CXXFLAGS -Wextra"],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-Wformat],[CXXFLAGS="$CXXFLAGS -Wformat"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wvla],[CXXFLAGS="$CXXFLAGS -Wvla"],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-Wformat-security],[CXXFLAGS="$CXXFLAGS -Wformat-security"],,[[$CXXFLAG_WERROR]]) ## Some compilers (gcc) ignore unknown -Wno-* options, but warn about all @@ -1061,6 +1077,7 @@ AC_SUBST(BITCOIN_CLI_NAME) AC_SUBST(BITCOIN_TX_NAME) AC_SUBST(RELDFLAGS) +AC_SUBST(ERROR_CXXFLAGS) AC_SUBST(HARDENED_CXXFLAGS) AC_SUBST(HARDENED_CPPFLAGS) AC_SUBST(HARDENED_LDFLAGS) @@ -1150,6 +1167,7 @@ echo " with test = $use_tests" echo " with bench = $use_bench" echo " with upnp = $use_upnp" echo " debug enabled = $enable_debug" +echo " werror = $enable_werror" echo echo " target os = $TARGET_OS" echo " build os = $BUILD_OS" diff --git a/src/Makefile.am b/src/Makefile.am index 24a36040e9380..6026b3a256947 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,7 +5,7 @@ DIST_SUBDIRS = secp256k1 univalue AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) -AM_CXXFLAGS = $(HARDENED_CXXFLAGS) +AM_CXXFLAGS = $(HARDENED_CXXFLAGS) $(ERROR_CXXFLAGS) AM_CPPFLAGS = $(HARDENED_CPPFLAGS) EXTRA_LIBRARIES = From 2f2dcddfa2b10462af2c0ccb1ea4d0322a18daaa Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 24 Feb 2017 10:21:59 +0100 Subject: [PATCH 14/75] =?UTF-8?q?Merge=20bitcoin#9840:=20Update=20sendfrom?= =?UTF-8?q?=20RPC=20help=20to=20correct=20coin=20selectio=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/wallet/rpcwallet.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 55ec2cce63bc3..655927bc79134 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -883,7 +883,14 @@ UniValue sendfrom(const JSONRPCRequest& request) + HelpRequiringPassphrase() + "\n" "\nArguments:\n" "1. \"fromaccount\" (string, required) The name of the account to send funds from. May be the default account using \"\".\n" +<<<<<<< HEAD "2. \"toaddress\" (string, required) The absolute address to send funds to.\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 dash address to send funds to.\n" +>>>>>>> 7c3b8ec4b... Merge #9840: Update sendfrom RPC help to correct coin selection misconception "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. addlockconf (bool, optional, default=false) Whether to add " + std::to_string(nInstantSendDepth) + " confirmations to transactions locked via InstantSend.\n" From 8e58929352c6fc8f84cc7c12f873d60fb38c2d4f Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 27 Feb 2017 13:25:08 +0100 Subject: [PATCH 15/75] Merge #9875: tests: Fix dangling pwalletMain pointer in wallet tests 75a1093 tests: Fix dangling pwalletMain pointer in wallet tests (Wladimir J. van der Laan) Tree-SHA512: 7fb6e8385fe7d542f9ecb113a08d675ca9e84907a1939b3a6ad41318fda55bc999b9bc8ffc3f56cd8610ca49d0db982d3c793df7bbcb7eb9638f4483030db6a8 --- src/wallet/test/wallet_tests.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index b95670b97bafc..f6ad9d04c960d 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -397,6 +397,7 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup) { CWallet wallet; + CWallet *backup = ::pwalletMain; ::pwalletMain = &wallet; UniValue key; key.setObject(); @@ -412,6 +413,7 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup) UniValue response = importmulti(request); BOOST_CHECK_EQUAL(response.write(), strprintf("[{\"success\":false,\"error\":{\"code\":-1,\"message\":\"Failed to rescan before time %d, transactions may be missing.\"}}]", newTip->GetBlockTimeMax())); + ::pwalletMain = backup; } } From 32871e925e6ca229b272518bf5ea7064dd8a29e9 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 28 Feb 2017 11:37:00 +0100 Subject: [PATCH 16/75] Merge #9856: Terminate immediately when allocation fails d4ee7ba prevector: assert successful allocation (Cory Fields) c5f008a don't throw std::bad_alloc when out of memory. Instead, terminate immediately (Cory Fields) Tree-SHA512: 699ce8df5b1775a99c71d3cfc952b45da1c0091e1a4b6adfac52d5be6144c3d98f88ac3af90e5c73fff2f74666a499feb4a34434683ce5979814e869c0aeddc3 --- src/init.cpp | 16 ++++++++++++++++ src/prevector.h | 6 ++++++ 2 files changed, 22 insertions(+) diff --git a/src/init.cpp b/src/init.cpp index 013d9c62f8a3c..79cc5b58c74ba 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -939,6 +939,19 @@ ServiceFlags nLocalServices = NODE_NETWORK; } +[[noreturn]] static void new_handler_terminate() +{ + // Rather than throwing std::bad-alloc if allocation fails, terminate + // immediately to (try to) avoid chain corruption. + // Since LogPrintf may itself allocate memory, set the handler directly + // to terminate first. + std::set_new_handler(std::terminate); + LogPrintf("Error: Out of memory. Terminating.\n"); + + // The log was successful, terminate now. + std::terminate(); +}; + bool AppInitBasicSetup() { // ********************************************************* Step 1: setup @@ -991,6 +1004,9 @@ bool AppInitBasicSetup() // Ignore SIGPIPE, otherwise it will bring the daemon down if the client closes unexpectedly signal(SIGPIPE, SIG_IGN); #endif + + std::set_new_handler(new_handler_terminate); + return true; } diff --git a/src/prevector.h b/src/prevector.h index 3585031b187a0..34eb2572c63b5 100644 --- a/src/prevector.h +++ b/src/prevector.h @@ -5,6 +5,7 @@ #ifndef _BITCOIN_PREVECTOR_H_ #define _BITCOIN_PREVECTOR_H_ +#include #include #include #include @@ -170,10 +171,15 @@ class prevector { } } else { if (!is_direct()) { + /* FIXME: Because malloc/realloc here won't call new_handler if allocation fails, assert + success. These should instead use an allocator or new/delete so that handlers + are called as necessary, but performance would be slightly degraded by doing so. */ _union.indirect = static_cast(realloc(_union.indirect, ((size_t)sizeof(T)) * new_capacity)); + assert(_union.indirect); _union.capacity = new_capacity; } else { char* new_indirect = static_cast(malloc(((size_t)sizeof(T)) * new_capacity)); + assert(new_indirect); T* src = direct_ptr(0); T* dst = reinterpret_cast(new_indirect); memcpy(dst, src, size() * sizeof(T)); From 4a84d1de983be5a9e628ba8c1e90b8e8a3f6e4fa Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 28 Feb 2017 11:43:37 +0100 Subject: [PATCH 17/75] Merge #9879: [doc] Update doc/bips.md for BIP90 implementation fe71661 [doc] Update doc/bips.md for BIP90 implementation (Suhas Daftuar) Tree-SHA512: cfa72662e5e8ecedb7869b64c2064cc29d8736bcd9baacd59ea420dc2f93265c8d950e469863e77e8fa9348fbf1b39a1e2397253a2fd94b63adc909cc8c14873 --- doc/bips.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/bips.md b/doc/bips.md index eae067ccfcdbc..11dea9f75b73e 100644 --- a/doc/bips.md +++ b/doc/bips.md @@ -19,6 +19,7 @@ BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.13.0**): * [`BIP 66`](https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki): The strict DER rules and associated version 3 blocks have been implemented since **v0.10.0** ([PR #5713](https://github.com/bitcoin/bitcoin/pull/5713)). * [`BIP 68`](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki): Sequence locks have been implemented as of **v0.12.1** ([PR #7184](https://github.com/bitcoin/bitcoin/pull/7184)), and have been activated since *block 419328*. * [`BIP 70`](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki) [`71`](https://github.com/bitcoin/bips/blob/master/bip-0071.mediawiki) [`72`](https://github.com/bitcoin/bips/blob/master/bip-0072.mediawiki): Payment Protocol support has been available in Bitcoin Core GUI since **v0.9.0** ([PR #5216](https://github.com/bitcoin/bitcoin/pull/5216)). +* [`BIP 90`](https://github.com/bitcoin/bips/blob/master/bip-0090.mediawiki): Trigger mechanism for activation of BIPs 34, 65, and 66 has been simplified to block height checks since **v0.14.0** ([PR #8391](https://github.com/bitcoin/bitcoin/pull/8391)). * [`BIP 111`](https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki): `NODE_BLOOM` service bit added, and enforced for all peer versions as of **v0.13.0** ([PR #6579](https://github.com/bitcoin/bitcoin/pull/6579) and [PR #6641](https://github.com/bitcoin/bitcoin/pull/6641)). * [`BIP 112`](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki): The CHECKSEQUENCEVERIFY opcode has been implemented since **v0.12.1** ([PR #7524](https://github.com/bitcoin/bitcoin/pull/7524)) and has been activated since *block 419328*. * [`BIP 113`](https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki): Median time past lock-time calculations have been implemented since **v0.12.1** ([PR #6566](https://github.com/bitcoin/bitcoin/pull/6566)) and have been activated since *block 419328*. From 8c58b619f6b901aa796c8bb7f7734fb684e05fa1 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 28 Feb 2017 11:57:38 +0100 Subject: [PATCH 18/75] Merge bitcoin#9865: Change bitcoin address in RPC help message --- src/wallet/rpcwallet.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 655927bc79134..6d57a9f698093 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -883,14 +883,10 @@ UniValue sendfrom(const JSONRPCRequest& request) + HelpRequiringPassphrase() + "\n" "\nArguments:\n" "1. \"fromaccount\" (string, required) The name of the account to send funds from. May be the default account using \"\".\n" -<<<<<<< HEAD - "2. \"toaddress\" (string, required) The absolute address to send funds to.\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 dash address to send funds to.\n" ->>>>>>> 7c3b8ec4b... Merge #9840: Update sendfrom RPC help to correct coin selection misconception + "2. \"toaddress\" (string, required) The absolute 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. addlockconf (bool, optional, default=false) Whether to add " + std::to_string(nInstantSendDepth) + " confirmations to transactions locked via InstantSend.\n" From 5969a10ac15e4013d7a9b889b1fba219e9224552 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 28 Feb 2017 13:52:22 +0100 Subject: [PATCH 19/75] Merge #9829: Fix importmulti returning rescan errors for wrong keys 306bd72 Fix importmulti returning rescan errors for wrong keys (Russell Yanofsky) Tree-SHA512: ae9998236cbd3ff749d6b5c716bd76c9cec386b0708583e4912e4e05bf4584545258e1d0543aa5445024d2b5decf859a64f40c6503029773366a0f9a9ddf9b88 --- src/wallet/rpcdump.cpp | 1 + src/wallet/test/wallet_tests.cpp | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 3791a5c3ccac9..d552c6099e54b 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -1311,6 +1311,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) 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; } } } diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index f6ad9d04c960d..7db06817a3709 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -395,24 +395,35 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup) BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 50 * COIN); } + // Verify importmulti RPC returns failure for a key whose creation time is + // before the missing block, and success for a key whose creation time is + // after. { CWallet wallet; CWallet *backup = ::pwalletMain; ::pwalletMain = &wallet; + UniValue keys; + keys.setArray(); UniValue key; key.setObject(); key.pushKV("scriptPubKey", HexStr(GetScriptForRawPubKey(coinbaseKey.GetPubKey()))); key.pushKV("timestamp", 0); key.pushKV("internal", UniValue(true)); - UniValue keys; - keys.setArray(); + keys.push_back(key); + key.clear(); + key.setObject(); + CKey futureKey; + futureKey.MakeNewKey(true); + key.pushKV("scriptPubKey", HexStr(GetScriptForRawPubKey(futureKey.GetPubKey()))); + key.pushKV("timestamp", newTip->GetBlockTimeMax() + 7200); + key.pushKV("internal", UniValue(true)); keys.push_back(key); JSONRPCRequest request; request.params.setArray(); request.params.push_back(keys); UniValue response = importmulti(request); - BOOST_CHECK_EQUAL(response.write(), strprintf("[{\"success\":false,\"error\":{\"code\":-1,\"message\":\"Failed to rescan before time %d, transactions may be missing.\"}}]", newTip->GetBlockTimeMax())); + BOOST_CHECK_EQUAL(response.write(), strprintf("[{\"success\":false,\"error\":{\"code\":-1,\"message\":\"Failed to rescan before time %d, transactions may be missing.\"}},{\"success\":true}]", newTip->GetBlockTimeMax())); ::pwalletMain = backup; } } From ed8bc3f31ee939f5614612997ee748744b81a85c Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 1 Mar 2017 10:41:47 +0100 Subject: [PATCH 20/75] Merge #9891: depends: make osx output deterministic 9e4d842 depends: make osx output deterministic (Cory Fields) Tree-SHA512: 997a671832a28e600bc3c9cd1340c6c1fa08f050d7cf676a5d51b38f08161ac418621520459a9a53dd87102c13fb69cb2e58ec3cc00f738e204eb787d6f0cad6 --- depends/packages/native_cctools.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/depends/packages/native_cctools.mk b/depends/packages/native_cctools.mk index 797480c25eb2f..44d238cc4c2a6 100644 --- a/depends/packages/native_cctools.mk +++ b/depends/packages/native_cctools.mk @@ -38,7 +38,8 @@ $(package)_cxx=$($(package)_extract_dir)/toolchain/bin/clang++ endef define $(package)_preprocess_cmds - cd $($(package)_build_subdir); ./autogen.sh + cd $($(package)_build_subdir); ./autogen.sh && \ + sed -i.old "/define HAVE_PTHREADS/d" ld64/src/ld/InputFiles.h endef define $(package)_config_cmds From 6be8b03952bc35864b00e48a29bd9ddea89be693 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 1 Mar 2017 12:33:32 +0100 Subject: [PATCH 21/75] Merge bitcoin#9892: Bugfix: Only install manpages for built programs --- doc/man/Makefile.am | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am index 4510b82606549..494c9d5097d95 100644 --- a/doc/man/Makefile.am +++ b/doc/man/Makefile.am @@ -1 +1,13 @@ -dist_man1_MANS=absoluted.1 absolute-qt.1 absolute-cli.1 absolute-tx.1 +dist_man1_MANS= + +if BUILD_BITCOIND + dist_man1_MANS+=absoluted.1 +endif + +if ENABLE_QT + dist_man1_MANS+=absolute-qt.1 +endif + +if BUILD_BITCOIN_UTILS + dist_man1_MANS+=absolute-cli.1 absolute-tx.1 +endif From 5b1463f44395264645cb3d1022bb2968ec97a548 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sun, 12 Mar 2017 16:36:31 +0100 Subject: [PATCH 22/75] Merge #9973: depends: fix zlib build on osx c624753 depends: fix zlib build on osx (Cory Fields) Tree-SHA512: fd9343edc24762fc4b7eb9798f0fb6f76d5f5aeef16a0bc3bab5400cb8f9b3ae8a2d34b480f03c853bb31ff4e39c267a2b81cd86df0532f11976072354aa9378 --- depends/packages/zlib.mk | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/depends/packages/zlib.mk b/depends/packages/zlib.mk index 7ff5d00bbdc64..589490800f8bd 100644 --- a/depends/packages/zlib.mk +++ b/depends/packages/zlib.mk @@ -7,8 +7,10 @@ $(package)_sha256_hash=c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca11 define $(package)_set_vars $(package)_build_opts= CC="$($(package)_cc)" $(package)_build_opts+=CFLAGS="$($(package)_cflags) $($(package)_cppflags) -fPIC" -$(package)_build_opts+=AR="$($(package)_ar)" $(package)_build_opts+=RANLIB="$($(package)_ranlib)" +$(package)_build_opts+=AR="$($(package)_ar)" +$(package)_build_opts_darwin+=AR="$($(package)_libtool)" +$(package)_build_opts_darwin+=ARFLAGS="-o" endef define $(package)_config_cmds From 86c678fa970e2ed30fe2f6ebd7727949b46b994f Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 13 Mar 2017 06:57:07 +0100 Subject: [PATCH 23/75] Merge #9953: Fix shutdown hang with >= 8 -addnodes set 819b513 Add missing braces in semaphore posts in net (Matt Corallo) e007b24 Fix shutdown hang with >= 8 -addnodes set (Matt Corallo) Tree-SHA512: f2d7562bd5d333cd0e80562eb3b1fe329fc10ee713996e053d2ed669db6d9eb39550e0a6c6ab768cd070bfe92a5ea85e0f752470206706de196bd4a689b9bc07 --- src/net.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index b1647ee867627..b89203f2edf7b 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2375,9 +2375,17 @@ void CConnman::Interrupt() interruptNet(); InterruptSocks5(true); - if (semOutbound) - for (int i=0; i<(nMaxOutbound + nMaxFeeler); i++) + if (semOutbound) { + for (int i=0; i<(nMaxOutbound + nMaxFeeler); i++) { semOutbound->post(); + } + } + + if (semAddnode) { + for (int i=0; ipost(); + } + } } void CConnman::Stop() @@ -2395,10 +2403,6 @@ void CConnman::Stop() if (threadSocketHandler.joinable()) threadSocketHandler.join(); - if (semAddnode) - for (int i=0; ipost(); - if (semMasternodeOutbound) for (int i=0; ipost(); From 557d289d0f3f43083f4a4bc119e6a42d57c7866e Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 14 Mar 2017 12:22:54 +0100 Subject: [PATCH 24/75] Merge #9497: CCheckQueue Unit Tests 96c7f2c Add CheckQueue Tests (Jeremy Rubin) e207342 Fix CCheckQueue IsIdle (potential) race condition and remove dangerous constructors. (Jeremy Rubin) Tree-SHA512: 5989743ad0f8b08998335e7ca9256e168fa319053f91b9dece9dbb134885bef7753b567b591acc7135785f23d19799ed7e6375917f59fe0178d389e961633d62 --- src/Makefile.test.include | 1 + src/checkqueue.h | 22 +- src/test/checkqueue_tests.cpp | 442 ++++++++++++++++++++++++++++++++++ 3 files changed, 455 insertions(+), 10 deletions(-) create mode 100644 src/test/checkqueue_tests.cpp diff --git a/src/Makefile.test.include b/src/Makefile.test.include index f9db5d678785f..551921815359f 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -77,6 +77,7 @@ BITCOIN_TESTS =\ test/bip39_tests.cpp \ test/bloom_tests.cpp \ test/bswap_tests.cpp \ + test/checkqueue_tests.cpp \ test/cachemap_tests.cpp \ test/cachemultimap_tests.cpp \ test/coins_tests.cpp \ diff --git a/src/checkqueue.h b/src/checkqueue.h index 32e25d5c8c6b7..ea12df66dd0e5 100644 --- a/src/checkqueue.h +++ b/src/checkqueue.h @@ -127,6 +127,9 @@ class CCheckQueue } public: + //! Mutex to ensure only one concurrent CCheckQueueControl + boost::mutex ControlMutex; + //! Create a new check queue CCheckQueue(unsigned int nBatchSizeIn) : nIdle(0), nTotal(0), fAllOk(true), nTodo(0), fQuit(false), nBatchSize(nBatchSizeIn) {} @@ -161,12 +164,6 @@ class CCheckQueue { } - bool IsIdle() - { - boost::unique_lock lock(mutex); - return (nTotal == nIdle && nTodo == 0 && fAllOk == true); - } - }; /** @@ -177,16 +174,18 @@ template class CCheckQueueControl { private: - CCheckQueue* pqueue; + CCheckQueue * const pqueue; bool fDone; public: - CCheckQueueControl(CCheckQueue* pqueueIn) : pqueue(pqueueIn), fDone(false) + CCheckQueueControl() = delete; + CCheckQueueControl(const CCheckQueueControl&) = delete; + CCheckQueueControl& operator=(const CCheckQueueControl&) = delete; + explicit CCheckQueueControl(CCheckQueue * const pqueueIn) : pqueue(pqueueIn), fDone(false) { // passed queue is supposed to be unused, or NULL if (pqueue != NULL) { - bool isIdle = pqueue->IsIdle(); - assert(isIdle); + ENTER_CRITICAL_SECTION(pqueue->ControlMutex); } } @@ -209,6 +208,9 @@ class CCheckQueueControl { if (!fDone) Wait(); + if (pqueue != NULL) { + LEAVE_CRITICAL_SECTION(pqueue->ControlMutex); + } } }; diff --git a/src/test/checkqueue_tests.cpp b/src/test/checkqueue_tests.cpp new file mode 100644 index 0000000000000..d89f9b770bce3 --- /dev/null +++ b/src/test/checkqueue_tests.cpp @@ -0,0 +1,442 @@ +// Copyright (c) 2012-2017 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 "utiltime.h" +#include "validation.h" + +#include "test/test_bitcoin.h" +#include "checkqueue.h" +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "random.h" + +// BasicTestingSetup not sufficient because nScriptCheckThreads is not set +// otherwise. +BOOST_FIXTURE_TEST_SUITE(checkqueue_tests, TestingSetup) + +static const int QUEUE_BATCH_SIZE = 128; + +struct FakeCheck { + bool operator()() + { + return true; + } + void swap(FakeCheck& x){}; +}; + +struct FakeCheckCheckCompletion { + static std::atomic n_calls; + bool operator()() + { + ++n_calls; + return true; + } + void swap(FakeCheckCheckCompletion& x){}; +}; + +struct FailingCheck { + bool fails; + FailingCheck(bool fails) : fails(fails){}; + FailingCheck() : fails(true){}; + bool operator()() + { + return !fails; + } + void swap(FailingCheck& x) + { + std::swap(fails, x.fails); + }; +}; + +struct UniqueCheck { + static std::mutex m; + static std::unordered_multiset results; + size_t check_id; + UniqueCheck(size_t check_id_in) : check_id(check_id_in){}; + UniqueCheck() : check_id(0){}; + bool operator()() + { + std::lock_guard l(m); + results.insert(check_id); + return true; + } + void swap(UniqueCheck& x) { std::swap(x.check_id, check_id); }; +}; + + +struct MemoryCheck { + static std::atomic fake_allocated_memory; + bool b {false}; + bool operator()() + { + return true; + } + MemoryCheck(){}; + MemoryCheck(const MemoryCheck& x) + { + // We have to do this to make sure that destructor calls are paired + // + // Really, copy constructor should be deletable, but CCheckQueue breaks + // if it is deleted because of internal push_back. + fake_allocated_memory += b; + }; + MemoryCheck(bool b_) : b(b_) + { + fake_allocated_memory += b; + }; + ~MemoryCheck(){ + fake_allocated_memory -= b; + + }; + void swap(MemoryCheck& x) { std::swap(b, x.b); }; +}; + +struct FrozenCleanupCheck { + static std::atomic nFrozen; + static std::condition_variable cv; + static std::mutex m; + // Freezing can't be the default initialized behavior given how the queue + // swaps in default initialized Checks. + bool should_freeze {false}; + bool operator()() + { + return true; + } + FrozenCleanupCheck() {} + ~FrozenCleanupCheck() + { + if (should_freeze) { + std::unique_lock l(m); + nFrozen = 1; + cv.notify_one(); + cv.wait(l, []{ return nFrozen == 0;}); + } + } + void swap(FrozenCleanupCheck& x){std::swap(should_freeze, x.should_freeze);}; +}; + +// Static Allocations +std::mutex FrozenCleanupCheck::m{}; +std::atomic FrozenCleanupCheck::nFrozen{0}; +std::condition_variable FrozenCleanupCheck::cv{}; +std::mutex UniqueCheck::m; +std::unordered_multiset UniqueCheck::results; +std::atomic FakeCheckCheckCompletion::n_calls{0}; +std::atomic MemoryCheck::fake_allocated_memory{0}; + +// Queue Typedefs +typedef CCheckQueue Correct_Queue; +typedef CCheckQueue Standard_Queue; +typedef CCheckQueue Failing_Queue; +typedef CCheckQueue Unique_Queue; +typedef CCheckQueue Memory_Queue; +typedef CCheckQueue FrozenCleanup_Queue; + + +/** This test case checks that the CCheckQueue works properly + * with each specified size_t Checks pushed. + */ +void Correct_Queue_range(std::vector range) +{ + auto small_queue = std::unique_ptr(new Correct_Queue {QUEUE_BATCH_SIZE}); + boost::thread_group tg; + for (auto x = 0; x < nScriptCheckThreads; ++x) { + tg.create_thread([&]{small_queue->Thread();}); + } + // Make vChecks here to save on malloc (this test can be slow...) + std::vector vChecks; + for (auto i : range) { + size_t total = i; + FakeCheckCheckCompletion::n_calls = 0; + CCheckQueueControl control(small_queue.get()); + while (total) { + vChecks.resize(std::min(total, (size_t) GetRand(10))); + total -= vChecks.size(); + control.Add(vChecks); + } + BOOST_REQUIRE(control.Wait()); + if (FakeCheckCheckCompletion::n_calls != i) { + BOOST_REQUIRE_EQUAL(FakeCheckCheckCompletion::n_calls, i); + BOOST_TEST_MESSAGE("Failure on trial " << i << " expected, got " << FakeCheckCheckCompletion::n_calls); + } + } + tg.interrupt_all(); + tg.join_all(); +} + +/** Test that 0 checks is correct + */ +BOOST_AUTO_TEST_CASE(test_CheckQueue_Correct_Zero) +{ + std::vector range; + range.push_back((size_t)0); + Correct_Queue_range(range); +} +/** Test that 1 check is correct + */ +BOOST_AUTO_TEST_CASE(test_CheckQueue_Correct_One) +{ + std::vector range; + range.push_back((size_t)1); + Correct_Queue_range(range); +} +/** Test that MAX check is correct + */ +BOOST_AUTO_TEST_CASE(test_CheckQueue_Correct_Max) +{ + std::vector range; + range.push_back(100000); + Correct_Queue_range(range); +} +/** Test that random numbers of checks are correct + */ +BOOST_AUTO_TEST_CASE(test_CheckQueue_Correct_Random) +{ + std::vector range; + range.reserve(100000/1000); + for (size_t i = 2; i < 100000; i += std::max((size_t)1, (size_t)GetRand(std::min((size_t)1000, ((size_t)100000) - i)))) + range.push_back(i); + Correct_Queue_range(range); +} + + +/** Test that failing checks are caught */ +BOOST_AUTO_TEST_CASE(test_CheckQueue_Catches_Failure) +{ + auto fail_queue = std::unique_ptr(new Failing_Queue {QUEUE_BATCH_SIZE}); + + boost::thread_group tg; + for (auto x = 0; x < nScriptCheckThreads; ++x) { + tg.create_thread([&]{fail_queue->Thread();}); + } + + for (size_t i = 0; i < 1001; ++i) { + CCheckQueueControl control(fail_queue.get()); + size_t remaining = i; + while (remaining) { + size_t r = GetRand(10); + + std::vector vChecks; + vChecks.reserve(r); + for (size_t k = 0; k < r && remaining; k++, remaining--) + vChecks.emplace_back(remaining == 1); + control.Add(vChecks); + } + bool success = control.Wait(); + if (i > 0) { + BOOST_REQUIRE(!success); + } else if (i == 0) { + BOOST_REQUIRE(success); + } + } + tg.interrupt_all(); + tg.join_all(); +} +// Test that a block validation which fails does not interfere with +// future blocks, ie, the bad state is cleared. +BOOST_AUTO_TEST_CASE(test_CheckQueue_Recovers_From_Failure) +{ + auto fail_queue = std::unique_ptr(new Failing_Queue {QUEUE_BATCH_SIZE}); + boost::thread_group tg; + for (auto x = 0; x < nScriptCheckThreads; ++x) { + tg.create_thread([&]{fail_queue->Thread();}); + } + + for (auto times = 0; times < 10; ++times) { + for (bool end_fails : {true, false}) { + CCheckQueueControl control(fail_queue.get()); + { + std::vector vChecks; + vChecks.resize(100, false); + vChecks[99] = end_fails; + control.Add(vChecks); + } + bool r =control.Wait(); + BOOST_REQUIRE(r || end_fails); + } + } + tg.interrupt_all(); + tg.join_all(); +} + +// Test that unique checks are actually all called individually, rather than +// just one check being called repeatedly. Test that checks are not called +// more than once as well +BOOST_AUTO_TEST_CASE(test_CheckQueue_UniqueCheck) +{ + auto queue = std::unique_ptr(new Unique_Queue {QUEUE_BATCH_SIZE}); + boost::thread_group tg; + for (auto x = 0; x < nScriptCheckThreads; ++x) { + tg.create_thread([&]{queue->Thread();}); + + } + + size_t COUNT = 100000; + size_t total = COUNT; + { + CCheckQueueControl control(queue.get()); + while (total) { + size_t r = GetRand(10); + std::vector vChecks; + for (size_t k = 0; k < r && total; k++) + vChecks.emplace_back(--total); + control.Add(vChecks); + } + } + bool r = true; + BOOST_REQUIRE_EQUAL(UniqueCheck::results.size(), COUNT); + for (size_t i = 0; i < COUNT; ++i) + r = r && UniqueCheck::results.count(i) == 1; + BOOST_REQUIRE(r); + tg.interrupt_all(); + tg.join_all(); +} + + +// Test that blocks which might allocate lots of memory free their memory agressively. +// +// This test attempts to catch a pathological case where by lazily freeing +// checks might mean leaving a check un-swapped out, and decreasing by 1 each +// time could leave the data hanging across a sequence of blocks. +BOOST_AUTO_TEST_CASE(test_CheckQueue_Memory) +{ + auto queue = std::unique_ptr(new Memory_Queue {QUEUE_BATCH_SIZE}); + boost::thread_group tg; + for (auto x = 0; x < nScriptCheckThreads; ++x) { + tg.create_thread([&]{queue->Thread();}); + } + for (size_t i = 0; i < 1000; ++i) { + size_t total = i; + { + CCheckQueueControl control(queue.get()); + while (total) { + size_t r = GetRand(10); + std::vector vChecks; + for (size_t k = 0; k < r && total; k++) { + total--; + // Each iteration leaves data at the front, back, and middle + // to catch any sort of deallocation failure + vChecks.emplace_back(total == 0 || total == i || total == i/2); + } + control.Add(vChecks); + } + } + BOOST_REQUIRE_EQUAL(MemoryCheck::fake_allocated_memory, 0); + } + tg.interrupt_all(); + tg.join_all(); +} + +// Test that a new verification cannot occur until all checks +// have been destructed +BOOST_AUTO_TEST_CASE(test_CheckQueue_FrozenCleanup) +{ + auto queue = std::unique_ptr(new FrozenCleanup_Queue {QUEUE_BATCH_SIZE}); + boost::thread_group tg; + bool fails = false; + for (auto x = 0; x < nScriptCheckThreads; ++x) { + tg.create_thread([&]{queue->Thread();}); + } + std::thread t0([&]() { + CCheckQueueControl control(queue.get()); + std::vector vChecks(1); + // Freezing can't be the default initialized behavior given how the queue + // swaps in default initialized Checks (otherwise freezing destructor + // would get called twice). + vChecks[0].should_freeze = true; + control.Add(vChecks); + control.Wait(); // Hangs here + }); + { + std::unique_lock l(FrozenCleanupCheck::m); + // Wait until the queue has finished all jobs and frozen + FrozenCleanupCheck::cv.wait(l, [](){return FrozenCleanupCheck::nFrozen == 1;}); + // Try to get control of the queue a bunch of times + for (auto x = 0; x < 100 && !fails; ++x) { + fails = queue->ControlMutex.try_lock(); + } + // Unfreeze + FrozenCleanupCheck::nFrozen = 0; + } + // Awaken frozen destructor + FrozenCleanupCheck::cv.notify_one(); + // Wait for control to finish + t0.join(); + tg.interrupt_all(); + tg.join_all(); + BOOST_REQUIRE(!fails); +} + + +/** Test that CCheckQueueControl is threadsafe */ +BOOST_AUTO_TEST_CASE(test_CheckQueueControl_Locks) +{ + auto queue = std::unique_ptr(new Standard_Queue{QUEUE_BATCH_SIZE}); + { + boost::thread_group tg; + std::atomic nThreads {0}; + std::atomic fails {0}; + for (size_t i = 0; i < 3; ++i) { + tg.create_thread( + [&]{ + CCheckQueueControl control(queue.get()); + // While sleeping, no other thread should execute to this point + auto observed = ++nThreads; + MilliSleep(10); + fails += observed != nThreads; + }); + } + tg.join_all(); + BOOST_REQUIRE_EQUAL(fails, 0); + } + { + boost::thread_group tg; + std::mutex m; + bool has_lock {false}; + bool has_tried {false}; + bool done {false}; + bool done_ack {false}; + std::condition_variable cv; + { + std::unique_lock l(m); + tg.create_thread([&]{ + CCheckQueueControl control(queue.get()); + std::unique_lock l(m); + has_lock = true; + cv.notify_one(); + cv.wait(l, [&]{return has_tried;}); + done = true; + cv.notify_one(); + // Wait until the done is acknowledged + // + cv.wait(l, [&]{return done_ack;}); + }); + // Wait for thread to get the lock + cv.wait(l, [&](){return has_lock;}); + bool fails = false; + for (auto x = 0; x < 100 && !fails; ++x) { + fails = queue->ControlMutex.try_lock(); + } + has_tried = true; + cv.notify_one(); + cv.wait(l, [&](){return done;}); + // Acknowledge the done + done_ack = true; + cv.notify_one(); + BOOST_REQUIRE(!fails); + } + tg.join_all(); + } +} +BOOST_AUTO_TEST_SUITE_END() + From 0e3e77040f03ad5f8365f3b4cf5351ca31c96369 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 14 Mar 2017 12:59:02 +0100 Subject: [PATCH 25/75] Merge #9481: [Qt] Show more significant warning if we fall back to the default fee 7abe7bb Qt/Send: Give fallback fee a reasonable indent (Luke Dashjr) 3e4d7bf Qt/Send: Figure a decent warning colour from theme (Luke Dashjr) c5adf8f [Qt] Show more significant warning if we fall back to the default fee (Jonas Schnelli) Tree-SHA512: 9e85b5b398d7a49aaf6c42578d63750b1b7aa9cc9e84d008fe21d6c53f1ffe2fb69286a1a764e634ebca3286564615578eea0a1bc883e4b332be8306d9883d14 --- src/qt/forms/sendcoinsdialog.ui | 22 ++++++++++++++++++++++ src/qt/sendcoinsdialog.cpp | 7 +++++++ 2 files changed, 29 insertions(+) diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui index 555b236650c61..67f5ec5a1c2d2 100644 --- a/src/qt/forms/sendcoinsdialog.ui +++ b/src/qt/forms/sendcoinsdialog.ui @@ -764,11 +764,33 @@ + + + + Using the fallbackfee can result in sending a transaction that will take serval hours or days (or never) to confirm. Consider choosing your fee manually or wait until your have validated the complete chain. + + + + 75 + true + + + + Warning: Fee estimation is currently not possible. + + + false + + + Qt::Horizontal + + QSizePolicy::MinimumExpanding + 40 diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index ad4838ebae295..767db851eb8b8 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -26,6 +26,7 @@ #include "privatesend.h" +#include #include #include #include @@ -769,6 +770,11 @@ void SendCoinsDialog::updateSmartFeeLabel() std::max(CWallet::fallbackFee.GetFeePerK(), CWallet::GetRequiredFee(1000))) + "/kB"); ui->labelSmartFee2->show(); // (Smart fee not initialized yet. This usually takes a few blocks...) ui->labelFeeEstimation->setText(""); + ui->fallbackFeeWarningLabel->setVisible(true); + int lightness = ui->fallbackFeeWarningLabel->palette().color(QPalette::WindowText).lightness(); + QColor warning_colour(255 - (lightness / 5), 176 - (lightness / 3), 48 - (lightness / 14)); + ui->fallbackFeeWarningLabel->setStyleSheet("QLabel { color: " + warning_colour.name() + "; }"); + ui->fallbackFeeWarningLabel->setIndent(QFontMetrics(ui->fallbackFeeWarningLabel->font()).width("x")); } else { @@ -776,6 +782,7 @@ void SendCoinsDialog::updateSmartFeeLabel() std::max(feeRate.GetFeePerK(), CWallet::GetRequiredFee(1000))) + "/kB"); ui->labelSmartFee2->hide(); ui->labelFeeEstimation->setText(tr("Estimated to begin confirmation within %n block(s).", "", estimateFoundAtBlocks)); + ui->fallbackFeeWarningLabel->setVisible(false); } updateFeeMinimizedLabel(); From 123284ef0f67638b1742857cda6a43701aec7a2c Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 16 Mar 2017 10:35:45 +0100 Subject: [PATCH 26/75] Merge #10008: [trivial] Fix a typo (introduced two days ago) in the default fee warning a3ca43b [trivial] Fix a typo (introduced two days ago) in the default fee warning (practicalswift) Tree-SHA512: b88bb45cb0cbe7f0b0c1dd5d573dad36f3915b1ddde58c9b29806544c832c4a2c0a7994080a57682684f1dea0a02d5367aed8ccbee331dbc40c45948392e0f3d --- src/qt/forms/sendcoinsdialog.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui index 67f5ec5a1c2d2..9ab86a05edaba 100644 --- a/src/qt/forms/sendcoinsdialog.ui +++ b/src/qt/forms/sendcoinsdialog.ui @@ -767,7 +767,7 @@ - Using the fallbackfee can result in sending a transaction that will take serval hours or days (or never) to confirm. Consider choosing your fee manually or wait until your have validated the complete chain. + Using the fallbackfee can result in sending a transaction that will take several hours or days (or never) to confirm. Consider choosing your fee manually or wait until your have validated the complete chain. From 10a76d40c06cbabbe65226c1071443af1add7508 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 20 Mar 2017 10:42:44 +0100 Subject: [PATCH 27/75] Merge #10037: Trivial: Fix typo in help getrawtransaction RPC 05a9f22 Trivial: Fix typo in help getrawtransaction RPC (James Evans) Tree-SHA512: 22c68fb49771f96b94c482b28d7efc4d51737cbb973ed3954641f3ea1832c14e7b909030c132afebe17854da134f717acbf14ee26294c61a303bc33dc43aac4c --- src/rpc/rawtransaction.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 1760cd5a65a22..264c14e476b3d 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -158,7 +158,7 @@ UniValue getrawtransaction(const JSONRPCRequest& request) "\nArguments:\n" "1. \"txid\" (string, required) The transaction id\n" - "2. verbose (bool, optional, default=false) If true, return a string, other return a json object\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" From 343954b088e71be36b55b79ffe7cf4f1b2f36cd5 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 27 Mar 2017 09:55:11 +0200 Subject: [PATCH 28/75] Merge #10060: [Qt] Ensure an item exists on the rpcconsole stack before adding 4df76e2 Ensure an item exists on the rpcconsole stack before adding (Andrew Chow) Tree-SHA512: f3fd5e70da186949aff794f6e2ba122da2145331212dcc5e0595285bee9dc3aa6b400b15e8eeec4476099965b74f46c4ef80f8ed1e05d490580167b002b9a5e7 --- src/qt/rpcconsole.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index e8d930679ffe3..960b1b1501604 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -185,6 +185,10 @@ bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string & nDepthInsideSensitive = 1; filter_begin_pos = chpos; } + // Make sure stack is not empty before adding something + if (stack.empty()) { + stack.push_back(std::vector()); + } stack.back().push_back(strArg); }; From 634643a468d11dbeaae02945bdbbb3550a532188 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 29 Mar 2017 10:44:35 +0200 Subject: [PATCH 29/75] Merge #10084: rpc: Rename first named arg of createrawtransaction fa55853 rpc: Rename first named arg of createrawtransaction (MarcoFalke) Tree-SHA512: f2e07183f2503344e676e08fe0fd73e995d7c6fda3fc11c64116208dec8e445f0627583dfba85014129b6f2dc7e253b9d760e57e66811272db89e9ba25ce6dbc --- src/rpc/client.cpp | 2 +- src/rpc/rawtransaction.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 063c2dfd9d5a6..cd7296c1f13a6 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -104,7 +104,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "getblockheaders", 2, "verbose" }, { "gettransaction", 1, "include_watchonly" }, { "getrawtransaction", 1, "verbose" }, - { "createrawtransaction", 0, "transactions" }, + { "createrawtransaction", 0, "inputs" }, { "createrawtransaction", 1, "outputs" }, { "createrawtransaction", 2, "locktime" }, { "signrawtransaction", 1, "prevtxs" }, diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 264c14e476b3d..d8bc81ea00358 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -387,7 +387,7 @@ UniValue createrawtransaction(const JSONRPCRequest& request) "it is not stored in the wallet or transmitted to the network.\n" "\nArguments:\n" - "1. \"inputs\" (string, required) A json array of json objects\n" + "1. \"inputs\" (array, required) A json array of json objects\n" " [\n" " {\n" " \"txid\":\"id\", (string, required) The transaction id\n" @@ -396,7 +396,7 @@ UniValue createrawtransaction(const JSONRPCRequest& request) " } \n" " ,...\n" " ]\n" - "2. \"outputs\" (string, required) a json object with outputs\n" + "2. \"outputs\" (object, required) a json object with outputs\n" " {\n" " \"address\": x.xxx, (numeric or string, required) The key is the absolute 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" @@ -952,7 +952,7 @@ static const CRPCCommand commands[] = { // category name actor (function) okSafeMode // --------------------- ------------------------ ----------------------- ---------- { "rawtransactions", "getrawtransaction", &getrawtransaction, true, {"txid","verbose"} }, - { "rawtransactions", "createrawtransaction", &createrawtransaction, true, {"transactions","outputs","locktime"} }, + { "rawtransactions", "createrawtransaction", &createrawtransaction, true, {"inputs","outputs","locktime"} }, { "rawtransactions", "decoderawtransaction", &decoderawtransaction, true, {"hexstring"} }, { "rawtransactions", "decodescript", &decodescript, true, {"hexstring"} }, { "rawtransactions", "sendrawtransaction", &sendrawtransaction, false, {"hexstring","allowhighfees","instantsend"} }, From c26e60bccf62d0459739218faeb98aa002b027d9 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 30 Mar 2017 20:53:31 +0200 Subject: [PATCH 30/75] =?UTF-8?q?Merge=20bitcoin#9959:=20Mining:=20Prevent?= =?UTF-8?q?=20slowdown=20in=20CreateNewBlock=20on=20lar=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/miner.cpp | 42 ++++++++++++++++++++++++++++++++++++++---- src/miner.h | 11 +++++++---- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index ed5e1da91501d..fef4bfa12b008 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -112,6 +112,8 @@ void BlockAssembler::resetBlock() std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn) { + int64_t nTimeStart = GetTimeMicros(); + resetBlock(); pblocktemplate.reset(new CBlockTemplate()); @@ -143,7 +145,12 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc : pblock->GetBlockTime(); addPriorityTxs(); - addPackageTxs(); + + int nPackagesSelected = 0; + int nDescendantsUpdated = 0; + addPackageTxs(nPackagesSelected, nDescendantsUpdated); + + int64_t nTime1 = GetTimeMicros(); nLastBlockTx = nBlockTx; nLastBlockSize = nBlockSize; @@ -183,6 +190,9 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc if (!TestBlockValidity(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); } @@ -294,9 +304,10 @@ void BlockAssembler::AddToBlock(CTxMemPool::txiter iter) } } -void BlockAssembler::UpdatePackagesForAdded(const CTxMemPool::setEntries& alreadyAdded, +int BlockAssembler::UpdatePackagesForAdded(const CTxMemPool::setEntries& alreadyAdded, indexed_modified_transaction_set &mapModifiedTx) { + int nDescendantsUpdated = 0; BOOST_FOREACH(const CTxMemPool::txiter it, alreadyAdded) { CTxMemPool::setEntries descendants; mempool.CalculateDescendants(it, descendants); @@ -304,6 +315,7 @@ void BlockAssembler::UpdatePackagesForAdded(const CTxMemPool::setEntries& alread BOOST_FOREACH(CTxMemPool::txiter desc, descendants) { if (alreadyAdded.count(desc)) continue; + ++nDescendantsUpdated; modtxiter mit = mapModifiedTx.find(desc); if (mit == mapModifiedTx.end()) { CTxMemPoolModifiedEntry modEntry(desc); @@ -316,6 +328,7 @@ void BlockAssembler::UpdatePackagesForAdded(const CTxMemPool::setEntries& alread } } } + return nDescendantsUpdated; } // Skip entries in mapTx that are already in a block or are present @@ -356,7 +369,7 @@ void BlockAssembler::SortForBlock(const CTxMemPool::setEntries& package, CTxMemP // 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() +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 @@ -370,6 +383,13 @@ void BlockAssembler::addPackageTxs() CTxMemPool::indexed_transaction_set::index::type::iterator mi = mempool.mapTx.get().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().end() || !mapModifiedTx.empty()) { // First try to find a new transaction in mapTx to evaluate. @@ -430,6 +450,14 @@ void BlockAssembler::addPackageTxs() mapModifiedTx.get().erase(modit); failedTx.insert(iter); } + + ++nConsecutiveFailed; + + if (nConsecutiveFailed > MAX_CONSECUTIVE_FAILURES && nBlockWeight > + nBlockMaxWeight - 4000) { + // Give up if we're close to full and haven't succeeded in a while + break; + } continue; } @@ -449,6 +477,10 @@ void BlockAssembler::addPackageTxs() } 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 sortedEntries; SortForBlock(ancestors, iter, sortedEntries); @@ -459,8 +491,10 @@ void BlockAssembler::addPackageTxs() mapModifiedTx.erase(sortedEntries[i]); } + ++nPackagesSelected; + // Update transactions that depend on each of these - UpdatePackagesForAdded(ancestors, mapModifiedTx); + nDescendantsUpdated += UpdatePackagesForAdded(ancestors, mapModifiedTx); } } diff --git a/src/miner.h b/src/miner.h index ff9c904ead341..de46fe2c7c9b3 100644 --- a/src/miner.h +++ b/src/miner.h @@ -173,8 +173,10 @@ class BlockAssembler // Methods for how to add transactions to a block. /** Add transactions based on tx "priority" */ void addPriorityTxs(); - /** Add transactions based on feerate including unconfirmed ancestors */ - void addPackageTxs(); + /** Add transactions based on feerate including unconfirmed ancestors + * Increments nPackagesSelected / nDescendantsUpdated with corresponding + * statistics from the package selection (for logging statistics). */ + void addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated); // helper function for addPriorityTxs /** Test if tx will still "fit" in the block */ @@ -197,8 +199,9 @@ class BlockAssembler /** Sort the package in an order that is valid to appear in a block */ void SortForBlock(const CTxMemPool::setEntries& package, CTxMemPool::txiter entry, std::vector& sortedEntries); /** Add descendants of given transactions to mapModifiedTx with ancestor - * state updated assuming given transactions are inBlock. */ - void UpdatePackagesForAdded(const CTxMemPool::setEntries& alreadyAdded, indexed_modified_transaction_set &mapModifiedTx); + * state updated assuming given transactions are inBlock. Returns number + * of updated descendants. */ + int UpdatePackagesForAdded(const CTxMemPool::setEntries& alreadyAdded, indexed_modified_transaction_set &mapModifiedTx); }; /** Modify the extranonce in a block */ void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce); From c5878f73dc88ce5f4be1ce6c0adc511e89e59985 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 31 Mar 2017 10:18:14 +0200 Subject: [PATCH 31/75] Merge #10130: bitcoin-tx input verification (awemany, jnewbery) 19ecd1e Add tests for bitcoin-tx input checking (John Newbery) 21704f6 Check stderr when testing bitcoin-tx (John Newbery) eb66bf9 bitcoin-tx: Fix missing range check (Awemany) Tree-SHA512: 08c6153cf7dd5e0ecd23e24d81af4c0f17534d484179dd91dcd78d42df14c91284341d31cc695469a64c507bce72c34231748b7cabb7df8f1051d228fb0a62c5 --- src/absolute-tx.cpp | 6 +++++ src/test/bctest.py | 12 ++++++++++ src/test/data/bitcoin-util-test.json | 36 ++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/src/absolute-tx.cpp b/src/absolute-tx.cpp index c34aa6ffdb28a..0de4e191bd76f 100644 --- a/src/absolute-tx.cpp +++ b/src/absolute-tx.cpp @@ -238,6 +238,9 @@ static void MutateTxAddOutAddr(CMutableTransaction& tx, const std::string& strIn std::vector 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]); @@ -260,6 +263,9 @@ static void MutateTxAddOutPubKey(CMutableTransaction& tx, const std::string& str std::vector 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]); diff --git a/src/test/bctest.py b/src/test/bctest.py index 540ea1077871b..6449b04de434b 100644 --- a/src/test/bctest.py +++ b/src/test/bctest.py @@ -99,6 +99,18 @@ def bctest(testDir, testObj, exeext): logging.error("Return code mismatch for " + outputFn) raise Exception + if "error_txt" in testObj: + want_error = testObj["error_txt"] + # Compare error text + # TODO: ideally, we'd compare the strings exactly and also assert + # That stderr is empty if no errors are expected. However, bitcoin-tx + # emits DISPLAY errors when running as a windows application on + # linux through wine. Just assert that the expected error text appears + # somewhere in stderr. + if want_error not in outs[1]: + logging.error("Error mismatch:\n" + "Expected: " + want_error + "\nReceived: " + outs[1].rstrip()) + raise Exception + def bctester(testDir, input_basename, buildenv): """ Loads and parses the input file, runs all tests and reports results""" input_filename = testDir + "/" + input_basename diff --git a/src/test/data/bitcoin-util-test.json b/src/test/data/bitcoin-util-test.json index 94240531386f7..af1be024046b7 100644 --- a/src/test/data/bitcoin-util-test.json +++ b/src/test/data/bitcoin-util-test.json @@ -42,6 +42,7 @@ "args": ["-", "delin=31"], "input": "tx394b54bb.hex", "return_code": 1, + "error_txt": "error: Invalid TX input index '31'", "description": "Attempts to delete an input with a bad index from a transaction. Expected to fail." }, { "exec": "./absolute-tx", @@ -60,6 +61,7 @@ "args": ["-", "delout=2"], "input": "tx394b54bb.hex", "return_code": 1, + "error_txt": "error: Invalid TX output index '2'", "description": "Attempts to delete an output with a bad index from a transaction. Expected to fail." }, { "exec": "./absolute-tx", @@ -75,6 +77,38 @@ "description": "Adds an nlocktime to a transaction (output in json)" }, { "exec": "./absolute-tx", + "args": + ["-create", + "outaddr=1"], + "return_code": 1, + "error_txt": "error: TX output missing or too many separators", + "description": "Malformed outaddr argument (no address specified). Expected to fail." + }, + { "exec": "./bitcoin-tx", + "args": + ["-create", + "outaddr=1:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o:garbage"], + "return_code": 1, + "error_txt": "error: TX output missing or too many separators", + "description": "Malformed outaddr argument (too many separators). Expected to fail." + }, + { "exec": "./bitcoin-tx", + "args": + ["-create", + "outpubkey=0"], + "return_code": 1, + "error_txt": "error: TX output missing or too many separators", + "description": "Malformed outpubkey argument (no pubkey specified). Expected to fail." + }, + { "exec": "./bitcoin-tx", + "args": + ["-create", + "outpubkey=0:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397:W:non53nse"], + "return_code": 1, + "error_txt": "error: TX output missing or too many separators", + "description": "Malformed outpubkey argument (too many separators). Expected to fail." + }, + { "exec": "./bitcoin-tx", "args": ["-create", "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", @@ -189,6 +223,7 @@ "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", "outdata=4:badhexdata"], "return_code": 1, + "error_txt": "error: invalid TX output data", "description": "Attempts to create a new transaction with one input and an output with malformed hex data. Expected to fail" }, { "exec": "./absolute-tx", @@ -197,6 +232,7 @@ "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", "outdata=badhexdata"], "return_code": 1, + "error_txt": "error: invalid TX output data", "description": "Attempts to create a new transaction with one input and an output with no value and malformed hex data. Expected to fail" }, { "exec": "./absolute-tx", From 4533c1a9f0905d0528f6b2d39be0290b34090963 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 31 Mar 2017 10:36:18 +0200 Subject: [PATCH 32/75] Merge #10120: util: Work around (virtual) memory exhaustion on 32-bit w/ glibc 625488a util: Work around (virtual) memory exhaustion on 32-bit w/ glibc (Wladimir J. van der Laan) Tree-SHA512: 99b610a8cf9561998af90e16fc19320fddd30c987e8f33325d63df0f56d70235b94d9482e80f28154d4b33a3ecf4961686380c444ec18d1da5e8804a8b6f4de1 --- configure.ac | 8 ++++++++ src/util.cpp | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/configure.ac b/configure.ac index 85bd7a6a5a023..5ec437a1cbee4 100644 --- a/configure.ac +++ b/configure.ac @@ -555,6 +555,14 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [ AC_MSG_RESULT(no)] ) +dnl Check for mallopt(M_ARENA_MAX) (to set glibc arenas) +AC_MSG_CHECKING(for mallopt M_ARENA_MAX) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[ mallopt(M_ARENA_MAX, 1); ]])], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_MALLOPT_ARENA_MAX, 1,[Define this symbol if you have mallopt with M_ARENA_MAX]) ], + [ AC_MSG_RESULT(no)] +) + AC_MSG_CHECKING([for visibility attribute]) AC_LINK_IFELSE([AC_LANG_SOURCE([ int foo_def( void ) __attribute__((visibility("default"))); diff --git a/src/util.cpp b/src/util.cpp index 72cf6cb6e0512..f25ce27fcfa11 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -76,6 +76,10 @@ #include #endif +#ifdef HAVE_MALLOPT_ARENA_MAX +#include +#endif + #include // for to_lower() #include #include // for startswith() and endswith() @@ -904,6 +908,16 @@ std::string GetThreadName() void SetupEnvironment() { +#ifdef HAVE_MALLOPT_ARENA_MAX + // glibc-specific: On 32-bit systems set the number of arenas to 1. + // By default, since glibc 2.10, the C library will create up to two heap + // arenas per core. This is known to cause excessive virtual address space + // usage in our usage. Work around it by setting the maximum number of + // arenas to 1. + if (sizeof(void*) == 4) { + mallopt(M_ARENA_MAX, 1); + } +#endif // On most POSIX systems (e.g. Linux, but not BSD) the environment's locale // may be invalid, in which case the "C" locale is used as fallback. #if !defined(WIN32) && !defined(MAC_OSX) && !defined(__FreeBSD__) && !defined(__OpenBSD__) From dc2860d518ef5e3f4135fc81ee00781f328e3767 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 3 Apr 2017 08:52:35 +0200 Subject: [PATCH 33/75] Merge #10139: [rpc] Remove auth cookie on shutdown 4b87973 [rpc] Remove auth cookie on shutdown (practicalswift) Tree-SHA512: 5d7d04413d3eb6a8d167443a3fdfe4c289bdc5cbc4c9b257a557c2a7fab5d4b32a81a1357e27b77ce2623e76e495b2e8b21eab0ab032bb261fdcdf171bac1dac --- src/rpc/server.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 5c8e551812802..f3ae36e78d01b 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -329,6 +329,7 @@ void StopRPC() { LogPrint("rpc", "Stopping RPC\n"); deadlineTimers.clear(); + DeleteAuthCookie(); g_rpcSignals.Stopped(); } From 44e5c21ee77bdf5bba6939140837761a9f0d0596 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 4 Apr 2017 08:58:53 +0200 Subject: [PATCH 34/75] Merge #10146: Better error handling for submitblock 30f30c0 Add braces to submitblock per current style. (Gregory Maxwell) 4f15ea1 Check transaction count early in submitblock. (Gregory Maxwell) ada0caa Make GetWitnessCommitmentIndex callable on blocks without a coinbase txn. (Gregory Maxwell) Tree-SHA512: 02dcd337ad9cdd8e4fa6a42c009d016026d1229c193676ed6fcc9ce55e924fedec57f516ac1e95c3db0985243ba908307338ce783a70416cb292bed881002bfc --- src/rpc/mining.cpp | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 5a3be5f30e262..13bd395d22ce2 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -756,7 +756,7 @@ class submitblock_StateCatcher : public CValidationInterface UniValue submitblock(const JSONRPCRequest& request) { - if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { throw runtime_error( "submitblock \"hexdata\" ( \"jsonparametersobject\" )\n" "\nAttempts to submit new block to network.\n" @@ -774,11 +774,17 @@ UniValue submitblock(const JSONRPCRequest& request) + HelpExampleCli("submitblock", "\"mydata\"") + HelpExampleRpc("submitblock", "\"mydata\"") ); + } std::shared_ptr blockptr = std::make_shared(); CBlock& block = *blockptr; - if (!DecodeHexBlk(block, request.params[0].get_str())) + if (!DecodeHexBlk(block, request.params[0].get_str())) { throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed"); + } + + if (block.vtx.empty() || !block.vtx[0]->IsCoinBase()) { + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block does not start with a coinbase"); + } uint256 hash = block.GetHash(); bool fBlockPresent = false; @@ -787,10 +793,12 @@ UniValue submitblock(const JSONRPCRequest& request) BlockMap::iterator mi = mapBlockIndex.find(hash); if (mi != mapBlockIndex.end()) { CBlockIndex *pindex = mi->second; - if (pindex->IsValid(BLOCK_VALID_SCRIPTS)) + if (pindex->IsValid(BLOCK_VALID_SCRIPTS)) { return "duplicate"; - if (pindex->nStatus & BLOCK_FAILED_MASK) + } + if (pindex->nStatus & BLOCK_FAILED_MASK) { return "duplicate-invalid"; + } // Otherwise, we might only have the header - process the block before returning fBlockPresent = true; } @@ -800,14 +808,15 @@ UniValue submitblock(const JSONRPCRequest& request) RegisterValidationInterface(&sc); bool fAccepted = ProcessNewBlock(Params(), blockptr, true, NULL); UnregisterValidationInterface(&sc); - if (fBlockPresent) - { - if (fAccepted && !sc.found) + if (fBlockPresent) { + if (fAccepted && !sc.found) { return "duplicate-inconclusive"; + } return "duplicate"; } - if (!sc.found) + if (!sc.found) { return "inconclusive"; + } return BIP22ValidationResult(sc.state); } From c87714a71fe885e11ac148544aac52ff8b3a8e50 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 5 Apr 2017 08:36:34 +0200 Subject: [PATCH 35/75] Merge #10144: Prioritisetransaction wasn't always updating ancestor fee 9bef02e Bugfix: ancestor modifed fees were incorrect for descendants (Suhas Daftuar) ba7dd8b Test prioritisetransaction and ancestor fee state (Suhas Daftuar) Tree-SHA512: 01977d88e1afb093a003f22a6f29ea60df3d70a179fe7e55910b9c8c340c4af9fb20cdc804c40235b62c43c453f0194eda0d0d4dbd365d2d98347f5dbe5de01c --- qa/rpc-tests/mempool_packages.py | 12 ++++++++++++ src/txmempool.cpp | 7 +++++++ 2 files changed, 19 insertions(+) diff --git a/qa/rpc-tests/mempool_packages.py b/qa/rpc-tests/mempool_packages.py index c920c69a53b4d..a5bcd349f38e7 100755 --- a/qa/rpc-tests/mempool_packages.py +++ b/qa/rpc-tests/mempool_packages.py @@ -101,6 +101,18 @@ def run_test(self): assert_equal(mempool[x], v_descendants[x]) assert(chain[0] not in v_descendants.keys()) + # Check that ancestor modified fees includes fee deltas from + # prioritisetransaction + self.nodes[0].prioritisetransaction(chain[0], 1000) + mempool = self.nodes[0].getrawmempool(True) + ancestor_fees = 0 + for x in chain: + ancestor_fees += mempool[x]['fee'] + assert_equal(mempool[x]['ancestorfees'], ancestor_fees * COIN + 1000) + + # Undo the prioritisetransaction for later tests + self.nodes[0].prioritisetransaction(chain[0], -1000) + # Check that descendant modified fees includes fee deltas from # prioritisetransaction self.nodes[0].prioritisetransaction(chain[-1], 0, 1000) diff --git a/src/txmempool.cpp b/src/txmempool.cpp index cccd70ae7757d..07b132329d846 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -1070,6 +1070,13 @@ void CTxMemPool::PrioritiseTransaction(const uint256 hash, const std::string str BOOST_FOREACH(txiter ancestorIt, setAncestors) { mapTx.modify(ancestorIt, update_descendant_state(0, nFeeDelta, 0)); } + // Now update all descendants' modified fees with ancestors + setEntries setDescendants; + CalculateDescendants(it, setDescendants); + setDescendants.erase(it); + BOOST_FOREACH(txiter descendantIt, setDescendants) { + mapTx.modify(descendantIt, update_ancestor_state(0, nFeeDelta, 0, 0)); + } } } LogPrintf("PrioritiseTransaction: %s priority += %f, fee += %d\n", strHash, dPriorityDelta, FormatMoney(nFeeDelta)); From f81678e23b89d09f6607db06620c8effff09294f Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 6 Apr 2017 09:35:41 +0200 Subject: [PATCH 36/75] Merge #10157: [0.14] Fix the mempool_packages.py test 39febb8 [qa] Fix mempool_packages.py for the 0.14 branch (Suhas Daftuar) Tree-SHA512: 7b5f2627a76d79da5d7c9d30794219a87bec99296d5f74f66b347c7c8914244bfd07f0d48231adda7269678706fd9158b846d710f942b724c8c5748cc4a49c7e --- qa/rpc-tests/mempool_packages.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/mempool_packages.py b/qa/rpc-tests/mempool_packages.py index a5bcd349f38e7..c4f24e8c2622d 100755 --- a/qa/rpc-tests/mempool_packages.py +++ b/qa/rpc-tests/mempool_packages.py @@ -103,7 +103,7 @@ def run_test(self): # Check that ancestor modified fees includes fee deltas from # prioritisetransaction - self.nodes[0].prioritisetransaction(chain[0], 1000) + self.nodes[0].prioritisetransaction(chain[0], 0, 1000) mempool = self.nodes[0].getrawmempool(True) ancestor_fees = 0 for x in chain: @@ -111,7 +111,7 @@ def run_test(self): assert_equal(mempool[x]['ancestorfees'], ancestor_fees * COIN + 1000) # Undo the prioritisetransaction for later tests - self.nodes[0].prioritisetransaction(chain[0], -1000) + self.nodes[0].prioritisetransaction(chain[0], 0, -1000) # Check that descendant modified fees includes fee deltas from # prioritisetransaction From cb032fabc56b6b7f250c14c78d38639bd7cab78d Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 13 Apr 2017 16:30:38 +0200 Subject: [PATCH 37/75] Merge #10176: net: gracefully handle NodeId wrapping c851be4 net: define NodeId as an int64_t (Cory Fields) Tree-SHA512: 2ccc931cfcdc555313b9434d8de2f6cea759b31891212ca62f962208f60157d4fc593010e3ca61265d1a20d6f78c6ca79103600b85df77983d5509d192875b96 --- src/net.h | 2 +- src/qt/peertablemodel.cpp | 2 +- src/qt/rpcconsole.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/net.h b/src/net.h index 5523c74e98ad3..44c3b4ccc3f91 100644 --- a/src/net.h +++ b/src/net.h @@ -97,7 +97,7 @@ static const ServiceFlags REQUIRED_SERVICES = NODE_NETWORK; // NOTE: When adjusting this, update rpcnet:setban's help ("24h") static const unsigned int DEFAULT_MISBEHAVING_BANTIME = 60 * 60 * 24; // Default 24-hour ban -typedef int NodeId; +typedef int64_t NodeId; struct AddedNodeInfo { diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp index dd4bd5539640d..33b1f611f86f6 100644 --- a/src/qt/peertablemodel.cpp +++ b/src/qt/peertablemodel.cpp @@ -166,7 +166,7 @@ QVariant PeerTableModel::data(const QModelIndex &index, int role) const switch(index.column()) { case NetNodeId: - return rec->nodeStats.nodeid; + return (qint64)rec->nodeStats.nodeid; case Address: return QString::fromStdString(rec->nodeStats.addrName); case Subversion: diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 960b1b1501604..14bb9dad49a65 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -1209,7 +1209,7 @@ void RPCConsole::disconnectSelectedNode() for(int i = 0; i < nodes.count(); i++) { // Get currently selected peer address - NodeId id = nodes.at(i).data().toInt(); + NodeId id = nodes.at(i).data().toLongLong(); // Find the node, disconnect it and clear the selected node if(g_connman->DisconnectNode(id)) clearSelectedNode(); @@ -1226,7 +1226,7 @@ void RPCConsole::banSelectedNode(int bantime) for(int i = 0; i < nodes.count(); i++) { // Get currently selected peer address - NodeId id = nodes.at(i).data().toInt(); + NodeId id = nodes.at(i).data().toLongLong(); // Get currently selected peer address int detailNodeRow = clientModel->getPeerTableModel()->getRowByNodeId(id); From 646e813a6784a6e1aa2bcd5dcae6c8b95c5080fa Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 14 Apr 2017 10:15:29 +0200 Subject: [PATCH 38/75] Merge #10204: [rpc] rename disconnectnode argument 883154c [rpc] rename disconnectnode argument (John Newbery) Tree-SHA512: 14245befd0a7315edd9e03c8bb283ff6b546cf4ef93c3ce02c01de687fea3bb96c510a638a42d2d6799e5e3e5b4f800021c2530b504baeaa4a4dc99323165986 --- src/rpc/net.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 60521421dc80d..b7142baf80129 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -240,10 +240,10 @@ UniValue disconnectnode(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 1) throw runtime_error( - "disconnectnode \"node\" \n" + "disconnectnode \"address\" \n" "\nImmediately disconnects from the specified node.\n" "\nArguments:\n" - "1. \"node\" (string, required) The node (see getpeerinfo for nodes)\n" + "1. \"address\" (string, required) The IP address/port of the node\n" "\nExamples:\n" + HelpExampleCli("disconnectnode", "\"192.168.0.6:8800\"") + HelpExampleRpc("disconnectnode", "\"192.168.0.6:8800\"") @@ -611,7 +611,7 @@ static const CRPCCommand commands[] = { "network", "ping", &ping, true, {} }, { "network", "getpeerinfo", &getpeerinfo, true, {} }, { "network", "addnode", &addnode, true, {"node","command"} }, - { "network", "disconnectnode", &disconnectnode, true, {"node"} }, + { "network", "disconnectnode", &disconnectnode, true, {"address"} }, { "network", "getaddednodeinfo", &getaddednodeinfo, true, {"node"} }, { "network", "getnettotals", &getnettotals, true, {} }, { "network", "getnetworkinfo", &getnetworkinfo, true, {} }, From df7d94b9f8742fa00204ec2feef6aaf213f89011 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 17 Apr 2017 05:08:19 -0700 Subject: [PATCH 39/75] Merge #10215: Check interruptNet during dnsseed lookups b2c9254 Check interruptNet during dnsseed lookups (Matt Corallo) Tree-SHA512: a76b5749b085d5571ac65a6925bb1c50fa1d02c02854d9126224dc2ec419eb9103f7c92bf9a0bbd39c7dee93a2266dc3973fb16b48e8daea057f45d452e2513c --- src/net.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/net.cpp b/src/net.cpp index b89203f2edf7b..d649a1af961d7 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1588,6 +1588,9 @@ void CConnman::ThreadDNSAddressSeed() LogPrintf("Loading addresses from DNS seeds (could take a while)\n"); BOOST_FOREACH(const CDNSSeedData &seed, vSeeds) { + if (interruptNet) { + return; + } if (HaveNameProxy()) { AddOneShot(seed.host); } else { @@ -1605,6 +1608,9 @@ void CConnman::ThreadDNSAddressSeed() 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 From 382444e48d5e4b5bd135938c77d73bd46bcbbfa0 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 17 Apr 2017 22:10:46 +0200 Subject: [PATCH 40/75] Merge #10207: Clarify importprivkey help text ... example of blank label without rescan c9e31c3 Clarify importprivkey help text with example of blank label without rescan Occasionally I waste a lot of time not remembering that the second parameter to importprivkey must be blank if you intend to stop rescan with "false" as the third parameter. (Warren Togami) Tree-SHA512: 23781e1d6fd59a9d06d6e12ad10e8ed6641947b3e4a1f66c8fdb5d44cbd8f291e8f2a5e686aa9f9ba5e4bab8ca688caa17244e837f651546055ddf7cc8e7df8f --- src/wallet/rpcdump.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index d552c6099e54b..2dc9d11175ecb 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -99,6 +99,8 @@ UniValue importprivkey(const JSONRPCRequest& request) + 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") ); From c9ff1fcea3a4a1a4011a9221f5218c3fc61ac5ba Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 21 Apr 2017 10:42:13 +0200 Subject: [PATCH 41/75] Merge #10245: Minor fix in build documentation for FreeBSD 11 0611bc3 Minor fix in build documentation for FreeBSD 11 (Shigeya Suzuki) Tree-SHA512: d0e0b66868e4a988e1fa121b9c7b2877b77e2b3c7a9d7a6220c9e16cf0d6817786e9020aeba19dfa2cbc07b2fbba12f2afefc442e762a7d00292bde7515ef880 --- doc/build-unix.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/build-unix.md b/doc/build-unix.md index e5687abeaea9a..7bf2c170ef79d 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -317,8 +317,10 @@ Clang is installed by default as `cc` compiler, this makes it easier to get started than on [OpenBSD](build-openbsd.md). Installing dependencies: pkg install autoconf automake libtool pkgconf - pkg install boost-libs openssl libevent2 + pkg install boost-libs openssl libevent + pkg install gmake +You need to use GNU make (`gmake`) instead of `make`. (`libressl` instead of `openssl` will also work) For the wallet (optional): @@ -334,7 +336,7 @@ Then build using: ./autogen.sh ./configure --with-incompatible-bdb BDB_CFLAGS="-I/usr/local/include/db5" BDB_LIBS="-L/usr/local/lib -ldb_cxx-5" - make + gmake *Note on debugging*: The version of `gdb` installed by default is [ancient and considered harmful](https://wiki.freebsd.org/GdbRetirement). It is not suitable for debugging a multi-threaded C++ program, not even for getting backtraces. Please install the package `gdb` and From 154f572d6705b07da18d53510c7055ba88886505 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 21 Apr 2017 10:59:01 +0200 Subject: [PATCH 42/75] Merge #10228: build: regenerate bitcoin-config.h as necessary 91ab8f5 build: fix bitcoin-config.h regeneration after touching build files (Cory Fields) 3577603 build: remove wonky auto top-level convenience targets (Cory Fields) Tree-SHA512: 2e68634439eeb7eca43cd2858135a583bfe0cf146e021a8384a24f7267aacc6f99bdc7a6d497a04d32e6a03e9446f0f599afb5bd53346dadf19f47d5fb2ea9f9 --- Makefile.am | 3 --- src/Makefile.am | 8 ++++++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Makefile.am b/Makefile.am index f8b0d27b0d745..66169a54642f8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -75,9 +75,6 @@ $(BITCOIN_WIN_INSTALLER): all-recursive echo error: could not build $@ @echo built $@ -$(if $(findstring src/,$(MAKECMDGOALS)),$(MAKECMDGOALS), none): FORCE - $(MAKE) -C src $(patsubst src/%,%,$@) - $(OSX_APP)/Contents/PkgInfo: $(MKDIR_P) $(@D) @echo "APPL????" > $@ diff --git a/src/Makefile.am b/src/Makefile.am index 6026b3a256947..5b073b34a47af 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -572,6 +572,14 @@ DISTCLEANFILES = obj/build.h EXTRA_DIST = $(CTAES_DIST) + +config/dash-config.h: config/stamp-h1 + @$(MAKE) -C $(top_builddir) $(subdir)/$(@) +config/stamp-h1: $(top_srcdir)/$(subdir)/config/dash-config.h.in $(top_builddir)/config.status + $(AM_V_at)$(MAKE) -C $(top_builddir) $(subdir)/$(@) +$(top_srcdir)/$(subdir)/config/dash-config.h.in: $(am__configure_deps) + $(AM_V_at)$(MAKE) -C $(top_srcdir) $(subdir)/config/dash-config.h.in + clean-local: -$(MAKE) -C secp256k1 clean -$(MAKE) -C univalue clean From 1a4e5cd053081592beee9be9abbfc3cea72c78ee Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 23 Apr 2017 16:49:23 +0200 Subject: [PATCH 43/75] Merge #10258: Fixed typo in documentation for merkleblock.h dd07068 Fixed typo in documentation for merkleblock.h (Mikerah) Tree-SHA512: 92655c8022eb33852c116da517b12bd17b3b668713cd85fe185a15245ea9810605626b1d0955fa117f7b56863e0a52b3a86dab42409332452b5eb72a7d34f30d --- src/merkleblock.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/merkleblock.h b/src/merkleblock.h index 17c33194a95b1..68fac71a938d8 100644 --- a/src/merkleblock.h +++ b/src/merkleblock.h @@ -23,7 +23,7 @@ * 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, and its children are not explored 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. From 0c2579e067c629d57b34d73a7134d2d1041c0f1b Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 25 Apr 2017 16:00:57 +0200 Subject: [PATCH 44/75] Merge #10265: [wallet] [moveonly] Check non-null pindex before potentially referencing c36ea69 [wallet] Make sure pindex is non-null before possibly referencing in LogPrintf call. (Karl-Johan Alm) Tree-SHA512: a14c9f3e1228bca91977bea821c56a377d80889b41d250050c9be67aa93e460319a7cf1d4b63ee40f23b5a34159590f0e3fe15dc88698dc694c0c8098bd2db4d --- src/wallet/wallet.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 3c41bf9374b5e..a08cb1f550108 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1864,6 +1864,10 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool f { 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)))); + if (GetTime() >= nNow + 60) { + nNow = GetTime(); + LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->nHeight, GuessVerificationProgress(chainParams.TxData(), pindex)); + } CBlock block; if (ReadBlockFromDisk(block, pindex, Params().GetConsensus())) { @@ -1877,10 +1881,6 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool f 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)); - } } ShowProgress(_("Rescanning..."), 100); // hide progress dialog in GUI } From 496a3991010d20d4a3fe652e8e7467092fd3106b Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 1 May 2017 15:19:47 +0200 Subject: [PATCH 45/75] Merge #10294: [Wallet] unset change position when there is no change 7c58863 [Wallet] unset change position when there is no change on exact match (Gregory Sanders) Tree-SHA512: ce8b9337e4132e32d80f954258d50938052c833a48e39431649d6adb16e3d18626a0ae5d300827e7fa397927fba72a1f066cb31af9b0a3ef7f1feb6024461626 --- qa/rpc-tests/fundrawtransaction.py | 5 +++++ src/wallet/wallet.cpp | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index 440d46e5da3eb..44762faa7008a 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -51,6 +51,11 @@ def run_test(self): self.nodes[0].generate(121) self.sync_all() + # ensure that setting changePosition in fundraw with an exact match is handled properly + rawmatch = self.nodes[2].createrawtransaction([], {self.nodes[2].getnewaddress():50}) + rawmatch = self.nodes[2].fundrawtransaction(rawmatch, {"changePosition":1, "subtractFeeFromOutputs":[0]}) + assert_equal(rawmatch["changepos"], -1) + watchonly_address = self.nodes[0].getnewaddress() watchonly_pubkey = self.nodes[0].validateaddress(watchonly_address)["pubkey"] watchonly_amount = Decimal(2000) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index a08cb1f550108..f2169cd54ca80 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3595,9 +3595,10 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt txNew.vout.insert(position, newTxOut); } } - } - else + } else { reservekey.ReturnKey(); + nChangePosInOut = -1; + } // Fill vin // From 39f1352728de22bdb2fd00594bb353a1c35cef40 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 1 May 2017 14:53:00 -0700 Subject: [PATCH 46/75] Merge #10309: Trivial: remove extra character from comment 3503716 Trivial: remove extra character from comment (CryptAxe) Tree-SHA512: 66ee474945b4f9fd098cee0d031c1860c0777d4b05c609c0eaba32234209356b630766de30235b49d22cc5ea7cf2bb93410dea4466396369a0cdc0b631512a33 --- src/merkleblock.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp index 12f0519939804..e453561733eb6 100644 --- a/src/merkleblock.cpp +++ b/src/merkleblock.cpp @@ -65,7 +65,7 @@ uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::ve } else { // calculate left hash uint256 left = CalcHash(height-1, pos*2, vTxid), right; - // calculate right hash if not beyond the end of the array - copy left hash otherwise1 + // calculate right hash if not beyond the end of the array - copy left hash otherwise if (pos*2+1 < CalcTreeWidth(height-1)) right = CalcHash(height-1, pos*2+1, vTxid); else From 493cc4aff222ed012828be93c02069191c903f7b Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 2 May 2017 18:48:58 +0200 Subject: [PATCH 47/75] Merge #10260: [doc] Minor corrections to osx dependencies 661caf8 [doc] Minor corrections to osx dependencies (fanquake) Tree-SHA512: 61451807d6208002550d2e37d26094a5515b11daacab39eb508b6168eebcea86f93dcc7f853aab490baec3727740c90d404c481e11b3d03dcea9f76f8fc7be12 --- doc/build-osx.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/build-osx.md b/doc/build-osx.md index cb52402af38d1..be20a971bf514 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -11,14 +11,14 @@ Install the OS X command line tools: When the popup appears, click `Install`. -Then install [Homebrew](http://brew.sh). +Then install [Homebrew](https://brew.sh). Dependencies ---------------------- - brew install automake berkeley-db4 libtool boost --c++11 miniupnpc openssl pkg-config protobuf --c++11 qt5 libevent + brew install automake berkeley-db4 libtool boost --c++11 miniupnpc openssl pkg-config protobuf qt libevent -In case you want to build the disk image with `make deploy` (.dmg / optional), you need RSVG +If you want to build the disk image with `make deploy` (.dmg / optional), you need RSVG brew install librsvg From 6b9ad941259dd39208a08dce04990c575352f452 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 8 May 2017 19:28:55 +0200 Subject: [PATCH 48/75] Merge #10310: [doc] Add hint about getmempoolentry to getrawmempool help. 3a0a5bc [doc] Add hint about getmempoolentry to getrawmempool help. (Karl-Johan Alm) Tree-SHA512: 8327d7d7ad93296525fbf95b7a824e3525bde84653999f125afd845823eb39e3a03cd39725962ed949aa2b9ad207ecad6d287294fa321ff1a4d7fbd5a4b8560b --- src/rpc/blockchain.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index b5e97af870d7e..097f5111b3032 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -416,6 +416,7 @@ UniValue getrawmempool(const JSONRPCRequest& request) throw runtime_error( "getrawmempool ( verbose )\n" "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n" + "\nHint: use getmempoolentry to fetch a specific transaction from the mempool.\n" "\nArguments:\n" "1. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n" "\nResult: (for verbose = false):\n" From 110badb249b6c23698000addc60f45c2c578a558 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 11 May 2017 18:54:02 +0200 Subject: [PATCH 49/75] Merge #10328: Update contrib/debian to latest Ubuntu PPA upload. 91700aa Re-enable upnp support in contrib/debian (Matt Corallo) c5071e1 Build with QT5 on Debian-based systems using contrib/debian (Matt Corallo) a8e9286 Bump minimum boost version in contrib/debian (Matt Corallo) 9970219 Update contrib/debian to latest Ubuntu PPA upload. (Matt Corallo) Tree-SHA512: ee4d3c5927a9cfb2794672eaca883c4af5df541383afbdbc6500714ee17518e78b58f509b2e9805bbc424ef97a5e64be0b9a977212c5002cb682f0569d28099b --- contrib/debian/changelog | 57 ++++++++++++++++++++++++++++++++++++++++ contrib/debian/control | 20 +++++++------- contrib/debian/rules | 4 ++- 3 files changed, 71 insertions(+), 10 deletions(-) diff --git a/contrib/debian/changelog b/contrib/debian/changelog index 258f3cc735362..33dab9b638889 100644 --- a/contrib/debian/changelog +++ b/contrib/debian/changelog @@ -1,3 +1,60 @@ +bitcoin (0.14.1-trusty4) trusty; urgency=medium + + * Re-enable UPnP support. + + -- Matt Corallo (BlueMatt) Fri, 05 May 2017 13:28:00 -0400 + +bitcoin (0.14.1-trusty3) trusty; urgency=medium + + * Build with qt5 if we are on a non-Ubuntu (ie non-Unity) distro. + + -- Matt Corallo (BlueMatt) Thu, 04 May 2017 17:13:00 -0400 + +bitcoin (0.14.1-trusty2) trusty; urgency=medium + + * Bump minimum boost version in deps. + + -- Matt Corallo (BlueMatt) Thu, 04 May 2017 17:12:00 -0400 + +bitcoin (0.14.1-trusty1) trusty; urgency=medium + + * New upstream release. + + -- Matt Corallo (BlueMatt) Sat, 22 Apr 2017 17:10:00 -0400 + +bitcoin (0.14.0-trusty1) trusty; urgency=medium + + * New upstream release. + + -- Matt Corallo (BlueMatt) Wed, 08 Mar 2017 10:30:00 -0500 + +bitcoin (0.13.2-trusty1) trusty; urgency=medium + + * New upstream release. + + -- Matt Corallo (BlueMatt) Thu, 05 Jan 2017 09:59:00 -0500 + +bitcoin (0.13.1-trusty2) trusty; urgency=medium + + * Revert to Qt4, due to https://github.com/bitcoin/bitcoin/issues/9038 + + -- Matt Corallo (BlueMatt) Mon, 31 Oct 2016 11:16:00 -0400 + +bitcoin (0.13.1-trusty1) trusty; urgency=medium + + * New upstream release. + * Backport updated bitcoin-qt.desktop from upstream master + * Add zmq dependency + * Switch to Qt5 (breaks precise, but that was already broken by C++11) + + -- Matt Corallo (BlueMatt) Thu, 27 Oct 2016 17:32:00 -0400 + +bitcoin (0.13.0-trusty1) trusty; urgency=medium + + * New upstream release. + + -- Matt Corallo (BlueMatt) Sun, 04 Sep 2016 22:09:00 -0400 + bitcoin (0.12.1-trusty1) trusty; urgency=medium * New upstream release. diff --git a/contrib/debian/control b/contrib/debian/control index a74e43fa4d68c..3a0a39f7a1276 100644 --- a/contrib/debian/control +++ b/contrib/debian/control @@ -10,17 +10,19 @@ Build-Depends: debhelper, libssl-dev, pkg-config, libevent-dev, - libboost-system1.48-dev | libboost-system-dev (>> 1.35), - libboost-filesystem1.48-dev | libboost-filesystem-dev (>> 1.35), - libboost-program-options1.48-dev | libboost-program-options-dev (>> 1.35), - libboost-thread1.48-dev | libboost-thread-dev (>> 1.35), - libboost-test1.48-dev | libboost-test-dev (>> 1.35), - libboost-chrono1.48-dev | libboost-chrono-dev (>> 1.35), - qt4-qmake, - libqt4-dev, + libboost-system1.48-dev | libboost-system-dev (>> 1.47), + libboost-filesystem1.48-dev | libboost-filesystem-dev (>> 1.47), + libboost-program-options1.48-dev | libboost-program-options-dev (>> 1.47), + libboost-thread1.48-dev | libboost-thread-dev (>> 1.47), + libboost-test1.48-dev | libboost-test-dev (>> 1.47), + libboost-chrono1.48-dev | libboost-chrono-dev (>> 1.47), + libminiupnpc8-dev | libminiupnpc-dev, + qt4-qmake, libqt4-dev, + qttools5-dev-tools, qttools5-dev, libqrencode-dev, libprotobuf-dev, protobuf-compiler, - python + python, + libzmq3-dev Standards-Version: 3.9.2 Homepage: https://absolutecoin.net Vcs-Git: git://github.com/absolutecrypto/absolutecoin.git diff --git a/contrib/debian/rules b/contrib/debian/rules index cf12eb9f4c1d8..a6041202ddfa1 100755 --- a/contrib/debian/rules +++ b/contrib/debian/rules @@ -12,10 +12,12 @@ override_dh_auto_clean: if [ -f Makefile ]; then $(MAKE) distclean; fi rm -rf Makefile.in aclocal.m4 configure src/Makefile.in src/absolute-config.h.in src/build-aux src/qt/Makefile.in src/qt/test/Makefile.in src/test/Makefile.in +QT=$(shell dpkg-vendor --derives-from Ubuntu && echo qt4 || echo qt5) + # Yea, autogen should be run on the source archive, but I like doing git archive override_dh_auto_configure: ./autogen.sh - ./configure --without-miniupnpc --with-gui=qt4 + ./configure --with-gui=$(QT) override_dh_auto_test: make check From 164e26a01a83fd99f0ad5c7b0096300e9b72f784 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 11 May 2017 19:28:04 +0200 Subject: [PATCH 50/75] Merge #10308: [wallet] Securely erase potentially sensitive keys/values 6c914ac [wallet] Securely erase potentially sensitive keys/values (Thomas Snider) Tree-SHA512: 071d88c4093108d4e4eced35a6ffcebe3f499798194f5b1be661ffa5b78b5f55311667f6d2a72758d85290f61f958381ee95d380b9045ca18e9e1875f0e686c8 --- src/support/cleanse.h | 1 + src/wallet/db.h | 43 ++++++++++++++++++++++--------------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/support/cleanse.h b/src/support/cleanse.h index 3e02aa8fd1fe5..f020216c7300a 100644 --- a/src/support/cleanse.h +++ b/src/support/cleanse.h @@ -8,6 +8,7 @@ #include +// Attempt to overwrite data in the specified memory span. void memory_cleanse(void *ptr, size_t len); #endif // BITCOIN_SUPPORT_CLEANSE_H diff --git a/src/wallet/db.h b/src/wallet/db.h index 75ed6f930c7b5..84f58b2b27cdc 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -126,22 +126,23 @@ class CDB 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() == NULL) - 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; + memory_cleanse(datKey.get_data(), datKey.get_size()); + bool success = false; + if (datValue.get_data() != NULL) { + // Unserialize value + try { + CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK, CLIENT_VERSION); + ssValue >> value; + success = true; + } catch (const std::exception&) { + // In this case success remains 'false' + } + + // Clear and free memory + memory_cleanse(datValue.get_data(), datValue.get_size()); + free(datValue.get_data()); } - - // Clear and free memory - memset(datValue.get_data(), 0, datValue.get_size()); - free(datValue.get_data()); - return (ret == 0); + return ret == 0 && success; } template @@ -168,8 +169,8 @@ class CDB 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()); + memory_cleanse(datKey.get_data(), datKey.get_size()); + memory_cleanse(datValue.get_data(), datValue.get_size()); return (ret == 0); } @@ -191,7 +192,7 @@ class CDB int ret = pdb->del(activeTxn, &datKey, 0); // Clear memory - memset(datKey.get_data(), 0, datKey.get_size()); + memory_cleanse(datKey.get_data(), datKey.get_size()); return (ret == 0 || ret == DB_NOTFOUND); } @@ -211,7 +212,7 @@ class CDB int ret = pdb->exists(activeTxn, &datKey, 0); // Clear memory - memset(datKey.get_data(), 0, datKey.get_size()); + memory_cleanse(datKey.get_data(), datKey.get_size()); return (ret == 0); } @@ -254,8 +255,8 @@ class CDB 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()); + memory_cleanse(datKey.get_data(), datKey.get_size()); + memory_cleanse(datValue.get_data(), datValue.get_size()); free(datKey.get_data()); free(datValue.get_data()); return 0; From 3a88f820ba6d18697737aa17427b60c79455b78b Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 17 May 2017 20:45:35 +0200 Subject: [PATCH 51/75] Merge #10414: [depends] miniupnpc 2.0.20170509 af5d48c [depends] miniupnpc 2.0.20170509 (fanquake) Tree-SHA512: e6cfa7856aa4ceb17de5e84156cdb90094eedfb08a84ba1cd9a5ce1689533e17863e3f5692a1b7b7b096a7ac88f18539e4b6b7a79f7726401effb11bf9a5ef2f --- depends/packages/miniupnpc.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/miniupnpc.mk b/depends/packages/miniupnpc.mk index e34cf7be2f1bf..1bb8cb5d26647 100644 --- a/depends/packages/miniupnpc.mk +++ b/depends/packages/miniupnpc.mk @@ -1,8 +1,8 @@ package=miniupnpc -$(package)_version=2.0 +$(package)_version=2.0.20170509 $(package)_download_path=http://miniupnp.free.fr/files $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=d434ceb8986efbe199c5ca53f90ed53eab290b1e6d0530b717eb6fa49d61f93b +$(package)_sha256_hash=d3c368627f5cdfb66d3ebd64ca39ba54d6ff14a61966dbecb8dd296b7039f16a define $(package)_set_vars $(package)_build_opts=CC="$($(package)_cc)" From 9d7cc1178b2ba61df09d14d56c211c5e12082a17 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 17 May 2017 13:17:28 -0700 Subject: [PATCH 52/75] Merge #10196: Bugfix: PrioritiseTransaction updates the mempool tx counter 6c2e25c [qa] Test prioritise_transaction / getblocktemplate interaction (Suhas Daftuar) acc2e4b Bugfix: PrioritiseTransaction updates the mempool tx counter (Suhas Daftuar) Tree-SHA512: dcf834df52d84d5eb86acb847c3f28d3cffd1f78f3092b8ff8913c2c400675a071c48a19cd852fdbaac1582aa1dba23433e0e16055831ef2a5e76dde91199941 --- qa/rpc-tests/prioritise_transaction.py | 15 ++++++++++++++- src/txmempool.cpp | 1 + src/txmempool.h | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/prioritise_transaction.py b/qa/rpc-tests/prioritise_transaction.py index eaf56dfb48893..be24fc0928ea6 100755 --- a/qa/rpc-tests/prioritise_transaction.py +++ b/qa/rpc-tests/prioritise_transaction.py @@ -16,7 +16,7 @@ class PrioritiseTransactionTest(BitcoinTestFramework): def __init__(self): super().__init__() self.setup_clean_chain = True - self.num_nodes = 1 + self.num_nodes = 2 self.txouts = gen_return_txouts() @@ -25,6 +25,8 @@ def setup_network(self): self.is_network_split = False self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-printpriority=1"])) + self.nodes.append(start_node(1, self.options.tmpdir, ["-debug", "-printpriority=1"])) # TODO move this to extra_args when Bitcoin #10198 gets backported + connect_nodes(self.nodes[0], 1) # TODO remove this when Bitcoin #10198 gets backported self.relayfee = self.nodes[0].getnetworkinfo()['relayfee'] def run_test(self): @@ -139,5 +141,16 @@ def run_test(self): assert_equal(self.nodes[0].sendrawtransaction(tx2_hex), tx2_id) assert(tx2_id in self.nodes[0].getrawmempool()) + # Test that calling prioritisetransaction is sufficient to trigger + # getblocktemplate to (eventually) return a new block. + mock_time = int(time.time()) + self.nodes[0].setmocktime(mock_time) + template = self.nodes[0].getblocktemplate() + self.nodes[0].prioritisetransaction(tx_id, -int(self.relayfee*COIN)) + self.nodes[0].setmocktime(mock_time+10) + new_template = self.nodes[0].getblocktemplate() + + assert(template != new_template) + if __name__ == '__main__': PrioritiseTransactionTest().main() diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 07b132329d846..91fd8b13b45b0 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -1077,6 +1077,7 @@ void CTxMemPool::PrioritiseTransaction(const uint256 hash, const std::string str BOOST_FOREACH(txiter descendantIt, setDescendants) { mapTx.modify(descendantIt, update_ancestor_state(0, nFeeDelta, 0, 0)); } + ++nTransactionsUpdated; } } LogPrintf("PrioritiseTransaction: %s priority += %f, fee += %d\n", strHash, dPriorityDelta, FormatMoney(nFeeDelta)); diff --git a/src/txmempool.h b/src/txmempool.h index 7db30e42a0d2d..583091abc70b8 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -443,7 +443,7 @@ class CTxMemPool { private: uint32_t nCheckFrequency; //!< Value n means that n times in 2^32 we check. - unsigned int nTransactionsUpdated; + unsigned int nTransactionsUpdated; //!< Used by getblocktemplate to trigger CreateNewBlock() invocation CBlockPolicyEstimator* minerPolicyEstimator; uint64_t totalTxSize; //!< sum of all mempool tx' byte sizes From 61277349c185b88733c55287e5bd497c7fb8fbad Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 22 May 2017 12:49:44 +0200 Subject: [PATCH 53/75] Merge #10424: Populate services in GetLocalAddress 3070134 Populate services in GetLocalAddress (Alex Morcos) Tree-SHA512: b822d7e898ccb5b959ccb1b1d0f159f27190c2105fbf8f5b67ae54debab6fa6a0723d65a66e7341f55cd0d80398c3fbb39a41e067b9f4e0bfa2c1cd366032404 --- src/net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/net.cpp b/src/net.cpp index d649a1af961d7..976b5af673117 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -154,7 +154,7 @@ static std::vector convertSeed6(const std::vector &vSeedsIn // one by discovery. CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices) { - CAddress ret(CService(CNetAddr(),GetListenPort()), NODE_NONE); + CAddress ret(CService(CNetAddr(),GetListenPort()), nLocalServices); CService addr; if (GetLocal(addr, paddrPeer)) { From 4765fe318a5344321381db9c35a56c80d777676f Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 23 May 2017 16:38:19 +0200 Subject: [PATCH 54/75] Merge #10410: Fix importwallet edge case rescan bug 2a8e35a Fix importwallet edge case rescan bug (Russell Yanofsky) Tree-SHA512: 59522c962290f9ef64436349d11183dd1fd829e515d1f5ec802b63dd813d04303e28d4f3ba38df77a6c151ee4c14f3ca5d3d82204c57456ac94054de62ae4bc7 --- src/wallet/rpcdump.cpp | 9 ++--- src/wallet/test/wallet_tests.cpp | 62 ++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 6 deletions(-) diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 2dc9d11175ecb..f9aa0192fa867 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -503,15 +503,12 @@ UniValue importwallet(const JSONRPCRequest& request) } 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; - if (!pwalletMain->nTimeFirstKey || nTimeBegin < pwalletMain->nTimeFirstKey) pwalletMain->nTimeFirstKey = nTimeBegin; - LogPrintf("Rescanning last %i blocks\n", chainActive.Height() - pindex->nHeight + 1); + CBlockIndex *pindex = chainActive.FindEarliestAtLeast(nTimeBegin - 7200); + + LogPrintf("Rescanning last %i blocks\n", pindex ? chainActive.Height() - pindex->nHeight + 1 : 0); pwalletMain->ScanForWalletTransactions(pindex); pwalletMain->MarkDirty(); diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 7db06817a3709..4c4dac2f56edf 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -19,6 +19,8 @@ #include extern UniValue importmulti(const JSONRPCRequest& request); +extern UniValue dumpwallet(const JSONRPCRequest& request); +extern UniValue importwallet(const JSONRPCRequest& request); // how many times to run all the tests to have a chance to catch errors that only show up with particular random shuffles #define RUN_TESTS 100 @@ -428,4 +430,64 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup) } } +// Verify importwallet RPC starts rescan at earliest block with timestamp +// greater or equal than key birthday. Previously there was a bug where +// importwallet RPC would start the scan at the latest block with timestamp less +// than or equal to key birthday. +BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup) +{ + CWallet *pwalletMainBackup = ::pwalletMain; + LOCK(cs_main); + + // Create two blocks with same timestamp to verify that importwallet rescan + // will pick up both blocks, not just the first. + const int64_t BLOCK_TIME = chainActive.Tip()->GetBlockTimeMax() + 5; + SetMockTime(BLOCK_TIME); + coinbaseTxns.emplace_back(*CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]); + coinbaseTxns.emplace_back(*CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]); + + // Set key birthday to block time increased by the timestamp window, so + // rescan will start at the block time. + const int64_t KEY_TIME = BLOCK_TIME + TIMESTAMP_WINDOW; + SetMockTime(KEY_TIME); + coinbaseTxns.emplace_back(*CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]); + + // Import key into wallet and call dumpwallet to create backup file. + { + CWallet wallet; + LOCK(wallet.cs_wallet); + wallet.mapKeyMetadata[coinbaseKey.GetPubKey().GetID()].nCreateTime = KEY_TIME; + wallet.AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()); + + JSONRPCRequest request; + request.params.setArray(); + request.params.push_back("wallet.backup"); + ::pwalletMain = &wallet; + ::dumpwallet(request); + } + + // Call importwallet RPC and verify all blocks with timestamps >= BLOCK_TIME + // were scanned, and no prior blocks were scanned. + { + CWallet wallet; + + JSONRPCRequest request; + request.params.setArray(); + request.params.push_back("wallet.backup"); + ::pwalletMain = &wallet; + ::importwallet(request); + + BOOST_CHECK_EQUAL(wallet.mapWallet.size(), 3); + BOOST_CHECK_EQUAL(coinbaseTxns.size(), 103); + for (size_t i = 0; i < coinbaseTxns.size(); ++i) { + bool found = wallet.GetWalletTx(coinbaseTxns[i].GetHash()); + bool expected = i >= 100; + BOOST_CHECK_EQUAL(found, expected); + } + } + + SetMockTime(0); + ::pwalletMain = pwalletMainBackup; +} + BOOST_AUTO_TEST_SUITE_END() From dcddd69d2943113462b9a50a85eeac8d55690b42 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 1 Jun 2017 12:59:05 +0200 Subject: [PATCH 55/75] Merge #10495: contrib: Update location of seeds.txt ac9cd95 contrib: Update location of seeds.txt (Wladimir J. van der Laan) Tree-SHA512: c12a75787ba87f03707c21731da083b466762a7e0af9ca501107695ea1074025907cc24805c7c87f4a66daa7f4f13e574da16be1681e61deaf1acbd72176b3ff --- contrib/seeds/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/seeds/README.md b/contrib/seeds/README.md index afe902fd7f063..139c03181fc80 100644 --- a/contrib/seeds/README.md +++ b/contrib/seeds/README.md @@ -8,7 +8,7 @@ and remove old versions as necessary. The seeds compiled into the release are created from sipa's DNS seed data, like this: - curl -s http://bitcoin.sipa.be/seeds.txt > seeds_main.txt + curl -s http://bitcoin.sipa.be/seeds.txt.gz | gzip -dc > seeds_main.txt python3 makeseeds.py < seeds_main.txt > nodes_main.txt python3 generate-seeds.py . > ../../src/chainparamsseeds.h From bf4ac85fc65878807ef7eb49c07c1113c6b8b401 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 1 Jun 2017 13:20:56 +0200 Subject: [PATCH 56/75] Merge #10441: net: only enforce expected services for half of outgoing connections b6fbfc2 net: only enforce the services required to connect (Cory Fields) Tree-SHA512: 88943bff63213a734f3c96c45760cadaeb9ba18287c8a20c279851ebaf058a334c969028fb2180f155508e3eea4b838147382e4f2b655e7a9aa098eadc81d53e --- src/net.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/net.cpp b/src/net.cpp index 976b5af673117..b11060f165a57 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1721,11 +1721,17 @@ void CConnman::ThreadOpenConnections() // Do this here so we don't have to critsect vNodes inside mapAddresses critsect. // This is only done for mainnet and testnet int nOutbound = 0; + int nOutboundRelevant = 0; std::set > setConnected; if (!Params().AllowMultipleAddressesFromGroup()) { LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) { if (!pnode->fInbound && !pnode->fAddnode && !pnode->fMasternode) { + + // Count the peers that have all relevant services + if (pnode->fSuccessfullyConnected && !pnode->fFeeler && ((pnode->nServices & nRelevantServices) == nRelevantServices)) { + nOutboundRelevant++; + } // 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 @@ -1789,14 +1795,27 @@ void CConnman::ThreadOpenConnections() 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))) + ServiceFlags nRequiredServices = nRelevantServices; + if (nTries >= 40 && nOutbound < (nMaxOutbound >> 1)) { + nRequiredServices = REQUIRED_SERVICES; + } + + if ((addr.nServices & nRequiredServices) != nRequiredServices) { continue; + } // do not allow non-default ports, unless after 50 invalid addresses selected already if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50) continue; addrConnect = addr; + + // regardless of the services assumed to be available, only require the minimum if half or more outbound have relevant services + if (nOutboundRelevant >= (nMaxOutbound >> 1)) { + addrConnect.nServices = REQUIRED_SERVICES; + } else { + addrConnect.nServices = nRequiredServices; + } break; } From e0ac0e4b127033df95138e94585072a62665899d Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 1 Jun 2017 15:04:25 +0200 Subject: [PATCH 57/75] Merge #10451: contrib/init/bitcoind.openrcconf: Don't disable wallet by default afc693d contrib/init/bitcoind.openrcconf: Don't disable wallet by default (Luke Dashjr) Tree-SHA512: 1763a9e91788485b079b96239cf09f1557b338e5045aa4ffbad3908f88c4e362b9b5d86a8a0f33734899de244e76e7ced02a6be8e52b3fb69258a5101d6445ef --- contrib/init/absoluted.openrcconf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/init/absoluted.openrcconf b/contrib/init/absoluted.openrcconf index b8fa6328d7911..fac3a28645a3b 100644 --- a/contrib/init/absoluted.openrcconf +++ b/contrib/init/absoluted.openrcconf @@ -23,7 +23,7 @@ #BITCOIND_NICE=0 # Additional options (avoid -conf and -datadir, use flags above) -BITCOIND_OPTS="-disablewallet" +#BITCOIND_OPTS="" # The timeout in seconds OpenRC will wait for bitcoind to terminate # after a SIGTERM has been raised. From f49c75c6137613516edfa4f22f8325b7db6ae931 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Thu, 25 Jan 2018 18:16:40 +0100 Subject: [PATCH 58/75] Only consider nodes missing relevant services after 40 failed attemps --- src/net.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index b11060f165a57..526c356ed7d84 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1794,15 +1794,9 @@ void CConnman::ThreadOpenConnections() 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. - ServiceFlags nRequiredServices = nRelevantServices; - if (nTries >= 40 && nOutbound < (nMaxOutbound >> 1)) { - nRequiredServices = REQUIRED_SERVICES; - } - - if ((addr.nServices & nRequiredServices) != nRequiredServices) { + // only consider nodes missing relevant services after 40 failed attempts + if ((addr.nServices & nRelevantServices) != nRelevantServices && nTries < 40) continue; - } // do not allow non-default ports, unless after 50 invalid addresses selected already if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50) From 2cb829eef378531cfb3831b704c7e5e0174ae654 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Thu, 25 Jan 2018 20:09:12 +0100 Subject: [PATCH 59/75] Use nBlockSize/nBlockMaxSize instead of nBlockWeight/nBlockMaxWeight --- src/miner.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index fef4bfa12b008..298b250fe4a2a 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -453,8 +453,7 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda ++nConsecutiveFailed; - if (nConsecutiveFailed > MAX_CONSECUTIVE_FAILURES && nBlockWeight > - nBlockMaxWeight - 4000) { + if (nConsecutiveFailed > MAX_CONSECUTIVE_FAILURES && nBlockSize > nBlockMaxSize - 4000) { // Give up if we're close to full and haven't succeeded in a while break; } From 9c6f746bb2cac84da1aefd69354be98d485f5ebb Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Wed, 27 Feb 2019 20:12:45 +0000 Subject: [PATCH 60/75] Include test_absolute.h instead of test_bitcoin.h --- src/test/checkqueue_tests.cpp | 7 +++---- src/wallet/test/wallet_tests.cpp | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/test/checkqueue_tests.cpp b/src/test/checkqueue_tests.cpp index d89f9b770bce3..cb84ea6185662 100644 --- a/src/test/checkqueue_tests.cpp +++ b/src/test/checkqueue_tests.cpp @@ -6,7 +6,7 @@ #include "utiltime.h" #include "validation.h" -#include "test/test_bitcoin.h" +#include "test/test_absolute.h" #include "checkqueue.h" #include #include @@ -96,7 +96,7 @@ struct MemoryCheck { }; ~MemoryCheck(){ fake_allocated_memory -= b; - + }; void swap(MemoryCheck& x) { std::swap(b, x.b); }; }; @@ -337,7 +337,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_Memory) tg.join_all(); } -// Test that a new verification cannot occur until all checks +// Test that a new verification cannot occur until all checks // have been destructed BOOST_AUTO_TEST_CASE(test_CheckQueue_FrozenCleanup) { @@ -439,4 +439,3 @@ BOOST_AUTO_TEST_CASE(test_CheckQueueControl_Locks) } } BOOST_AUTO_TEST_SUITE_END() - diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 4c4dac2f56edf..d7b3a8d0b40e0 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -10,7 +10,7 @@ #include #include "rpc/server.h" -#include "test/test_bitcoin.h" +#include "test/test_absolute.h" #include "validation.h" #include "wallet/test/wallet_test_fixture.h" From 3a5181a99f0f6b7621e133a967f6c9198f190cb9 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Thu, 25 Jan 2018 20:24:40 +0100 Subject: [PATCH 61/75] Use constant 7200 instead of TIMESTAMP_WINDOW for now Until Bitcoin #9908 gets backported --- src/wallet/test/wallet_tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index d7b3a8d0b40e0..62e24dd28382c 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -448,7 +448,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup) // Set key birthday to block time increased by the timestamp window, so // rescan will start at the block time. - const int64_t KEY_TIME = BLOCK_TIME + TIMESTAMP_WINDOW; + const int64_t KEY_TIME = BLOCK_TIME + 7200; SetMockTime(KEY_TIME); coinbaseTxns.emplace_back(*CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]); From 94850edd76d06691e7dd0bd74f20dd9fe3647c82 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Thu, 25 Jan 2018 22:07:35 +0100 Subject: [PATCH 62/75] Fix rpc tests --- qa/rpc-tests/fundrawtransaction.py | 2 +- qa/rpc-tests/prioritise_transaction.py | 2 +- src/wallet/test/wallet_tests.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index 44762faa7008a..229c454825bc7 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -52,7 +52,7 @@ def run_test(self): self.sync_all() # ensure that setting changePosition in fundraw with an exact match is handled properly - rawmatch = self.nodes[2].createrawtransaction([], {self.nodes[2].getnewaddress():50}) + rawmatch = self.nodes[2].createrawtransaction([], {self.nodes[2].getnewaddress():500}) rawmatch = self.nodes[2].fundrawtransaction(rawmatch, {"changePosition":1, "subtractFeeFromOutputs":[0]}) assert_equal(rawmatch["changepos"], -1) diff --git a/qa/rpc-tests/prioritise_transaction.py b/qa/rpc-tests/prioritise_transaction.py index be24fc0928ea6..de60fd3ddea07 100755 --- a/qa/rpc-tests/prioritise_transaction.py +++ b/qa/rpc-tests/prioritise_transaction.py @@ -146,7 +146,7 @@ def run_test(self): mock_time = int(time.time()) self.nodes[0].setmocktime(mock_time) template = self.nodes[0].getblocktemplate() - self.nodes[0].prioritisetransaction(tx_id, -int(self.relayfee*COIN)) + self.nodes[0].prioritisetransaction(tx2_id, 0, -int(self.relayfee*COIN)) self.nodes[0].setmocktime(mock_time+10) new_template = self.nodes[0].getblocktemplate() diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 62e24dd28382c..8dbc2edb68ee2 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -380,7 +380,7 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup) LOCK(wallet.cs_wallet); wallet.AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()); BOOST_CHECK_EQUAL(oldTip, wallet.ScanForWalletTransactions(oldTip)); - BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 100 * COIN); + BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 1000 * COIN); } // Prune the older block file. @@ -394,7 +394,7 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup) LOCK(wallet.cs_wallet); wallet.AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()); BOOST_CHECK_EQUAL(newTip, wallet.ScanForWalletTransactions(oldTip)); - BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 50 * COIN); + BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 500 * COIN); } // Verify importmulti RPC returns failure for a key whose creation time is From 2d04791f1825515ecef48a2b9031f7f6439c05c3 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Fri, 26 Jan 2018 08:54:46 +0100 Subject: [PATCH 63/75] Fix formatting of help in sendfrom --- src/wallet/rpcwallet.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 6d57a9f698093..b40dd10b01c14 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -882,19 +882,19 @@ UniValue sendfrom(const JSONRPCRequest& request) "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a absolute 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" + "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 absolute 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. addlockconf (bool, optional, default=false) Whether to add " + std::to_string(nInstantSendDepth) + " confirmations to transactions locked via InstantSend.\n" - "6. \"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" + "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. addlockconf (bool, optional, default=false) Whether to add " + std::to_string(nInstantSendDepth) + " confirmations to transactions locked via InstantSend.\n" + "6. \"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" "7. \"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" + " 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" From 1e028a9ef5a9527a562ce4d703320a0f6b674b9c Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Wed, 27 Feb 2019 20:18:27 +0000 Subject: [PATCH 64/75] Fix new absolute-tx tests Also use S flag instead of W flag for the outpubkey test. Not really needed to fix the test, but we don't have the flag in Absolute so lets not confuse people. --- src/test/data/bitcoin-util-test.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/data/bitcoin-util-test.json b/src/test/data/bitcoin-util-test.json index af1be024046b7..1ad0682e9332c 100644 --- a/src/test/data/bitcoin-util-test.json +++ b/src/test/data/bitcoin-util-test.json @@ -84,15 +84,15 @@ "error_txt": "error: TX output missing or too many separators", "description": "Malformed outaddr argument (no address specified). Expected to fail." }, - { "exec": "./bitcoin-tx", + { "exec": "./absolute-tx", "args": ["-create", - "outaddr=1:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o:garbage"], + "outaddr=1:ALCJFVbESDjkeHxQcAGDowEftPprjr7XmQ:garbage"], "return_code": 1, "error_txt": "error: TX output missing or too many separators", "description": "Malformed outaddr argument (too many separators). Expected to fail." }, - { "exec": "./bitcoin-tx", + { "exec": "./absolute-tx", "args": ["-create", "outpubkey=0"], @@ -100,15 +100,15 @@ "error_txt": "error: TX output missing or too many separators", "description": "Malformed outpubkey argument (no pubkey specified). Expected to fail." }, - { "exec": "./bitcoin-tx", + { "exec": "./absolute-tx", "args": ["-create", - "outpubkey=0:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397:W:non53nse"], + "outpubkey=0:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397:S:non53nse"], "return_code": 1, "error_txt": "error: TX output missing or too many separators", "description": "Malformed outpubkey argument (too many separators). Expected to fail." }, - { "exec": "./bitcoin-tx", + { "exec": "./absolute-tx", "args": ["-create", "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", From b247c3b50508be4225eab2d07131b570074eb071 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Fri, 26 Jan 2018 17:31:20 +0100 Subject: [PATCH 65/75] Give 1000 bytes instead of 4000 bytes before the block is full --- src/miner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/miner.cpp b/src/miner.cpp index 298b250fe4a2a..2272e1a94d483 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -453,7 +453,7 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda ++nConsecutiveFailed; - if (nConsecutiveFailed > MAX_CONSECUTIVE_FAILURES && nBlockSize > nBlockMaxSize - 4000) { + if (nConsecutiveFailed > MAX_CONSECUTIVE_FAILURES && nBlockSize > nBlockMaxSize - 1000) { // Give up if we're close to full and haven't succeeded in a while break; } From 61d35557482e892b52e4847e6f89950971d2300e Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Mon, 29 Jan 2018 11:16:05 +0100 Subject: [PATCH 66/75] Replace more example Absolute addresses with invalid addresses --- src/wallet/rpcwallet.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index b40dd10b01c14..23f9628bc5a4f 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1096,9 +1096,9 @@ UniValue addmultisigaddress(const JSONRPCRequest& request) "\nExamples:\n" "\nAdd a multisig address from 2 addresses\n" - + HelpExampleCli("addmultisigaddress", "2 \"[\\\"Xt4qk9uKvQYAonVGSZNXqxeDmtjaEWgfrs\\\",\\\"XoSoWQkpgLpppPoyyzbUFh1fq2RBvW6UK1\\\"]\"") + + + HelpExampleCli("addmultisigaddress", "2 \"[\\\"ALCJFVbESDjkeHxQcAGDowEftPprjr7XmQ\\\",\\\"AUJpTLhPKBTxRessG5X6FjXy4To7TFmB2M\\\"]\"") + "\nAs json rpc call\n" - + HelpExampleRpc("addmultisigaddress", "2, \"[\\\"Xt4qk9uKvQYAonVGSZNXqxeDmtjaEWgfrs\\\",\\\"XoSoWQkpgLpppPoyyzbUFh1fq2RBvW6UK1\\\"]\"") + + HelpExampleRpc("addmultisigaddress", "2, \"[\\\"ALCJFVbESDjkeHxQcAGDowEftPprjr7XmQ\\\",\\\"AUJpTLhPKBTxRessG5X6FjXy4To7TFmB2M\\\"]\"") ; throw runtime_error(msg); } From 180d5f9999fdc0ddfbc6cefa9f25a61d7e07721a Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Fri, 26 Jan 2018 04:11:01 +0300 Subject: [PATCH 67/75] Rename `fMasterNode` to `fMasternodeMode` --- src/activemasternode.cpp | 2 +- src/governance.cpp | 2 +- src/init.cpp | 10 +++++----- src/instantx.cpp | 2 +- src/masternode-payments.cpp | 4 ++-- src/masternode-sync.cpp | 2 +- src/masternode.cpp | 8 ++++---- src/masternodeman.cpp | 8 ++++---- src/net.cpp | 2 +- src/privatesend-client.cpp | 24 ++++++++++++------------ src/privatesend-server.cpp | 28 ++++++++++++++-------------- src/privatesend.cpp | 6 +++--- src/qt/overviewpage.cpp | 2 +- src/rpc/masternode.cpp | 8 ++++---- src/util.cpp | 2 +- src/util.h | 2 +- src/wallet/wallet.cpp | 4 ++-- 17 files changed, 58 insertions(+), 58 deletions(-) diff --git a/src/activemasternode.cpp b/src/activemasternode.cpp index cf99860817bd7..2ba67333a83aa 100644 --- a/src/activemasternode.cpp +++ b/src/activemasternode.cpp @@ -15,7 +15,7 @@ CActiveMasternode activeMasternode; void CActiveMasternode::ManageState(CConnman& connman) { LogPrint("masternode", "CActiveMasternode::ManageState -- Start\n"); - if(!fMasterNode) { + if(!fMasternodeMode) { LogPrint("masternode", "CActiveMasternode::ManageState -- Not a masternode, returning\n"); return; } diff --git a/src/governance.cpp b/src/governance.cpp index 846e89b849244..a8ae377acf9fa 100644 --- a/src/governance.cpp +++ b/src/governance.cpp @@ -1219,7 +1219,7 @@ int CGovernanceManager::RequestGovernanceObjectVotes(const std::vector& // they stay connected for a short period of time and it's possible that we won't get everything we should. // Only use outbound connections - inbound connection could be a "masternode" connection // initiated from another node, so skip it too. - if(pnode->fMasternode || (fMasterNode && pnode->fInbound)) continue; + if(pnode->fMasternode || (fMasternodeMode && pnode->fInbound)) continue; // only use up to date peers if(pnode->nVersion < MIN_GOVERNANCE_PEER_PROTO_VERSION) continue; // stop early to prevent setAskFor overflow diff --git a/src/init.cpp b/src/init.cpp index 79cc5b58c74ba..b885c83247d44 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1737,15 +1737,15 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) } // ********************************************************* Step 11a: setup PrivateSend - fMasterNode = GetBoolArg("-masternode", false); + fMasternodeMode = GetBoolArg("-masternode", false); // TODO: masternode should have no wallet - if((fMasterNode || masternodeConfig.getCount() > -1) && fTxIndex == false) { + if((fMasternodeMode || masternodeConfig.getCount() > -1) && fTxIndex == false) { return InitError("Enabling Masternode support requires turning on transaction indexing." "Please add txindex=1 to your configuration and start with -reindex"); } - if(fMasterNode) { + if(fMasternodeMode) { LogPrintf("MASTERNODE:\n"); std::string strMasterNodePrivKey = GetArg("-masternodeprivkey", ""); @@ -1799,7 +1799,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) //lite mode disables all Masternode and Darksend related functionality fLiteMode = GetBoolArg("-litemode", false); - if(fMasterNode && fLiteMode){ + if(fMasternodeMode && fLiteMode){ return InitError("You can not start a masternode in litemode"); } @@ -1862,7 +1862,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) // ********************************************************* Step 11d: start absolute-ps- threads threadGroup.create_thread(boost::bind(&ThreadCheckPrivateSend, boost::ref(*g_connman))); - if (fMasterNode) + if (fMasternodeMode) threadGroup.create_thread(boost::bind(&ThreadCheckPrivateSendServer, boost::ref(*g_connman))); #ifdef ENABLE_WALLET else diff --git a/src/instantx.cpp b/src/instantx.cpp index 01f56ef5f898a..59a6d5f9ff6ff 100644 --- a/src/instantx.cpp +++ b/src/instantx.cpp @@ -194,7 +194,7 @@ void CInstantSend::Vote(const uint256& txHash, CConnman& connman) void CInstantSend::Vote(CTxLockCandidate& txLockCandidate, CConnman& connman) { - if(!fMasterNode) return; + if(!fMasternodeMode) return; if(!sporkManager.IsSporkActive(SPORK_2_INSTANTSEND_ENABLED)) return; LOCK2(cs_main, cs_instantsend); diff --git a/src/masternode-payments.cpp b/src/masternode-payments.cpp index c3104f53a642e..5345787f202fc 100644 --- a/src/masternode-payments.cpp +++ b/src/masternode-payments.cpp @@ -686,7 +686,7 @@ bool CMasternodePaymentVote::IsValid(CNode* pnode, int nValidationHeight, std::s // Only masternodes should try to check masternode rank for old votes - they need to pick the right winner for future blocks. // Regular clients (miners included) need to verify masternode rank for future block votes only. - if(!fMasterNode && nBlockHeight < nValidationHeight) return true; + if(!fMasternodeMode && nBlockHeight < nValidationHeight) return true; int nRank; @@ -717,7 +717,7 @@ bool CMasternodePayments::ProcessBlock(int nBlockHeight, CConnman& connman) { // DETERMINE IF WE SHOULD BE VOTING FOR THE NEXT PAYEE - if(fLiteMode || !fMasterNode) return false; + if(fLiteMode || !fMasternodeMode) return false; // We have little chances to pick the right winner if winners list is out of sync // but we have no choice, so we'll try. However it doesn't make sense to even try to do so diff --git a/src/masternode-sync.cpp b/src/masternode-sync.cpp index b9d3292999236..eb53f1dea557a 100644 --- a/src/masternode-sync.cpp +++ b/src/masternode-sync.cpp @@ -202,7 +202,7 @@ void CMasternodeSync::ProcessTick(CConnman& connman) // they are temporary and should be considered unreliable for a sync process. // Inbound connection this early is most likely a "masternode" connection // initiated from another node, so skip it too. - if(pnode->fMasternode || (fMasterNode && pnode->fInbound)) continue; + if(pnode->fMasternode || (fMasternodeMode && pnode->fInbound)) continue; // QUICK MODE (REGTEST ONLY!) if(Params().NetworkIDString() == CBaseChainParams::REGTEST) diff --git a/src/masternode.cpp b/src/masternode.cpp index 3dc87732026bb..d536a4fa579e3 100644 --- a/src/masternode.cpp +++ b/src/masternode.cpp @@ -74,7 +74,7 @@ bool CMasternode::UpdateFromNewBroadcast(CMasternodeBroadcast& mnb, CConnman& co mnodeman.mapSeenMasternodePing.insert(std::make_pair(lastPing.GetHash(), lastPing)); } // if it matches our Masternode privkey... - if(fMasterNode && pubKeyMasternode == activeMasternode.pubKeyMasternode) { + if(fMasternodeMode && pubKeyMasternode == activeMasternode.pubKeyMasternode) { nPoSeBanScore = -MASTERNODE_POSE_BAN_MAX_SCORE; if(nProtocolVersion == PROTOCOL_VERSION) { // ... and PROTOCOL_VERSION, then we've been remotely activated ... @@ -173,7 +173,7 @@ void CMasternode::Check(bool fForce) } int nActiveStatePrev = nActiveState; - bool fOurMasternode = fMasterNode && activeMasternode.pubKeyMasternode == pubKeyMasternode; + bool fOurMasternode = fMasternodeMode && activeMasternode.pubKeyMasternode == pubKeyMasternode; // masternode doesn't meet payment protocol requirements ... bool fRequireUpdate = nProtocolVersion < mnpayments.GetMinMasternodePaymentsProto() || @@ -510,7 +510,7 @@ bool CMasternodeBroadcast::Update(CMasternode* pmn, int& nDos, CConnman& connman } // if ther was no masternode broadcast recently or if it matches our Masternode privkey... - if(!pmn->IsBroadcastedWithin(MASTERNODE_MIN_MNB_SECONDS) || (fMasterNode && pubKeyMasternode == activeMasternode.pubKeyMasternode)) { + if(!pmn->IsBroadcastedWithin(MASTERNODE_MIN_MNB_SECONDS) || (fMasternodeMode && pubKeyMasternode == activeMasternode.pubKeyMasternode)) { // take the newest entry LogPrintf("CMasternodeBroadcast::Update -- Got UPDATED Masternode entry: addr=%s\n", addr.ToString()); if(pmn->UpdateFromNewBroadcast(*this, connman)) { @@ -527,7 +527,7 @@ bool CMasternodeBroadcast::CheckOutpoint(int& nDos) { // we are a masternode with the same vin (i.e. already activated) and this mnb is ours (matches our Masternode privkey) // so nothing to do here for us - if(fMasterNode && vin.prevout == activeMasternode.outpoint && pubKeyMasternode == activeMasternode.pubKeyMasternode) { + if(fMasternodeMode && vin.prevout == activeMasternode.outpoint && pubKeyMasternode == activeMasternode.pubKeyMasternode) { return false; } diff --git a/src/masternodeman.cpp b/src/masternodeman.cpp index 6951a25f71ec5..52ec605fcea06 100644 --- a/src/masternodeman.cpp +++ b/src/masternodeman.cpp @@ -1073,7 +1073,7 @@ bool CMasternodeMan::SendVerifyRequest(const CAddress& addr, const std::vector= nTimeout*1000 + nLagTime; @@ -362,7 +362,7 @@ void CPrivateSendClient::CheckTimeout() // bool CPrivateSendClient::SendDenominate(const std::vector& vecTxDSIn, const std::vector& vecTxOut, CConnman& connman) { - if(fMasterNode) { + if(fMasternodeMode) { LogPrintf("CPrivateSendClient::SendDenominate -- PrivateSend from a Masternode is not supported currently.\n"); return false; } @@ -442,7 +442,7 @@ bool CPrivateSendClient::SendDenominate(const std::vector& vecTxDSIn, c // Incoming message from Masternode updating the progress of mixing bool CPrivateSendClient::CheckPoolStateUpdate(PoolState nStateNew, int nEntriesCountNew, PoolStatusUpdate nStatusUpdate, PoolMessage nMessageID, int nSessionIDNew) { - if(fMasterNode) return false; + if(fMasternodeMode) return false; // do not update state when mixing client state is one of these if(nState == POOL_STATE_IDLE || nState == POOL_STATE_ERROR || nState == POOL_STATE_SUCCESS) return false; @@ -488,7 +488,7 @@ bool CPrivateSendClient::CheckPoolStateUpdate(PoolState nStateNew, int nEntriesC // bool CPrivateSendClient::SignFinalTransaction(const CTransaction& finalTransactionNew, CNode* pnode, CConnman& connman) { - if(fMasterNode || pnode == NULL) return false; + if(fMasternodeMode || pnode == NULL) return false; finalMutableTransaction = finalTransactionNew; LogPrintf("CPrivateSendClient::SignFinalTransaction -- finalMutableTransaction=%s", finalMutableTransaction.ToString()); @@ -588,7 +588,7 @@ bool CPrivateSendClient::SignFinalTransaction(const CTransaction& finalTransacti // mixing transaction was completed (failed or successful) void CPrivateSendClient::CompletedTransaction(PoolMessage nMessageID) { - if(fMasterNode) return; + if(fMasternodeMode) return; if(nMessageID == MSG_SUCCESS) { LogPrintf("CompletedTransaction -- success\n"); @@ -684,7 +684,7 @@ bool CPrivateSendClient::CheckAutomaticBackup() // bool CPrivateSendClient::DoAutomaticDenominating(CConnman& connman, bool fDryRun) { - if(fMasterNode) return false; // no client-side mixing on masternodes + if(fMasternodeMode) return false; // no client-side mixing on masternodes if(!fEnablePrivateSend) return false; if(!pwalletMain || pwalletMain->IsLocked(true)) return false; if(nState != POOL_STATE_IDLE) return false; @@ -1398,8 +1398,8 @@ void CPrivateSendClient::UpdatedBlockTip(const CBlockIndex *pindex) //TODO: Rename/move to core void ThreadCheckPrivateSendClient(CConnman& connman) { - if(fLiteMode) return; // disable all Absolute specific functionality - if(fMasterNode) return; // no client-side mixing on masternodes + if(fLiteMode) return; // disable all absolute specific functionality + if(fMasternodeMode) return; // no client-side mixing on masternodes static bool fOneThread; if(fOneThread) return; diff --git a/src/privatesend-server.cpp b/src/privatesend-server.cpp index 536a887171ec8..9374587200cb8 100644 --- a/src/privatesend-server.cpp +++ b/src/privatesend-server.cpp @@ -20,8 +20,8 @@ CPrivateSendServer privateSendServer; void CPrivateSendServer::ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman) { - if(!fMasterNode) return; - if(fLiteMode) return; // ignore all Absolute related functionality + if(!fMasternodeMode) return; + if(fLiteMode) return; // ignore all absolute related functionality if(!masternodeSync.IsBlockchainSynced()) return; if(strCommand == NetMsgType::DSACCEPT) { @@ -280,7 +280,7 @@ void CPrivateSendServer::SetNull() // void CPrivateSendServer::CheckPool(CConnman& connman) { - if(fMasterNode) { + if(fMasternodeMode) { LogPrint("privatesend", "CPrivateSendServer::CheckPool -- entries count %lu\n", GetEntriesCount()); // If entries are full, create finalized transaction @@ -333,7 +333,7 @@ void CPrivateSendServer::CreateFinalTransaction(CConnman& connman) void CPrivateSendServer::CommitFinalTransaction(CConnman& connman) { - if(!fMasterNode) return; // check and relay final tx only on masternode + if(!fMasternodeMode) return; // check and relay final tx only on masternode CTransactionRef finalTransaction = MakeTransactionRef(finalMutableTransaction); uint256 hashTx = finalTransaction->GetHash(); @@ -394,7 +394,7 @@ void CPrivateSendServer::CommitFinalTransaction(CConnman& connman) // void CPrivateSendServer::ChargeFees(CConnman& connman) { - if(!fMasterNode) return; + if(!fMasternodeMode) return; //we don't need to charge collateral for every offence. if(GetRandInt(100) > 33) return; @@ -471,7 +471,7 @@ void CPrivateSendServer::ChargeFees(CConnman& connman) */ void CPrivateSendServer::ChargeRandomFees(CConnman& connman) { - if(!fMasterNode) return; + if(!fMasternodeMode) return; LOCK(cs_main); @@ -499,9 +499,9 @@ void CPrivateSendServer::CheckTimeout(CConnman& connman) { CheckQueue(); - if(!fMasterNode) return; + if(!fMasternodeMode) return; - int nLagTime = fMasterNode ? 0 : 10000; // if we're the client, give the server a few extra seconds before resetting. + int nLagTime = fMasternodeMode ? 0 : 10000; // if we're the client, give the server a few extra seconds before resetting. int nTimeout = (nState == POOL_STATE_SIGNING) ? PRIVATESEND_SIGNING_TIMEOUT : PRIVATESEND_QUEUE_TIMEOUT; bool fTimeout = GetTimeMillis() - nTimeLastSuccessfulStep >= nTimeout*1000 + nLagTime; @@ -521,7 +521,7 @@ void CPrivateSendServer::CheckTimeout(CConnman& connman) */ void CPrivateSendServer::CheckForCompleteQueue(CConnman& connman) { - if(!fMasterNode) return; + if(!fMasternodeMode) return; if(nState == POOL_STATE_QUEUE && IsSessionReady()) { SetState(POOL_STATE_ACCEPTING_ENTRIES); @@ -581,7 +581,7 @@ bool CPrivateSendServer::IsInputScriptSigValid(const CTxIn& txin) // bool CPrivateSendServer::AddEntry(const CDarkSendEntry& entryNew, PoolMessage& nMessageIDRet) { - if(!fMasterNode) return false; + if(!fMasternodeMode) return false; BOOST_FOREACH(CTxIn txin, entryNew.vecTxDSIn) { if(txin.prevout.IsNull()) { @@ -687,7 +687,7 @@ bool CPrivateSendServer::IsOutputsCompatibleWithSessionDenom(const std::vector vecBits; @@ -709,7 +709,7 @@ bool CPrivateSendServer::IsAcceptableDenomAndCollateral(int nDenom, CTransaction bool CPrivateSendServer::CreateNewSession(int nDenom, CTransaction txCollateral, PoolMessage& nMessageIDRet, CConnman& connman) { - if(!fMasterNode || nSessionID != 0) return false; + if(!fMasternodeMode || nSessionID != 0) return false; // new session can only be started in idle mode if(nState != POOL_STATE_IDLE) { @@ -748,7 +748,7 @@ bool CPrivateSendServer::CreateNewSession(int nDenom, CTransaction txCollateral, bool CPrivateSendServer::AddUserToExistingSession(int nDenom, CTransaction txCollateral, PoolMessage& nMessageIDRet) { - if(!fMasterNode || nSessionID == 0 || IsSessionReady()) return false; + if(!fMasternodeMode || nSessionID == 0 || IsSessionReady()) return false; if(!IsAcceptableDenomAndCollateral(nDenom, txCollateral, nMessageIDRet)) { return false; @@ -865,7 +865,7 @@ void CPrivateSendServer::RelayCompletedTransaction(PoolMessage nMessageID, CConn void CPrivateSendServer::SetState(PoolState nStateNew) { - if(fMasterNode && (nStateNew == POOL_STATE_ERROR || nStateNew == POOL_STATE_SUCCESS)) { + if(fMasternodeMode && (nStateNew == POOL_STATE_ERROR || nStateNew == POOL_STATE_SUCCESS)) { LogPrint("privatesend", "CPrivateSendServer::SetState -- Can't set state to ERROR or SUCCESS as a Masternode. \n"); return; } diff --git a/src/privatesend.cpp b/src/privatesend.cpp index a586e6bd2d4b5..2da249131c5b8 100644 --- a/src/privatesend.cpp +++ b/src/privatesend.cpp @@ -39,7 +39,7 @@ bool CDarkSendEntry::AddScriptSig(const CTxIn& txin) bool CDarksendQueue::Sign() { - if(!fMasterNode) return false; + if(!fMasternodeMode) return false; std::string strMessage = vin.ToString() + boost::lexical_cast(nDenom) + boost::lexical_cast(nTime) + boost::lexical_cast(fReady); @@ -79,7 +79,7 @@ bool CDarksendQueue::Relay(CConnman& connman) bool CDarksendBroadcastTx::Sign() { - if(!fMasterNode) return false; + if(!fMasternodeMode) return false; std::string strMessage = tx->GetHash().ToString() + boost::lexical_cast(sigTime); @@ -467,7 +467,7 @@ void ThreadCheckPrivateSend(CConnman& connman) mnpayments.CheckAndRemove(); instantsend.CheckAndRemove(); } - if(fMasterNode && (nTick % (60 * 5) == 0)) { + if(fMasternodeMode && (nTick % (60 * 5) == 0)) { mnodeman.DoFullVerificationStep(connman); } diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 891695b2374fb..b33fb5c2c5e58 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -163,7 +163,7 @@ OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent) if(fLiteMode) return; // Disable any PS UI for masternode or when autobackup is disabled or failed for whatever reason - if(fMasterNode || nWalletBackups <= 0){ + if(fMasternodeMode || nWalletBackups <= 0){ DisablePrivateSendCompletely(); if (nWalletBackups <= 0) { ui->labelPrivateSendEnabled->setToolTip(tr("Automatic backups are disabled, no mixing available!")); diff --git a/src/rpc/masternode.cpp b/src/rpc/masternode.cpp index ee0a1818734d6..de2767c899d56 100644 --- a/src/rpc/masternode.cpp +++ b/src/rpc/masternode.cpp @@ -48,7 +48,7 @@ UniValue privatesend(const JSONRPCRequest& request) EnsureWalletIsUnlocked(); } - if(fMasterNode) + if(fMasternodeMode) return "Mixing is not supported from masternodes"; privateSendClient.fEnablePrivateSend = true; @@ -78,11 +78,11 @@ UniValue getpoolinfo(const JSONRPCRequest& request) "Returns an object containing mixing pool related information.\n"); #ifdef ENABLE_WALLET - CPrivateSendBase* pprivateSendBase = fMasterNode ? (CPrivateSendBase*)&privateSendServer : (CPrivateSendBase*)&privateSendClient; + CPrivateSendBase* pprivateSendBase = fMasternodeMode ? (CPrivateSendBase*)&privateSendServer : (CPrivateSendBase*)&privateSendClient; UniValue obj(UniValue::VOBJ); obj.push_back(Pair("state", pprivateSendBase->GetStateString())); - obj.push_back(Pair("mixing_mode", (!fMasterNode && privateSendClient.fPrivateSendMultiSession) ? "multi-session" : "normal")); + obj.push_back(Pair("mixing_mode", (!fMasternodeMode && privateSendClient.fPrivateSendMultiSession) ? "multi-session" : "normal")); obj.push_back(Pair("queue", pprivateSendBase->GetQueueSize())); obj.push_back(Pair("entries", pprivateSendBase->GetEntriesCount())); obj.push_back(Pair("status", privateSendClient.GetStatus())); @@ -391,7 +391,7 @@ UniValue masternode(const JSONRPCRequest& request) if (strCommand == "status") { - if (!fMasterNode) + if (!fMasternodeMode) throw JSONRPCError(RPC_INTERNAL_ERROR, "This is not a masternode"); UniValue mnObj(UniValue::VOBJ); diff --git a/src/util.cpp b/src/util.cpp index f25ce27fcfa11..2b4a64c4d06d7 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -110,7 +110,7 @@ namespace boost { using namespace std; //Absolute only features -bool fMasterNode = false; +bool fMasternodeMode = false; bool fLiteMode = false; /** nWalletBackups: diff --git a/src/util.h b/src/util.h index 05fc1bfbf11f8..ff51a0640c287 100644 --- a/src/util.h +++ b/src/util.h @@ -48,7 +48,7 @@ //Absolute only features -extern bool fMasterNode; +extern bool fMasternodeMode; extern bool fLiteMode; extern int nWalletBackups; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index f2169cd54ca80..79683adc839d8 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3067,7 +3067,7 @@ bool CWallet::SelectCoinsGrouppedByAddresses(std::vector& vecT if(fAnonymizable) { // ignore collaterals if(CPrivateSend::IsCollateralAmount(wtx.tx->vout[i].nValue)) continue; - if(fMasterNode && wtx.tx->vout[i].nValue == 1000*COIN) continue; + if(fMasternodeMode && wtx.tx->vout[i].nValue == 2500*COIN) continue; // ignore outputs that are 10 times smaller then the smallest denomination // otherwise they will just lead to higher fee / lower priority if(wtx.tx->vout[i].nValue <= nSmallestDenom/10) continue; @@ -3133,7 +3133,7 @@ bool CWallet::SelectCoinsDark(CAmount nValueMin, CAmount nValueMax, std::vector< if(out.tx->tx->vout[out.i].nValue < nValueMin/10) continue; //do not allow collaterals to be selected if(CPrivateSend::IsCollateralAmount(out.tx->tx->vout[out.i].nValue)) continue; - if(fMasterNode && out.tx->tx->vout[out.i].nValue == 1000*COIN) continue; //masternode input + if(fMasternodeMode && out.tx->tx->vout[out.i].nValue == 2500*COIN) continue; //masternode input if(nValueRet + out.tx->tx->vout[out.i].nValue <= nValueMax){ CTxIn txin = CTxIn(out.tx->GetHash(),out.i); From dd78ec785912c76ffa225fd276f0e1922494dc26 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Mon, 22 Jan 2018 14:17:11 +0100 Subject: [PATCH 68/75] Allow to filter for fully connected nodes when calling CopyNodeVector (#1864) And use this where needed. This avoids warnings about unset version fields and is also generally a good thing (we really should only communicate with nodes we know are good) --- src/governance.cpp | 2 +- src/masternode-sync.cpp | 4 ++-- src/masternodeman.cpp | 2 +- src/net.cpp | 9 ++++++++- src/net.h | 1 + src/privatesend-client.cpp | 4 ++-- src/privatesend.cpp | 2 +- 7 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/governance.cpp b/src/governance.cpp index a8ae377acf9fa..eef1e32e9c35a 100644 --- a/src/governance.cpp +++ b/src/governance.cpp @@ -1364,7 +1364,7 @@ void CGovernanceManager::UpdatedBlockTip(const CBlockIndex *pindex, CConnman& co void CGovernanceManager::RequestOrphanObjects(CConnman& connman) { - std::vector vNodesCopy = connman.CopyNodeVector(); + std::vector vNodesCopy = connman.CopyNodeVector(CConnman::FullyConnectedOnly); std::vector vecHashesFiltered; { diff --git a/src/masternode-sync.cpp b/src/masternode-sync.cpp index eb53f1dea557a..d9d4114235703 100644 --- a/src/masternode-sync.cpp +++ b/src/masternode-sync.cpp @@ -180,7 +180,7 @@ void CMasternodeSync::ProcessTick(CConnman& connman) // gradually request the rest of the votes after sync finished if(IsSynced()) { - std::vector vNodesCopy = connman.CopyNodeVector(); + std::vector vNodesCopy = connman.CopyNodeVector(CConnman::FullyConnectedOnly); governance.RequestGovernanceObjectVotes(vNodesCopy, connman); connman.ReleaseNodeVector(vNodesCopy); return; @@ -191,7 +191,7 @@ void CMasternodeSync::ProcessTick(CConnman& connman) LogPrintf("CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d nRequestedMasternodeAttempt %d nSyncProgress %f\n", nTick, nRequestedMasternodeAssets, nRequestedMasternodeAttempt, nSyncProgress); uiInterface.NotifyAdditionalDataSyncProgressChanged(nSyncProgress); - std::vector vNodesCopy = connman.CopyNodeVector(); + std::vector vNodesCopy = connman.CopyNodeVector(CConnman::FullyConnectedOnly); BOOST_FOREACH(CNode* pnode, vNodesCopy) { diff --git a/src/masternodeman.cpp b/src/masternodeman.cpp index 52ec605fcea06..eb25d232a39e2 100644 --- a/src/masternodeman.cpp +++ b/src/masternodeman.cpp @@ -1057,7 +1057,7 @@ bool CMasternodeMan::SendVerifyRequest(const CAddress& addr, const std::vectorGetSendVersion()); + CNetMsgMaker msgMaker(pnode->GetSendVersion()); // TODO this gives a warning about version not being set (we should wait for VERSION exchange) connman.PushMessage(pnode, msgMaker.Make(NetMsgType::MNVERIFY, mnv)); return true; diff --git a/src/net.cpp b/src/net.cpp index 03ba5431b609c..5985d8356b738 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2931,18 +2931,25 @@ 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); } -std::vector CConnman::CopyNodeVector() +std::vector CConnman::CopyNodeVector(std::function cond) { std::vector vecNodesCopy; LOCK(cs_vNodes); for(size_t i = 0; i < vNodes.size(); ++i) { CNode* pnode = vNodes[i]; + if (!cond(pnode)) + continue; pnode->AddRef(); vecNodesCopy.push_back(pnode); } return vecNodesCopy; } +std::vector CConnman::CopyNodeVector() +{ + return CopyNodeVector(AllNodes); +} + void CConnman::ReleaseNodeVector(const std::vector& vecNodes) { LOCK(cs_vNodes); diff --git a/src/net.h b/src/net.h index 44c3b4ccc3f91..fd334c086aeb8 100644 --- a/src/net.h +++ b/src/net.h @@ -303,6 +303,7 @@ class CConnman ForEachNodeThen(FullyConnectedOnly, pre, post); } + std::vector CopyNodeVector(std::function cond); std::vector CopyNodeVector(); void ReleaseNodeVector(const std::vector& vecNodes); diff --git a/src/privatesend-client.cpp b/src/privatesend-client.cpp index 9005a682fc732..dac2785cec127 100644 --- a/src/privatesend-client.cpp +++ b/src/privatesend-client.cpp @@ -890,7 +890,7 @@ bool CPrivateSendClient::JoinExistingQueue(CAmount nBalanceNeedsAnonymized, CCon infoMixingMasternode = infoMn; nSessionDenom = dsq.nDenom; - CNetMsgMaker msgMaker(pnode->GetSendVersion()); + CNetMsgMaker msgMaker(pnode->GetSendVersion()); // TODO this gives a warning about version not being set (we should wait for VERSION exchange) connman.PushMessage(pnode, msgMaker.Make(NetMsgType::DSACCEPT, nSessionDenom, txMyCollateral)); LogPrintf("CPrivateSendClient::JoinExistingQueue -- connected (from queue), sending DSACCEPT: nSessionDenom: %d (%s), addr=%s\n", nSessionDenom, CPrivateSend::GetDenominationsToString(nSessionDenom), pnode->addr.ToString()); @@ -964,7 +964,7 @@ bool CPrivateSendClient::StartNewQueue(CAmount nValueMin, CAmount nBalanceNeedsA nSessionDenom = CPrivateSend::GetDenominationsByAmounts(vecAmounts); } - CNetMsgMaker msgMaker(pnode->GetSendVersion()); + CNetMsgMaker msgMaker(pnode->GetSendVersion()); // TODO this gives a warning about version not being set (we should wait for VERSION exchange) connman.PushMessage(pnode, msgMaker.Make(NetMsgType::DSACCEPT, nSessionDenom, txMyCollateral)); LogPrintf("CPrivateSendClient::StartNewQueue -- connected, sending DSACCEPT, nSessionDenom: %d (%s)\n", nSessionDenom, CPrivateSend::GetDenominationsToString(nSessionDenom)); diff --git a/src/privatesend.cpp b/src/privatesend.cpp index 2da249131c5b8..bf34a802f31d3 100644 --- a/src/privatesend.cpp +++ b/src/privatesend.cpp @@ -66,7 +66,7 @@ bool CDarksendQueue::CheckSignature(const CPubKey& pubKeyMasternode) bool CDarksendQueue::Relay(CConnman& connman) { - std::vector vNodesCopy = connman.CopyNodeVector(); + std::vector vNodesCopy = connman.CopyNodeVector(CConnman::FullyConnectedOnly); BOOST_FOREACH(CNode* pnode, vNodesCopy) { CNetMsgMaker msgMaker(pnode->GetSendVersion()); if (pnode->nVersion >= MIN_PRIVATESEND_PEER_PROTO_VERSION) From 20f3f89ba2ac3919496cc156c2859cca58153d0d Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Wed, 27 Feb 2019 20:54:11 +0000 Subject: [PATCH 69/75] Add missed nRequiredServices --- src/net.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 5985d8356b738..11971cb38288a 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1794,9 +1794,15 @@ void CConnman::ThreadOpenConnections() if (nANow - addr.nLastTry < 600 && nTries < 30) continue; - // only consider nodes missing relevant services after 40 failed attempts - if ((addr.nServices & nRelevantServices) != nRelevantServices && nTries < 40) + // only consider nodes missing relevant services after 40 failed attempts and only if less than half the outbound are up. + ServiceFlags nRequiredServices = nRelevantServices; + if (nTries >= 40 && nOutbound < (nMaxOutbound >> 1)) { + nRequiredServices = REQUIRED_SERVICES; + } + + if ((addr.nServices & nRequiredServices) != nRequiredServices) { continue; + } // do not allow non-default ports, unless after 50 invalid addresses selected already if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50) From 7d13ab58761615668d050d63f933f301194b415e Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Fri, 26 Jan 2018 04:11:15 +0300 Subject: [PATCH 70/75] Introduce CDarksendAccept class (for DSACCEPT messages) (#1875) --- src/privatesend-client.cpp | 8 ++++---- src/privatesend-server.cpp | 41 +++++++++++++++++++------------------- src/privatesend-server.h | 6 +++--- src/privatesend.h | 25 +++++++++++++++++++++++ 4 files changed, 52 insertions(+), 28 deletions(-) diff --git a/src/privatesend-client.cpp b/src/privatesend-client.cpp index dac2785cec127..1e103463b5b4c 100644 --- a/src/privatesend-client.cpp +++ b/src/privatesend-client.cpp @@ -889,9 +889,9 @@ bool CPrivateSendClient::JoinExistingQueue(CAmount nBalanceNeedsAnonymized, CCon bool fSuccess = connman.ForNode(addr, CConnman::AllNodes, [&](CNode* pnode){ infoMixingMasternode = infoMn; nSessionDenom = dsq.nDenom; - + CDarksendAccept dsa(nSessionDenom, txMyCollateral); CNetMsgMaker msgMaker(pnode->GetSendVersion()); // TODO this gives a warning about version not being set (we should wait for VERSION exchange) - connman.PushMessage(pnode, msgMaker.Make(NetMsgType::DSACCEPT, nSessionDenom, txMyCollateral)); + connman.PushMessage(pnode, msgMaker.Make(NetMsgType::DSACCEPT, dsa)); LogPrintf("CPrivateSendClient::JoinExistingQueue -- connected (from queue), sending DSACCEPT: nSessionDenom: %d (%s), addr=%s\n", nSessionDenom, CPrivateSend::GetDenominationsToString(nSessionDenom), pnode->addr.ToString()); strAutoDenomResult = _("Mixing in progress..."); @@ -963,9 +963,9 @@ bool CPrivateSendClient::StartNewQueue(CAmount nValueMin, CAmount nBalanceNeedsA while(nSessionDenom == 0) { nSessionDenom = CPrivateSend::GetDenominationsByAmounts(vecAmounts); } - + CDarksendAccept dsa(nSessionDenom, txMyCollateral); CNetMsgMaker msgMaker(pnode->GetSendVersion()); // TODO this gives a warning about version not being set (we should wait for VERSION exchange) - connman.PushMessage(pnode, msgMaker.Make(NetMsgType::DSACCEPT, nSessionDenom, txMyCollateral)); + connman.PushMessage(pnode, msgMaker.Make(NetMsgType::DSACCEPT, dsa)); LogPrintf("CPrivateSendClient::StartNewQueue -- connected, sending DSACCEPT, nSessionDenom: %d (%s)\n", nSessionDenom, CPrivateSend::GetDenominationsToString(nSessionDenom)); strAutoDenomResult = _("Mixing in progress..."); diff --git a/src/privatesend-server.cpp b/src/privatesend-server.cpp index 9374587200cb8..025da879b4c28 100644 --- a/src/privatesend-server.cpp +++ b/src/privatesend-server.cpp @@ -39,11 +39,10 @@ void CPrivateSendServer::ProcessMessage(CNode* pfrom, const std::string& strComm return; } - int nDenom; - vRecv >> nDenom; - CTransaction txCollateral(deserialize, vRecv); + CDarksendAccept dsa; + vRecv >> dsa; - LogPrint("privatesend", "DSACCEPT -- nDenom %d (%s) txCollateral %s", nDenom, CPrivateSend::GetDenominationsToString(nDenom), txCollateral.ToString()); + LogPrint("privatesend", "DSACCEPT -- nDenom %d (%s) txCollateral %s", dsa.nDenom, CPrivateSend::GetDenominationsToString(dsa.nDenom), dsa.txCollateral.ToString()); masternode_info_t mnInfo; if(!mnodeman.GetMasternodeInfo(activeMasternode.outpoint, mnInfo)) { @@ -61,8 +60,8 @@ void CPrivateSendServer::ProcessMessage(CNode* pfrom, const std::string& strComm PoolMessage nMessageID = MSG_NOERR; - bool fResult = nSessionID == 0 ? CreateNewSession(nDenom, txCollateral, nMessageID, connman) - : AddUserToExistingSession(nDenom, txCollateral, nMessageID); + bool fResult = nSessionID == 0 ? CreateNewSession(dsa, nMessageID, connman) + : AddUserToExistingSession(dsa, nMessageID); if(fResult) { LogPrintf("DSACCEPT -- is compatible, please submit!\n"); PushStatus(pfrom, STATUS_ACCEPTED, nMessageID, connman); @@ -685,21 +684,21 @@ bool CPrivateSendServer::IsOutputsCompatibleWithSessionDenom(const std::vector vecBits; - if(!CPrivateSend::GetDenominationsBits(nDenom, vecBits)) { - LogPrint("privatesend", "CPrivateSendServer::IsAcceptableDenomAndCollateral -- denom not valid!\n"); + if(!CPrivateSend::GetDenominationsBits(dsa.nDenom, vecBits)) { + LogPrint("privatesend", "CPrivateSendServer::%s -- denom not valid!\n", __func__); nMessageIDRet = ERR_DENOM; return false; } // check collateral - if(!fUnitTest && !CPrivateSend::IsCollateralValid(txCollateral)) { - LogPrint("privatesend", "CPrivateSendServer::IsAcceptableDenomAndCollateral -- collateral not valid!\n"); + if(!fUnitTest && !CPrivateSend::IsCollateralValid(dsa.txCollateral)) { + LogPrint("privatesend", "CPrivateSendServer::%s -- collateral not valid!\n", __func__); nMessageIDRet = ERR_INVALID_COLLATERAL; return false; } @@ -707,7 +706,7 @@ bool CPrivateSendServer::IsAcceptableDenomAndCollateral(int nDenom, CTransaction return true; } -bool CPrivateSendServer::CreateNewSession(int nDenom, CTransaction txCollateral, PoolMessage& nMessageIDRet, CConnman& connman) +bool CPrivateSendServer::CreateNewSession(const CDarksendAccept& dsa, PoolMessage& nMessageIDRet, CConnman& connman) { if(!fMasternodeMode || nSessionID != 0) return false; @@ -718,39 +717,39 @@ bool CPrivateSendServer::CreateNewSession(int nDenom, CTransaction txCollateral, return false; } - if(!IsAcceptableDenomAndCollateral(nDenom, txCollateral, nMessageIDRet)) { + if(!IsAcceptableDSA(dsa, nMessageIDRet)) { return false; } // start new session nMessageIDRet = MSG_NOERR; nSessionID = GetRandInt(999999)+1; - nSessionDenom = nDenom; + nSessionDenom = dsa.nDenom; SetState(POOL_STATE_QUEUE); nTimeLastSuccessfulStep = GetTimeMillis(); if(!fUnitTest) { //broadcast that I'm accepting entries, only if it's the first entry through - CDarksendQueue dsq(nDenom, activeMasternode.outpoint, GetAdjustedTime(), false); + CDarksendQueue dsq(dsa.nDenom, activeMasternode.outpoint, GetAdjustedTime(), false); LogPrint("privatesend", "CPrivateSendServer::CreateNewSession -- signing and relaying new queue: %s\n", dsq.ToString()); dsq.Sign(); dsq.Relay(connman); vecDarksendQueue.push_back(dsq); } - vecSessionCollaterals.push_back(MakeTransactionRef(txCollateral)); + vecSessionCollaterals.push_back(MakeTransactionRef(dsa.txCollateral)); LogPrintf("CPrivateSendServer::CreateNewSession -- new session created, nSessionID: %d nSessionDenom: %d (%s) vecSessionCollaterals.size(): %d\n", nSessionID, nSessionDenom, CPrivateSend::GetDenominationsToString(nSessionDenom), vecSessionCollaterals.size()); return true; } -bool CPrivateSendServer::AddUserToExistingSession(int nDenom, CTransaction txCollateral, PoolMessage& nMessageIDRet) +bool CPrivateSendServer::AddUserToExistingSession(const CDarksendAccept& dsa, PoolMessage& nMessageIDRet) { if(!fMasternodeMode || nSessionID == 0 || IsSessionReady()) return false; - if(!IsAcceptableDenomAndCollateral(nDenom, txCollateral, nMessageIDRet)) { + if(!IsAcceptableDSA(dsa, nMessageIDRet)) { return false; } @@ -761,9 +760,9 @@ bool CPrivateSendServer::AddUserToExistingSession(int nDenom, CTransaction txCol return false; } - if(nDenom != nSessionDenom) { + if(dsa.nDenom != nSessionDenom) { LogPrintf("CPrivateSendServer::AddUserToExistingSession -- incompatible denom %d (%s) != nSessionDenom %d (%s)\n", - nDenom, CPrivateSend::GetDenominationsToString(nDenom), nSessionDenom, CPrivateSend::GetDenominationsToString(nSessionDenom)); + dsa.nDenom, CPrivateSend::GetDenominationsToString(dsa.nDenom), nSessionDenom, CPrivateSend::GetDenominationsToString(nSessionDenom)); nMessageIDRet = ERR_DENOM; return false; } @@ -772,7 +771,7 @@ bool CPrivateSendServer::AddUserToExistingSession(int nDenom, CTransaction txCol nMessageIDRet = MSG_NOERR; nTimeLastSuccessfulStep = GetTimeMillis(); - vecSessionCollaterals.push_back(MakeTransactionRef(txCollateral)); + vecSessionCollaterals.push_back(MakeTransactionRef(dsa.txCollateral)); LogPrintf("CPrivateSendServer::AddUserToExistingSession -- new user accepted, nSessionID: %d nSessionDenom: %d (%s) vecSessionCollaterals.size(): %d\n", nSessionID, nSessionDenom, CPrivateSend::GetDenominationsToString(nSessionDenom), vecSessionCollaterals.size()); diff --git a/src/privatesend-server.h b/src/privatesend-server.h index b23528c929522..aa9909fafca93 100644 --- a/src/privatesend-server.h +++ b/src/privatesend-server.h @@ -42,9 +42,9 @@ class CPrivateSendServer : public CPrivateSendBase void CommitFinalTransaction(CConnman& connman); /// Is this nDenom and txCollateral acceptable? - bool IsAcceptableDenomAndCollateral(int nDenom, CTransaction txCollateral, PoolMessage &nMessageIDRet); - bool CreateNewSession(int nDenom, CTransaction txCollateral, PoolMessage &nMessageIDRet, CConnman& connman); - bool AddUserToExistingSession(int nDenom, CTransaction txCollateral, PoolMessage &nMessageIDRet); + bool IsAcceptableDSA(const CDarksendAccept& dsa, PoolMessage &nMessageIDRet); + bool CreateNewSession(const CDarksendAccept& dsa, PoolMessage &nMessageIDRet, CConnman& connman); + bool AddUserToExistingSession(const CDarksendAccept& dsa, PoolMessage &nMessageIDRet); /// Do we have enough users to take entries? bool IsSessionReady() { return (int)vecSessionCollaterals.size() >= CPrivateSend::GetMaxPoolTransactions(); } diff --git a/src/privatesend.h b/src/privatesend.h index 9ed41f0d06156..7f189461f3e8c 100644 --- a/src/privatesend.h +++ b/src/privatesend.h @@ -99,6 +99,31 @@ class CTxDSIn : public CTxIn {} }; +class CDarksendAccept +{ +public: + int nDenom; + CMutableTransaction txCollateral; + + CDarksendAccept() : + nDenom(0), + txCollateral(CMutableTransaction()) + {}; + + CDarksendAccept(int nDenom, const CMutableTransaction& txCollateral) : + nDenom(nDenom), + txCollateral(txCollateral) + {}; + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action) { + READWRITE(nDenom); + READWRITE(txCollateral); + } +}; + // A clients transaction in the mixing pool class CDarkSendEntry { From c38663bbc62fdfdf94fdbdee06e55256b4aa015d Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Fri, 26 Jan 2018 04:11:30 +0300 Subject: [PATCH 71/75] No need for msgMakerInitProto for sporks because we loop by fully connected nodes only now (#1877) --- src/masternode-sync.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/masternode-sync.cpp b/src/masternode-sync.cpp index d9d4114235703..dd3aac625c014 100644 --- a/src/masternode-sync.cpp +++ b/src/masternode-sync.cpp @@ -196,7 +196,6 @@ void CMasternodeSync::ProcessTick(CConnman& connman) BOOST_FOREACH(CNode* pnode, vNodesCopy) { CNetMsgMaker msgMaker(pnode->GetSendVersion()); - CNetMsgMaker msgMakerInitProto(INIT_PROTO_VERSION); // Don't try to sync any data from outbound "masternode" connections - // they are temporary and should be considered unreliable for a sync process. @@ -208,7 +207,7 @@ void CMasternodeSync::ProcessTick(CConnman& connman) if(Params().NetworkIDString() == CBaseChainParams::REGTEST) { if(nRequestedMasternodeAttempt <= 2) { - connman.PushMessage(pnode, msgMakerInitProto.Make(NetMsgType::GETSPORKS)); //get current network sporks + connman.PushMessage(pnode, msgMaker.Make(NetMsgType::GETSPORKS)); //get current network sporks } else if(nRequestedMasternodeAttempt < 4) { mnodeman.DsegUpdate(pnode, connman); } else if(nRequestedMasternodeAttempt < 6) { @@ -239,7 +238,7 @@ void CMasternodeSync::ProcessTick(CConnman& connman) // always get sporks first, only request once from each peer netfulfilledman.AddFulfilledRequest(pnode->addr, "spork-sync"); // get current network sporks - connman.PushMessage(pnode, msgMakerInitProto.Make(NetMsgType::GETSPORKS)); + connman.PushMessage(pnode, msgMaker.Make(NetMsgType::GETSPORKS)); LogPrintf("CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- requesting sporks from peer %d\n", nTick, nRequestedMasternodeAssets, pnode->id); } From fab725f621039b9e8509c979cfa54be2aa3f0d7a Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Wed, 27 Feb 2019 21:15:09 +0000 Subject: [PATCH 72/75] Update 2minutes on Sync --- src/masternode-sync.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/masternode-sync.h b/src/masternode-sync.h index 50023cb8e3f3b..fb4ed17d3d109 100644 --- a/src/masternode-sync.h +++ b/src/masternode-sync.h @@ -23,7 +23,7 @@ static const int MASTERNODE_SYNC_GOVOBJ_VOTE = 11; static const int MASTERNODE_SYNC_FINISHED = 999; static const int MASTERNODE_SYNC_TICK_SECONDS = 6; -static const int MASTERNODE_SYNC_TIMEOUT_SECONDS = 30; // our blocks are 1.5 minutes so 30 seconds should be fine +static const int MASTERNODE_SYNC_TIMEOUT_SECONDS = 30; // our blocks are 2 minutes so 30 seconds should be fine static const int MASTERNODE_SYNC_ENOUGH_PEERS = 6; From 9c641eabc85165ec4105ba709f894b13c8025d97 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Wed, 27 Feb 2019 21:15:30 +0000 Subject: [PATCH 73/75] bump lower Proto on Masternodes --- src/masternode-payments.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/masternode-payments.h b/src/masternode-payments.h index 73da31ed3f93a..d1bc058b90bb0 100644 --- a/src/masternode-payments.h +++ b/src/masternode-payments.h @@ -24,7 +24,7 @@ static const int MNPAYMENTS_SIGNATURES_TOTAL = 10; // vote for masternode and be elected as a payment winner // V1 - Last protocol version before update // V2 - Newest protocol version -static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_1 = 70206; +static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_1 = 70208; static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_2 = 70210; extern CCriticalSection cs_vecPayees; From 4bafa2582f1587bd0b4b1d6795208ee44d4a1bff Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Wed, 24 Jan 2018 18:29:24 +0300 Subject: [PATCH 74/75] Separate .h generation from .json/.raw for different modules --- src/Makefile.bench.include | 5 +++-- src/Makefile.test.include | 12 +++++++++++- src/bench/checkblock.cpp | 14 ++++++-------- src/test/alert_tests.cpp | 2 +- 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include index b0e0130505270..de763413b30dc 100644 --- a/src/Makefile.bench.include +++ b/src/Makefile.bench.include @@ -67,11 +67,12 @@ bench: $(BENCH_BINARY) FORCE bitcoin_bench_clean : FORCE rm -f $(CLEAN_BITCOIN_BENCH) $(bench_bench_absolute_OBJECTS) $(BENCH_BINARY) -%.raw.h: %.raw +bench/data/%.raw.h: bench/data/%.raw @$(MKDIR_P) $(@D) @{ \ + echo "namespace raw_bench{" && \ echo "static unsigned const char $(*F)[] = {" && \ $(HEXDUMP) -v -e '8/1 "0x%02x, "' -e '"\n"' $< | $(SED) -e 's/0x ,//g' && \ - echo "};"; \ + echo "};};"; \ } > "$@.new" && mv -f "$@.new" "$@" @echo "Generated $@" diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 551921815359f..a9106bf98ad31 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -182,7 +182,7 @@ if EMBEDDED_UNIVALUE $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C univalue check endif -%.json.h: %.json +test/data/%.json.h: test/data/%.json @$(MKDIR_P) $(@D) @{ \ echo "namespace json_tests{" && \ @@ -191,3 +191,13 @@ endif echo "};};"; \ } > "$@.new" && mv -f "$@.new" "$@" @echo "Generated $@" + +test/data/%.raw.h: test/data/%.raw + @$(MKDIR_P) $(@D) + @{ \ + echo "namespace raw_tests{" && \ + echo "static unsigned const char $(*F)[] = {" && \ + $(HEXDUMP) -v -e '8/1 "0x%02x, "' -e '"\n"' $< | $(SED) -e 's/0x ,//g' && \ + echo "};};"; \ + } > "$@.new" && mv -f "$@.new" "$@" + @echo "Generated $@" diff --git a/src/bench/checkblock.cpp b/src/bench/checkblock.cpp index d25e88de2e994..b97997822156d 100644 --- a/src/bench/checkblock.cpp +++ b/src/bench/checkblock.cpp @@ -9,9 +9,7 @@ #include "streams.h" #include "consensus/validation.h" -namespace block_bench { #include "bench/data/block413567.raw.h" -} // These are the two major time-sinks which happen after we have fully received // a block off the wire, but before we can relay the block on to peers using @@ -19,8 +17,8 @@ namespace block_bench { static void DeserializeBlockTest(benchmark::State& state) { - CDataStream stream((const char*)block_bench::block413567, - (const char*)&block_bench::block413567[sizeof(block_bench::block413567)], + CDataStream stream((const char*)raw_bench::block413567, + (const char*)&raw_bench::block413567[sizeof(raw_bench::block413567)], SER_NETWORK, PROTOCOL_VERSION); char a; stream.write(&a, 1); // Prevent compaction @@ -28,14 +26,14 @@ static void DeserializeBlockTest(benchmark::State& state) while (state.KeepRunning()) { CBlock block; stream >> block; - assert(stream.Rewind(sizeof(block_bench::block413567))); + assert(stream.Rewind(sizeof(raw_bench::block413567))); } } static void DeserializeAndCheckBlockTest(benchmark::State& state) { - CDataStream stream((const char*)block_bench::block413567, - (const char*)&block_bench::block413567[sizeof(block_bench::block413567)], + CDataStream stream((const char*)raw_bench::block413567, + (const char*)&raw_bench::block413567[sizeof(raw_bench::block413567)], SER_NETWORK, PROTOCOL_VERSION); char a; stream.write(&a, 1); // Prevent compaction @@ -45,7 +43,7 @@ static void DeserializeAndCheckBlockTest(benchmark::State& state) while (state.KeepRunning()) { CBlock block; // Note that CBlock caches its checked state, so we need to recreate it here stream >> block; - assert(stream.Rewind(sizeof(block_bench::block413567))); + assert(stream.Rewind(sizeof(raw_bench::block413567))); CValidationState validationState; assert(CheckBlock(block, validationState, params, block.GetBlockTime())); diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp index 0e6ba93e5a720..b1e77d9706e34 100644 --- a/src/test/alert_tests.cpp +++ b/src/test/alert_tests.cpp @@ -110,7 +110,7 @@ struct ReadAlerts : public TestingSetup { ReadAlerts() { - std::vector vch(alertTests, alertTests + sizeof(alertTests)); + std::vector vch(raw_tests::alertTests, raw_tests::alertTests + sizeof(raw_tests::alertTests)); CDataStream stream(vch, SER_DISK, CLIENT_VERSION); try { while (!stream.eof()) From 7030eac191b9777731608e1cf976780ebbbec7cd Mon Sep 17 00:00:00 2001 From: Nathan Marley Date: Wed, 31 Jan 2018 02:56:30 -0800 Subject: [PATCH 75/75] Shorten MN outpoint output from getvotes (#1871) --- src/governance-vote.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/governance-vote.h b/src/governance-vote.h index 20ff39bd70477..53ccc2200d167 100644 --- a/src/governance-vote.h +++ b/src/governance-vote.h @@ -152,7 +152,7 @@ class CGovernanceVote std::string ToString() const { std::ostringstream ostr; - ostr << vinMasternode.ToString() << ":" + ostr << vinMasternode.prevout.ToStringShort() << ":" << nTime << ":" << CGovernanceVoting::ConvertOutcomeToString(GetOutcome()) << ":" << CGovernanceVoting::ConvertSignalToString(GetSignal());