From 98ea64cf232c34d4b1aebe738b3956191667cd76 Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Mon, 28 Nov 2016 17:19:27 -0500 Subject: [PATCH 0001/1200] Let wallet importmulti RPC accept labels for standard scriptPubKeys Allow importmulti RPC to apply address labels when importing standard scriptPubKeys. This makes the importmulti RPC less finnicky about import formats and also simpler internally. --- src/wallet/rpcdump.cpp | 42 +++++-------------------- test/functional/wallet_import_rescan.py | 10 +++--- test/functional/wallet_importmulti.py | 27 +++++++++------- 3 files changed, 28 insertions(+), 51 deletions(-) diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 741ea25340..caaacdd72c 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -838,6 +838,9 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6 std::vector vData(ParseHex(output)); script = CScript(vData.begin(), vData.end()); + if (!ExtractDestination(script, dest) && !internal) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Internal must be set to true for nonstandard scriptPubKey imports."); + } } // Watchonly and private keys @@ -850,11 +853,6 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6 throw JSONRPCError(RPC_INVALID_PARAMETER, "Incompatibility found between internal and label"); } - // Not having Internal + Script - if (!internal && isScript) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Internal must be set for hex scriptPubKey"); - } - // Keys / PubKeys size check. if (!isP2SH && (keys.size() > 1 || pubKeys.size() > 1)) { // Address / scriptPubKey throw JSONRPCError(RPC_INVALID_PARAMETER, "More than private key given for one address"); @@ -965,21 +963,10 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6 CTxDestination pubkey_dest = pubKey.GetID(); // Consistency check. - if (!isScript && !(pubkey_dest == dest)) { + if (!(pubkey_dest == dest)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Consistency check failed"); } - // Consistency check. - if (isScript) { - CTxDestination destination; - - if (ExtractDestination(script, destination)) { - if (!(destination == pubkey_dest)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Consistency check failed"); - } - } - } - CScript pubKeyScript = GetScriptForDestination(pubkey_dest); if (::IsMine(*pwallet, pubKeyScript) == ISMINE_SPENDABLE) { @@ -1036,21 +1023,10 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6 CTxDestination pubkey_dest = pubKey.GetID(); // Consistency check. - if (!isScript && !(pubkey_dest == dest)) { + if (!(pubkey_dest == dest)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Consistency check failed"); } - // Consistency check. - if (isScript) { - CTxDestination destination; - - if (ExtractDestination(script, destination)) { - if (!(destination == pubkey_dest)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Consistency check failed"); - } - } - } - CKeyID vchAddress = pubKey.GetID(); pwallet->MarkDirty(); pwallet->SetAddressBook(vchAddress, label, "receive"); @@ -1082,11 +1058,9 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6 throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } - if (scriptPubKey.getType() == UniValue::VOBJ) { - // add to address book or update label - if (IsValidDestination(dest)) { - pwallet->SetAddressBook(dest, label, "receive"); - } + // add to address book or update label + if (IsValidDestination(dest)) { + pwallet->SetAddressBook(dest, label, "receive"); } success = true; diff --git a/test/functional/wallet_import_rescan.py b/test/functional/wallet_import_rescan.py index 3288ce4b60..a7095e1a24 100755 --- a/test/functional/wallet_import_rescan.py +++ b/test/functional/wallet_import_rescan.py @@ -26,7 +26,7 @@ import enum import itertools -Call = enum.Enum("Call", "single multi") +Call = enum.Enum("Call", "single multiaddress multiscript") Data = enum.Enum("Data", "address pub priv") Rescan = enum.Enum("Rescan", "no yes late_timestamp") @@ -54,11 +54,11 @@ def do_import(self, timestamp): response = self.try_rpc(self.node.importprivkey, self.key, self.label, self.rescan == Rescan.yes) assert_equal(response, None) - elif self.call == Call.multi: + elif self.call in (Call.multiaddress, Call.multiscript): response = self.node.importmulti([{ "scriptPubKey": { "address": self.address["address"] - }, + } if self.call == Call.multiaddress else self.address["scriptPubKey"], "timestamp": timestamp + TIMESTAMP_WINDOW + (1 if self.rescan == Rescan.late_timestamp else 0), "pubkeys": [self.address["pubkey"]] if self.data == Data.pub else [], "keys": [self.key] if self.data == Data.priv else [], @@ -136,7 +136,7 @@ def run_test(self): variant.label = "label {} {}".format(i, variant) variant.address = self.nodes[1].getaddressinfo(self.nodes[1].getnewaddress(variant.label)) variant.key = self.nodes[1].dumpprivkey(variant.address["address"]) - variant.initial_amount = 10 - (i + 1) / 4.0 + variant.initial_amount = 1 - (i + 1) / 64 variant.initial_txid = self.nodes[0].sendtoaddress(variant.address["address"], variant.initial_amount) # Generate a block containing the initial transactions, then another @@ -166,7 +166,7 @@ def run_test(self): # Create new transactions sending to each address. for i, variant in enumerate(IMPORT_VARIANTS): - variant.sent_amount = 10 - (2 * i + 1) / 8.0 + variant.sent_amount = 1 - (2 * i + 1) / 128 variant.sent_txid = self.nodes[0].sendtoaddress(variant.address["address"], variant.sent_amount) # Generate a block containing the new transactions. diff --git a/test/functional/wallet_importmulti.py b/test/functional/wallet_importmulti.py index 56ebc2622a..0b4065ed7e 100755 --- a/test/functional/wallet_importmulti.py +++ b/test/functional/wallet_importmulti.py @@ -3,6 +3,8 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the importmulti RPC.""" + +from test_framework import script from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * @@ -79,16 +81,17 @@ def run_test (self): assert_equal(address_assert['ismine'], False) assert_equal(address_assert['timestamp'], timestamp) - # ScriptPubKey + !internal - self.log.info("Should not import a scriptPubKey without internal flag") + # Nonstandard scriptPubKey + !internal + self.log.info("Should not import a nonstandard scriptPubKey without internal flag") + nonstandardScriptPubKey = address['scriptPubKey'] + bytes_to_hex_str(script.CScript([script.OP_NOP])) address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress()) result = self.nodes[1].importmulti([{ - "scriptPubKey": address['scriptPubKey'], + "scriptPubKey": nonstandardScriptPubKey, "timestamp": "now", }]) assert_equal(result[0]['success'], False) assert_equal(result[0]['error']['code'], -8) - assert_equal(result[0]['error']['message'], 'Internal must be set for hex scriptPubKey') + assert_equal(result[0]['error']['message'], 'Internal must be set to true for nonstandard scriptPubKey imports.') address_assert = self.nodes[1].getaddressinfo(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) @@ -128,18 +131,18 @@ def run_test (self): assert_equal(address_assert['ismine'], False) assert_equal(address_assert['timestamp'], timestamp) - # ScriptPubKey + Public key + !internal - self.log.info("Should not import a scriptPubKey without internal and with public key") + # Nonstandard scriptPubKey + Public key + !internal + self.log.info("Should not import a nonstandard scriptPubKey without internal and with public key") address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress()) request = [{ - "scriptPubKey": address['scriptPubKey'], + "scriptPubKey": nonstandardScriptPubKey, "timestamp": "now", "pubkeys": [ address['pubkey'] ] }] result = self.nodes[1].importmulti(request) assert_equal(result[0]['success'], False) assert_equal(result[0]['error']['code'], -8) - assert_equal(result[0]['error']['message'], 'Internal must be set for hex scriptPubKey') + assert_equal(result[0]['error']['message'], 'Internal must be set to true for nonstandard scriptPubKey imports.') address_assert = self.nodes[1].getaddressinfo(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) @@ -207,17 +210,17 @@ def run_test (self): assert_equal(address_assert['ismine'], True) assert_equal(address_assert['timestamp'], timestamp) - # ScriptPubKey + Private key + !internal - self.log.info("Should not import a scriptPubKey without internal and with private key") + # Nonstandard scriptPubKey + Private key + !internal + self.log.info("Should not import a nonstandard scriptPubKey without internal and with private key") address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress()) result = self.nodes[1].importmulti([{ - "scriptPubKey": address['scriptPubKey'], + "scriptPubKey": nonstandardScriptPubKey, "timestamp": "now", "keys": [ self.nodes[0].dumpprivkey(address['address']) ] }]) assert_equal(result[0]['success'], False) assert_equal(result[0]['error']['code'], -8) - assert_equal(result[0]['error']['message'], 'Internal must be set for hex scriptPubKey') + assert_equal(result[0]['error']['message'], 'Internal must be set to true for nonstandard scriptPubKey imports.') address_assert = self.nodes[1].getaddressinfo(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) From 545e85eccc2441c6d7745bb90d88dc14718455a2 Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Thu, 15 Jun 2017 14:56:35 -0400 Subject: [PATCH 0002/1200] Add AssertLockHeld assertions in CWallet::ListCoins --- src/wallet/test/wallet_tests.cpp | 16 +++++++++++++--- src/wallet/wallet.cpp | 12 ++---------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 14c5ad7214..10e6da8b13 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -317,7 +317,11 @@ BOOST_FIXTURE_TEST_CASE(ListCoins, ListCoinsTestingSetup) // Confirm ListCoins initially returns 1 coin grouped under coinbaseKey // address. - auto list = wallet->ListCoins(); + std::map> list; + { + LOCK2(cs_main, wallet->cs_wallet); + list = wallet->ListCoins(); + } BOOST_CHECK_EQUAL(list.size(), 1U); BOOST_CHECK_EQUAL(boost::get(list.begin()->first).ToString(), coinbaseAddress); BOOST_CHECK_EQUAL(list.begin()->second.size(), 1U); @@ -330,7 +334,10 @@ BOOST_FIXTURE_TEST_CASE(ListCoins, ListCoinsTestingSetup) // coinbaseKey pubkey, even though the change address has a different // pubkey. AddTx(CRecipient{GetScriptForRawPubKey({}), 1 * COIN, false /* subtract fee */}); - list = wallet->ListCoins(); + { + LOCK2(cs_main, wallet->cs_wallet); + list = wallet->ListCoins(); + } BOOST_CHECK_EQUAL(list.size(), 1U); BOOST_CHECK_EQUAL(boost::get(list.begin()->first).ToString(), coinbaseAddress); BOOST_CHECK_EQUAL(list.begin()->second.size(), 2U); @@ -356,7 +363,10 @@ BOOST_FIXTURE_TEST_CASE(ListCoins, ListCoinsTestingSetup) } // Confirm ListCoins still returns same result as before, despite coins // being locked. - list = wallet->ListCoins(); + { + LOCK2(cs_main, wallet->cs_wallet); + list = wallet->ListCoins(); + } BOOST_CHECK_EQUAL(list.size(), 1U); BOOST_CHECK_EQUAL(boost::get(list.begin()->first).ToString(), coinbaseAddress); BOOST_CHECK_EQUAL(list.begin()->second.size(), 2U); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 7d46f02745..40ff063105 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2364,20 +2364,12 @@ void CWallet::AvailableCoins(std::vector &vCoins, bool fOnlySafe, const std::map> CWallet::ListCoins() const { - // TODO: Add AssertLockHeld(cs_wallet) here. - // - // Because the return value from this function contains pointers to - // CWalletTx objects, callers to this function really should acquire the - // cs_wallet lock before calling it. However, the current caller doesn't - // acquire this lock yet. There was an attempt to add the missing lock in - // https://github.com/bitcoin/bitcoin/pull/10340, but that change has been - // postponed until after https://github.com/bitcoin/bitcoin/pull/10244 to - // avoid adding some extra complexity to the Qt code. + AssertLockHeld(cs_main); + AssertLockHeld(cs_wallet); std::map> result; std::vector availableCoins; - LOCK2(cs_main, cs_wallet); AvailableCoins(availableCoins); for (auto& coin : availableCoins) { From 820d31f95fb6b886b38dab5d378825bea7edd49e Mon Sep 17 00:00:00 2001 From: dexX7 Date: Tue, 13 Mar 2018 11:46:22 +0100 Subject: [PATCH 0003/1200] Add "bip125-replaceable" flag to mempool RPCs This affects getrawmempool, getmempoolentry, getmempoolancestors and getmempooldescendants. --- src/rpc/blockchain.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 06c68ea27c..a26b8f3b45 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -376,7 +377,8 @@ std::string EntryDescriptionString() " ... ]\n" " \"spentby\" : [ (array) unconfirmed transactions spending outputs from this transaction\n" " \"transactionid\", (string) child transaction id\n" - " ... ]\n"; + " ... ]\n" + " \"bip125-replaceable\" : true|false, (boolean) Whether this transaction could be replaced due to BIP125 (replace-by-fee)\n"; } void entryToJSON(UniValue &info, const CTxMemPoolEntry &e) @@ -419,6 +421,17 @@ void entryToJSON(UniValue &info, const CTxMemPoolEntry &e) } info.pushKV("spentby", spent); + + // Add opt-in RBF status + bool rbfStatus = false; + RBFTransactionState rbfState = IsRBFOptIn(tx, mempool); + if (rbfState == RBFTransactionState::UNKNOWN) { + throw JSONRPCError(RPC_MISC_ERROR, "Transaction is not in mempool"); + } else if (rbfState == RBFTransactionState::REPLACEABLE_BIP125) { + rbfStatus = true; + } + + info.pushKV("bip125-replaceable", rbfStatus); } UniValue mempoolToJSON(bool fVerbose) From 870bd4c73ddf494dc23c658bf0fb672ee0109158 Mon Sep 17 00:00:00 2001 From: dexX7 Date: Tue, 13 Mar 2018 12:03:49 +0100 Subject: [PATCH 0004/1200] Update functional RBF test to check replaceable flag --- test/functional/feature_rbf.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/functional/feature_rbf.py b/test/functional/feature_rbf.py index d6ab5ecc37..a9bcb8483c 100755 --- a/test/functional/feature_rbf.py +++ b/test/functional/feature_rbf.py @@ -427,6 +427,9 @@ def test_opt_in(self): tx1a_hex = txToHex(tx1a) tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True) + # This transaction isn't shown as replaceable + assert_equal(self.nodes[0].getmempoolentry(tx1a_txid)['bip125-replaceable'], False) + # Shouldn't be able to double-spend tx1b = CTransaction() tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)] @@ -467,7 +470,10 @@ def test_opt_in(self): tx3a.vout = [CTxOut(int(0.9*COIN), CScript([b'c'])), CTxOut(int(0.9*COIN), CScript([b'd']))] tx3a_hex = txToHex(tx3a) - self.nodes[0].sendrawtransaction(tx3a_hex, True) + tx3a_txid = self.nodes[0].sendrawtransaction(tx3a_hex, True) + + # This transaction is shown as replaceable + assert_equal(self.nodes[0].getmempoolentry(tx3a_txid)['bip125-replaceable'], True) tx3b = CTransaction() tx3b.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0)] From b16ab9af07f802cc769c2443df1c637e8e12ab80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Barbosa?= Date: Wed, 23 May 2018 11:53:19 +0100 Subject: [PATCH 0005/1200] Report progress in ReplayBlocks while rolling forward --- src/validation.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/validation.cpp b/src/validation.cpp index 3971906424..c1e8ba5558 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -4103,6 +4103,7 @@ bool CChainState::ReplayBlocks(const CChainParams& params, CCoinsView* view) for (int nHeight = nForkHeight + 1; nHeight <= pindexNew->nHeight; ++nHeight) { const CBlockIndex* pindex = pindexNew->GetAncestor(nHeight); LogPrintf("Rolling forward %s (%i)\n", pindex->GetBlockHash().ToString(), nHeight); + uiInterface.ShowProgress(_("Replaying blocks..."), (int) ((nHeight - nForkHeight) * 100.0 / (pindexNew->nHeight - nForkHeight)) , false); if (!RollforwardBlock(pindex, cache, params)) return false; } From 6ad0328f1c3e145d3224197eafd0f66b17cc1a1c Mon Sep 17 00:00:00 2001 From: practicalswift Date: Tue, 26 Jun 2018 17:19:31 +0200 Subject: [PATCH 0006/1200] Don't assert(foo()) where foo has side effects --- src/bench/block_assemble.cpp | 3 ++- src/bench/checkblock.cpp | 9 ++++++--- src/httprpc.cpp | 5 +++-- src/script/sign.cpp | 3 ++- src/test/txvalidation_tests.cpp | 2 +- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/bench/block_assemble.cpp b/src/bench/block_assemble.cpp index 36fa175a76..2bd67654ab 100644 --- a/src/bench/block_assemble.cpp +++ b/src/bench/block_assemble.cpp @@ -41,7 +41,8 @@ static CTxIn MineBlock(const CScript& coinbase_scriptPubKey) auto block = PrepareBlock(coinbase_scriptPubKey); while (!CheckProofOfWork(block->GetHash(), block->nBits, Params().GetConsensus())) { - assert(++block->nNonce); + ++block->nNonce; + assert(block->nNonce); } bool processed{ProcessNewBlock(Params(), block, true, nullptr)}; diff --git a/src/bench/checkblock.cpp b/src/bench/checkblock.cpp index fac7e079a7..387ae1769c 100644 --- a/src/bench/checkblock.cpp +++ b/src/bench/checkblock.cpp @@ -28,7 +28,8 @@ static void DeserializeBlockTest(benchmark::State& state) while (state.KeepRunning()) { CBlock block; stream >> block; - assert(stream.Rewind(sizeof(block_bench::block413567))); + bool rewound = stream.Rewind(sizeof(block_bench::block413567)); + assert(rewound); } } @@ -45,10 +46,12 @@ 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))); + bool rewound = stream.Rewind(sizeof(block_bench::block413567)); + assert(rewound); CValidationState validationState; - assert(CheckBlock(block, validationState, chainParams->GetConsensus())); + bool checked = CheckBlock(block, validationState, chainParams->GetConsensus()); + assert(checked); } } diff --git a/src/httprpc.cpp b/src/httprpc.cpp index de2437943e..aec92711c9 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -240,8 +240,9 @@ bool StartHTTPRPC() // ifdef can be removed once we switch to better endpoint support and API versioning RegisterHTTPHandler("/wallet/", false, HTTPReq_JSONRPC); #endif - assert(EventBase()); - httpRPCTimerInterface = MakeUnique(EventBase()); + struct event_base* eventBase = EventBase(); + assert(eventBase); + httpRPCTimerInterface = MakeUnique(eventBase); RPCSetTimerInterface(httpRPCTimerInterface.get()); return true; } diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 60a8a2655d..541d90e78f 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -424,7 +424,8 @@ bool IsSolvable(const SigningProvider& provider, const CScript& script) static_assert(STANDARD_SCRIPT_VERIFY_FLAGS & SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, "IsSolvable requires standard script flags to include WITNESS_PUBKEYTYPE"); if (ProduceSignature(provider, DUMMY_SIGNATURE_CREATOR, script, sigs)) { // VerifyScript check is just defensive, and should never fail. - assert(VerifyScript(sigs.scriptSig, script, &sigs.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, DUMMY_CHECKER)); + bool verified = VerifyScript(sigs.scriptSig, script, &sigs.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, DUMMY_CHECKER); + assert(verified); return true; } return false; diff --git a/src/test/txvalidation_tests.cpp b/src/test/txvalidation_tests.cpp index 2d1eb7b772..473ec5addf 100644 --- a/src/test/txvalidation_tests.cpp +++ b/src/test/txvalidation_tests.cpp @@ -30,7 +30,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_reject_coinbase, TestChain100Setup) coinbaseTx.vout[0].nValue = 1 * CENT; coinbaseTx.vout[0].scriptPubKey = scriptPubKey; - assert(CTransaction(coinbaseTx).IsCoinBase()); + BOOST_CHECK(CTransaction(coinbaseTx).IsCoinBase()); CValidationState state; From 65a449f8e3b1bd95a0978b68cd6ce3ddda832658 Mon Sep 17 00:00:00 2001 From: Sjors Provoost Date: Sat, 14 Jul 2018 17:48:16 +0200 Subject: [PATCH 0007/1200] Explain when reindex-chainstate can be used instead of reindex --- src/init.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index fe4fba8cdf..87650c3276 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -384,7 +384,7 @@ void SetupServerArgs() "Warning: Reverting this setting requires re-downloading the entire blockchain. " "(default: 0 = disable pruning blocks, 1 = allow manual pruning via RPC, >%u = automatically prune block files to stay under the specified target size in MiB)", MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024), false, OptionsCategory::OPTIONS); gArgs.AddArg("-reindex", "Rebuild chain state and block index from the blk*.dat files on disk", false, OptionsCategory::OPTIONS); - gArgs.AddArg("-reindex-chainstate", "Rebuild chain state from the currently indexed blocks", false, OptionsCategory::OPTIONS); + gArgs.AddArg("-reindex-chainstate", "Rebuild chain state from the currently indexed blocks. When in pruning mode or if blocks on disk might be corrupted, use full -reindex instead.", false, OptionsCategory::OPTIONS); #ifndef WIN32 gArgs.AddArg("-sysperms", "Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)", false, OptionsCategory::OPTIONS); #else From 03a2d680101a9fee47c6fd818df7585cfc93ac06 Mon Sep 17 00:00:00 2001 From: Mason Simon Date: Wed, 18 Jul 2018 17:47:34 -0700 Subject: [PATCH 0008/1200] Tests: add usage note to check-rpc-mappings.py --- test/lint/check-rpc-mappings.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/lint/check-rpc-mappings.py b/test/lint/check-rpc-mappings.py index c3cdeef580..28d08eba01 100755 --- a/test/lint/check-rpc-mappings.py +++ b/test/lint/check-rpc-mappings.py @@ -90,6 +90,10 @@ def process_mapping(fname): return cmds def main(): + if len(sys.argv) != 2: + print('Usage: {} ROOT-DIR'.format(sys.argv[0]), file=sys.stderr) + sys.exit(1) + root = sys.argv[1] # Get all commands from dispatch tables From 984d72ec659361d8c1a6f3c6864e839a807817a7 Mon Sep 17 00:00:00 2001 From: Ben Woosley Date: Sun, 10 Jun 2018 22:19:07 -0700 Subject: [PATCH 0009/1200] Return the script type from Solver Because false is synonymous with TX_NONSTANDARD, this conveys the same information and makes the handling explicitly based on script type, simplifying each call site. Prior to this change it was common for the return value to be ignored, or for the return value and TX_NONSTANDARD to be redundantly handled. --- src/bloom.cpp | 6 ++-- src/core_write.cpp | 3 +- src/policy/policy.cpp | 23 ++++++------ src/rpc/rawtransaction.cpp | 3 +- src/script/ismine.cpp | 3 +- src/script/sign.cpp | 10 +++--- src/script/standard.cpp | 57 +++++++++++------------------- src/script/standard.h | 5 ++- src/test/script_standard_tests.cpp | 47 ++++++++++-------------- src/wallet/rpcwallet.cpp | 3 +- 10 files changed, 62 insertions(+), 98 deletions(-) diff --git a/src/bloom.cpp b/src/bloom.cpp index f8e28edded..4bc0eab011 100644 --- a/src/bloom.cpp +++ b/src/bloom.cpp @@ -164,11 +164,11 @@ bool CBloomFilter::IsRelevantAndUpdate(const CTransaction& tx) insert(COutPoint(hash, i)); else if ((nFlags & BLOOM_UPDATE_MASK) == BLOOM_UPDATE_P2PUBKEY_ONLY) { - txnouttype type; std::vector > vSolutions; - if (Solver(txout.scriptPubKey, type, vSolutions) && - (type == TX_PUBKEY || type == TX_MULTISIG)) + txnouttype type = Solver(txout.scriptPubKey, vSolutions); + if (type == TX_PUBKEY || type == TX_MULTISIG) { insert(COutPoint(hash, i)); + } } break; } diff --git a/src/core_write.cpp b/src/core_write.cpp index 1272266235..ec6a7d1321 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -141,8 +141,7 @@ void ScriptToUniv(const CScript& script, UniValue& out, bool include_address) out.pushKV("hex", HexStr(script.begin(), script.end())); std::vector> solns; - txnouttype type; - Solver(script, type, solns); + txnouttype type = Solver(script, solns); out.pushKV("type", GetTxnOutputType(type)); CTxDestination address; diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 3a592e40d3..f1ba09d4d2 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -57,11 +57,11 @@ bool IsDust(const CTxOut& txout, const CFeeRate& dustRelayFeeIn) bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType) { std::vector > vSolutions; - if (!Solver(scriptPubKey, whichType, vSolutions)) - return false; + whichType = Solver(scriptPubKey, vSolutions); - if (whichType == TX_MULTISIG) - { + if (whichType == TX_NONSTANDARD || whichType == TX_WITNESS_UNKNOWN) { + return false; + } else if (whichType == TX_MULTISIG) { unsigned char m = vSolutions.front()[0]; unsigned char n = vSolutions.back()[0]; // Support up to x-of-3 multisig txns as standard @@ -70,10 +70,11 @@ bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType) if (m < 1 || m > n) return false; } else if (whichType == TX_NULL_DATA && - (!fAcceptDatacarrier || scriptPubKey.size() > nMaxDatacarrierBytes)) + (!fAcceptDatacarrier || scriptPubKey.size() > nMaxDatacarrierBytes)) { return false; + } - return whichType != TX_NONSTANDARD && whichType != TX_WITNESS_UNKNOWN; + return true; } bool IsStandardTx(const CTransaction& tx, std::string& reason) @@ -166,14 +167,10 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) const CTxOut& prev = mapInputs.AccessCoin(tx.vin[i].prevout).out; std::vector > vSolutions; - txnouttype whichType; - // get the scriptPubKey corresponding to this input: - const CScript& prevScript = prev.scriptPubKey; - if (!Solver(prevScript, whichType, vSolutions)) + txnouttype whichType = Solver(prev.scriptPubKey, vSolutions); + if (whichType == TX_NONSTANDARD) { return false; - - if (whichType == TX_SCRIPTHASH) - { + } else if (whichType == TX_SCRIPTHASH) { std::vector > stack; // convert the scriptSig into a stack, so we can inspect the redeemScript if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SigVersion::BASE)) diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index bb94e11fea..eed70d730f 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -627,9 +627,8 @@ static UniValue decodescript(const JSONRPCRequest& request) // P2SH and witness programs cannot be wrapped in P2WSH, if this script // is a witness program, don't return addresses for a segwit programs. if (type.get_str() == "pubkey" || type.get_str() == "pubkeyhash" || type.get_str() == "multisig" || type.get_str() == "nonstandard") { - txnouttype which_type; std::vector> solutions_data; - Solver(script, which_type, solutions_data); + txnouttype which_type = Solver(script, solutions_data); // Uncompressed pubkeys cannot be used with segwit checksigs. // If the script contains an uncompressed pubkey, skip encoding of a segwit program. if ((which_type == TX_PUBKEY) || (which_type == TX_MULTISIG)) { diff --git a/src/script/ismine.cpp b/src/script/ismine.cpp index 8c26866483..7e7087663a 100644 --- a/src/script/ismine.cpp +++ b/src/script/ismine.cpp @@ -60,8 +60,7 @@ IsMineResult IsMineInner(const CKeyStore& keystore, const CScript& scriptPubKey, IsMineResult ret = IsMineResult::NO; std::vector vSolutions; - txnouttype whichType; - Solver(scriptPubKey, whichType, vSolutions); + txnouttype whichType = Solver(scriptPubKey, vSolutions); CKeyID keyID; switch (whichType) diff --git a/src/script/sign.cpp b/src/script/sign.cpp index c2ae4ff2ea..f0090800aa 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -102,8 +102,7 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator std::vector sig; std::vector vSolutions; - if (!Solver(scriptPubKey, whichTypeRet, vSolutions)) - return false; + whichTypeRet = Solver(scriptPubKey, vSolutions); switch (whichTypeRet) { @@ -314,9 +313,8 @@ SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nI } // Get scripts - txnouttype script_type; std::vector> solutions; - Solver(txout.scriptPubKey, script_type, solutions); + txnouttype script_type = Solver(txout.scriptPubKey, solutions); SigVersion sigversion = SigVersion::BASE; CScript next_script = txout.scriptPubKey; @@ -327,7 +325,7 @@ SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nI next_script = std::move(redeem_script); // Get redeemScript type - Solver(next_script, script_type, solutions); + script_type = Solver(next_script, solutions); stack.script.pop_back(); } if (script_type == TX_WITNESS_V0_SCRIPTHASH && !stack.witness.empty() && !stack.witness.back().empty()) { @@ -337,7 +335,7 @@ SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nI next_script = std::move(witness_script); // Get witnessScript type - Solver(next_script, script_type, solutions); + script_type = Solver(next_script, solutions); stack.witness.pop_back(); stack.script = std::move(stack.witness); stack.witness.clear(); diff --git a/src/script/standard.cpp b/src/script/standard.cpp index d7b1724790..d309420d35 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -87,7 +87,7 @@ static bool MatchMultisig(const CScript& script, unsigned int& required, std::ve return (it + 1 == script.end()); } -bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector >& vSolutionsRet) +txnouttype Solver(const CScript& scriptPubKey, std::vector>& vSolutionsRet) { vSolutionsRet.clear(); @@ -95,33 +95,28 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector hashBytes(scriptPubKey.begin()+2, scriptPubKey.begin()+22); vSolutionsRet.push_back(hashBytes); - return true; + return TX_SCRIPTHASH; } int witnessversion; std::vector witnessprogram; if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) { if (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_KEYHASH_SIZE) { - typeRet = TX_WITNESS_V0_KEYHASH; vSolutionsRet.push_back(witnessprogram); - return true; + return TX_WITNESS_V0_KEYHASH; } if (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_SCRIPTHASH_SIZE) { - typeRet = TX_WITNESS_V0_SCRIPTHASH; vSolutionsRet.push_back(witnessprogram); - return true; + return TX_WITNESS_V0_SCRIPTHASH; } if (witnessversion != 0) { - typeRet = TX_WITNESS_UNKNOWN; vSolutionsRet.push_back(std::vector{(unsigned char)witnessversion}); vSolutionsRet.push_back(std::move(witnessprogram)); - return true; + return TX_WITNESS_UNKNOWN; } - typeRet = TX_NONSTANDARD; - return false; + return TX_NONSTANDARD; } // Provably prunable, data-carrying output @@ -130,47 +125,39 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector= 1 && scriptPubKey[0] == OP_RETURN && scriptPubKey.IsPushOnly(scriptPubKey.begin()+1)) { - typeRet = TX_NULL_DATA; - return true; + return TX_NULL_DATA; } std::vector data; if (MatchPayToPubkey(scriptPubKey, data)) { - typeRet = TX_PUBKEY; vSolutionsRet.push_back(std::move(data)); - return true; + return TX_PUBKEY; } if (MatchPayToPubkeyHash(scriptPubKey, data)) { - typeRet = TX_PUBKEYHASH; vSolutionsRet.push_back(std::move(data)); - return true; + return TX_PUBKEYHASH; } unsigned int required; std::vector> keys; if (MatchMultisig(scriptPubKey, required, keys)) { - typeRet = TX_MULTISIG; vSolutionsRet.push_back({static_cast(required)}); // safe as required is in range 1..16 vSolutionsRet.insert(vSolutionsRet.end(), keys.begin(), keys.end()); vSolutionsRet.push_back({static_cast(keys.size())}); // safe as size is in range 1..16 - return true; + return TX_MULTISIG; } vSolutionsRet.clear(); - typeRet = TX_NONSTANDARD; - return false; + return TX_NONSTANDARD; } bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) { std::vector vSolutions; - txnouttype whichType; - if (!Solver(scriptPubKey, whichType, vSolutions)) - return false; + txnouttype whichType = Solver(scriptPubKey, vSolutions); - if (whichType == TX_PUBKEY) - { + if (whichType == TX_PUBKEY) { CPubKey pubKey(vSolutions[0]); if (!pubKey.IsValid()) return false; @@ -212,11 +199,11 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector& addressRet, int& nRequiredRet) { addressRet.clear(); - typeRet = TX_NONSTANDARD; std::vector vSolutions; - if (!Solver(scriptPubKey, typeRet, vSolutions)) + typeRet = Solver(scriptPubKey, vSolutions); + if (typeRet == TX_NONSTANDARD) { return false; - if (typeRet == TX_NULL_DATA){ + } else if (typeRet == TX_NULL_DATA) { // This is data, not addresses return false; } @@ -324,14 +311,12 @@ CScript GetScriptForMultisig(int nRequired, const std::vector& keys) CScript GetScriptForWitness(const CScript& redeemscript) { - txnouttype typ; std::vector > vSolutions; - if (Solver(redeemscript, typ, vSolutions)) { - if (typ == TX_PUBKEY) { - return GetScriptForDestination(WitnessV0KeyHash(Hash160(vSolutions[0].begin(), vSolutions[0].end()))); - } else if (typ == TX_PUBKEYHASH) { - return GetScriptForDestination(WitnessV0KeyHash(vSolutions[0])); - } + txnouttype typ = Solver(redeemscript, vSolutions); + if (typ == TX_PUBKEY) { + return GetScriptForDestination(WitnessV0KeyHash(Hash160(vSolutions[0].begin(), vSolutions[0].end()))); + } else if (typ == TX_PUBKEYHASH) { + return GetScriptForDestination(WitnessV0KeyHash(vSolutions[0])); } return GetScriptForDestination(WitnessV0ScriptHash(redeemscript)); } diff --git a/src/script/standard.h b/src/script/standard.h index 1380030871..4728b056dd 100644 --- a/src/script/standard.h +++ b/src/script/standard.h @@ -135,11 +135,10 @@ const char* GetTxnOutputType(txnouttype t); * script hash, for P2PKH it will contain the key hash, etc. * * @param[in] scriptPubKey Script to parse - * @param[out] typeRet The script type * @param[out] vSolutionsRet Vector of parsed pubkeys and hashes - * @return True if script matches standard template + * @return The script type. TX_NONSTANDARD represents a failed solve. */ -bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector >& vSolutionsRet); +txnouttype Solver(const CScript& scriptPubKey, std::vector>& vSolutionsRet); /** * Parse a standard scriptPubKey for the destination address. Assigns result to diff --git a/src/test/script_standard_tests.cpp b/src/test/script_standard_tests.cpp index 7d4734986a..ded0a8ac1a 100644 --- a/src/test/script_standard_tests.cpp +++ b/src/test/script_standard_tests.cpp @@ -25,22 +25,19 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success) } CScript s; - txnouttype whichType; std::vector > solutions; // TX_PUBKEY s.clear(); s << ToByteVector(pubkeys[0]) << OP_CHECKSIG; - BOOST_CHECK(Solver(s, whichType, solutions)); - BOOST_CHECK_EQUAL(whichType, TX_PUBKEY); + BOOST_CHECK_EQUAL(Solver(s, solutions), TX_PUBKEY); BOOST_CHECK_EQUAL(solutions.size(), 1U); BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0])); // TX_PUBKEYHASH s.clear(); s << OP_DUP << OP_HASH160 << ToByteVector(pubkeys[0].GetID()) << OP_EQUALVERIFY << OP_CHECKSIG; - BOOST_CHECK(Solver(s, whichType, solutions)); - BOOST_CHECK_EQUAL(whichType, TX_PUBKEYHASH); + BOOST_CHECK_EQUAL(Solver(s, solutions), TX_PUBKEYHASH); BOOST_CHECK_EQUAL(solutions.size(), 1U); BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0].GetID())); @@ -48,8 +45,7 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success) CScript redeemScript(s); // initialize with leftover P2PKH script s.clear(); s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL; - BOOST_CHECK(Solver(s, whichType, solutions)); - BOOST_CHECK_EQUAL(whichType, TX_SCRIPTHASH); + BOOST_CHECK_EQUAL(Solver(s, solutions), TX_SCRIPTHASH); BOOST_CHECK_EQUAL(solutions.size(), 1U); BOOST_CHECK(solutions[0] == ToByteVector(CScriptID(redeemScript))); @@ -59,8 +55,7 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success) ToByteVector(pubkeys[0]) << ToByteVector(pubkeys[1]) << OP_2 << OP_CHECKMULTISIG; - BOOST_CHECK(Solver(s, whichType, solutions)); - BOOST_CHECK_EQUAL(whichType, TX_MULTISIG); + BOOST_CHECK_EQUAL(Solver(s, solutions), TX_MULTISIG); BOOST_CHECK_EQUAL(solutions.size(), 4U); BOOST_CHECK(solutions[0] == std::vector({1})); BOOST_CHECK(solutions[1] == ToByteVector(pubkeys[0])); @@ -73,8 +68,7 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success) ToByteVector(pubkeys[1]) << ToByteVector(pubkeys[2]) << OP_3 << OP_CHECKMULTISIG; - BOOST_CHECK(Solver(s, whichType, solutions)); - BOOST_CHECK_EQUAL(whichType, TX_MULTISIG); + BOOST_CHECK_EQUAL(Solver(s, solutions), TX_MULTISIG); BOOST_CHECK_EQUAL(solutions.size(), 5U); BOOST_CHECK(solutions[0] == std::vector({2})); BOOST_CHECK(solutions[1] == ToByteVector(pubkeys[0])); @@ -88,15 +82,13 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success) std::vector({0}) << std::vector({75}) << std::vector({255}); - BOOST_CHECK(Solver(s, whichType, solutions)); - BOOST_CHECK_EQUAL(whichType, TX_NULL_DATA); + BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NULL_DATA); BOOST_CHECK_EQUAL(solutions.size(), 0U); // TX_WITNESS_V0_KEYHASH s.clear(); s << OP_0 << ToByteVector(pubkeys[0].GetID()); - BOOST_CHECK(Solver(s, whichType, solutions)); - BOOST_CHECK_EQUAL(whichType, TX_WITNESS_V0_KEYHASH); + BOOST_CHECK_EQUAL(Solver(s, solutions), TX_WITNESS_V0_KEYHASH); BOOST_CHECK_EQUAL(solutions.size(), 1U); BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0].GetID())); @@ -107,16 +99,14 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success) s.clear(); s << OP_0 << ToByteVector(scriptHash); - BOOST_CHECK(Solver(s, whichType, solutions)); - BOOST_CHECK_EQUAL(whichType, TX_WITNESS_V0_SCRIPTHASH); + BOOST_CHECK_EQUAL(Solver(s, solutions), TX_WITNESS_V0_SCRIPTHASH); BOOST_CHECK_EQUAL(solutions.size(), 1U); BOOST_CHECK(solutions[0] == ToByteVector(scriptHash)); // TX_NONSTANDARD s.clear(); s << OP_9 << OP_ADD << OP_11 << OP_EQUAL; - BOOST_CHECK(!Solver(s, whichType, solutions)); - BOOST_CHECK_EQUAL(whichType, TX_NONSTANDARD); + BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD); } BOOST_AUTO_TEST_CASE(script_standard_Solver_failure) @@ -127,53 +117,52 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_failure) pubkey = key.GetPubKey(); CScript s; - txnouttype whichType; std::vector > solutions; // TX_PUBKEY with incorrectly sized pubkey s.clear(); s << std::vector(30, 0x01) << OP_CHECKSIG; - BOOST_CHECK(!Solver(s, whichType, solutions)); + BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD); // TX_PUBKEYHASH with incorrectly sized key hash s.clear(); s << OP_DUP << OP_HASH160 << ToByteVector(pubkey) << OP_EQUALVERIFY << OP_CHECKSIG; - BOOST_CHECK(!Solver(s, whichType, solutions)); + BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD); // TX_SCRIPTHASH with incorrectly sized script hash s.clear(); s << OP_HASH160 << std::vector(21, 0x01) << OP_EQUAL; - BOOST_CHECK(!Solver(s, whichType, solutions)); + BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD); // TX_MULTISIG 0/2 s.clear(); s << OP_0 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG; - BOOST_CHECK(!Solver(s, whichType, solutions)); + BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD); // TX_MULTISIG 2/1 s.clear(); s << OP_2 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG; - BOOST_CHECK(!Solver(s, whichType, solutions)); + BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD); // TX_MULTISIG n = 2 with 1 pubkey s.clear(); s << OP_1 << ToByteVector(pubkey) << OP_2 << OP_CHECKMULTISIG; - BOOST_CHECK(!Solver(s, whichType, solutions)); + BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD); // TX_MULTISIG n = 1 with 0 pubkeys s.clear(); s << OP_1 << OP_1 << OP_CHECKMULTISIG; - BOOST_CHECK(!Solver(s, whichType, solutions)); + BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD); // TX_NULL_DATA with other opcodes s.clear(); s << OP_RETURN << std::vector({75}) << OP_ADD; - BOOST_CHECK(!Solver(s, whichType, solutions)); + BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD); // TX_WITNESS with incorrect program size s.clear(); s << OP_0 << std::vector(19, 0x01); - BOOST_CHECK(!Solver(s, whichType, solutions)); + BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD); } BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 73dfebf114..eb1e5ba3fb 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4021,9 +4021,8 @@ class DescribeWalletAddressVisitor : public boost::static_visitor void ProcessSubScript(const CScript& subscript, UniValue& obj, bool include_addresses = false) const { // Always present: script type and redeemscript - txnouttype which_type; std::vector> solutions_data; - Solver(subscript, which_type, solutions_data); + txnouttype which_type = Solver(subscript, solutions_data); obj.pushKV("script", GetTxnOutputType(which_type)); obj.pushKV("hex", HexStr(subscript.begin(), subscript.end())); From 6d5fcad576962e5950641f7e7b113a6ac6f397e5 Mon Sep 17 00:00:00 2001 From: Cristian Mircea Messel Date: Wed, 16 May 2018 23:05:09 +0300 Subject: [PATCH 0010/1200] [gui] Make proxy icon from statusbar clickable Clicking on the proxy icon will open settings showing the network tab Create enum Tab in OptionsModel Use new connect syntax Use lambda for private slots --- src/qt/bitcoingui.cpp | 32 +++++++++++++++++++------------- src/qt/bitcoingui.h | 16 +++++++++++----- src/qt/optionsdialog.cpp | 10 ++++++++++ src/qt/optionsdialog.h | 6 ++++++ 4 files changed, 46 insertions(+), 18 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 2438361a58..a26bacd5dd 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -146,7 +146,7 @@ BitcoinGUI::BitcoinGUI(interfaces::Node& node, const PlatformStyle *_platformSty unitDisplayControl = new UnitDisplayStatusBarControl(platformStyle); labelWalletEncryptionIcon = new QLabel(); labelWalletHDStatusIcon = new QLabel(); - labelProxyIcon = new QLabel(); + labelProxyIcon = new GUIUtil::ClickableLabel(); connectionsControl = new GUIUtil::ClickableLabel(); labelBlocksIcon = new GUIUtil::ClickableLabel(); if(enableWallet) @@ -193,7 +193,12 @@ BitcoinGUI::BitcoinGUI(interfaces::Node& node, const PlatformStyle *_platformSty // Subscribe to notifications from core subscribeToCoreSignals(); - connect(connectionsControl, SIGNAL(clicked(QPoint)), this, SLOT(toggleNetworkActive())); + connect(connectionsControl, &GUIUtil::ClickableLabel::clicked, [this] { + m_node.setNetworkActive(!m_node.getNetworkActive()); + }); + connect(labelProxyIcon, &GUIUtil::ClickableLabel::clicked, [this] { + openOptionsDialogWithTab(OptionsDialog::TAB_NETWORK); + }); modalOverlay = new ModalOverlay(this->centralWidget()); #ifdef ENABLE_WALLET @@ -635,12 +640,7 @@ void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason) void BitcoinGUI::optionsClicked() { - if(!clientModel || !clientModel->getOptionsModel()) - return; - - OptionsDialog dlg(this, enableWallet); - dlg.setModel(clientModel->getOptionsModel()); - dlg.exec(); + openOptionsDialogWithTab(OptionsDialog::TAB_MAIN); } void BitcoinGUI::aboutClicked() @@ -764,6 +764,17 @@ void BitcoinGUI::updateHeadersSyncProgressLabel() progressBarLabel->setText(tr("Syncing Headers (%1%)...").arg(QString::number(100.0 / (headersTipHeight+estHeadersLeft)*headersTipHeight, 'f', 1))); } +void BitcoinGUI::openOptionsDialogWithTab(OptionsDialog::Tab tab) +{ + if (!clientModel || !clientModel->getOptionsModel()) + return; + + OptionsDialog dlg(this, enableWallet); + dlg.setCurrentTab(tab); + dlg.setModel(clientModel->getOptionsModel()); + dlg.exec(); +} + void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, bool header) { if (modalOverlay) @@ -1231,11 +1242,6 @@ void BitcoinGUI::unsubscribeFromCoreSignals() m_handler_question->disconnect(); } -void BitcoinGUI::toggleNetworkActive() -{ - m_node.setNetworkActive(!m_node.getNetworkActive()); -} - UnitDisplayStatusBarControl::UnitDisplayStatusBarControl(const PlatformStyle *platformStyle) : optionsModel(0), menu(0) diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 4deeb325b3..2b4c19ec59 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -9,6 +9,8 @@ #include #endif +#include + #include #include @@ -45,6 +47,10 @@ class QProgressBar; class QProgressDialog; QT_END_NAMESPACE +namespace GUIUtil { +class ClickableLabel; +} + /** Bitcoin GUI main class. This class represents the main window of the Bitcoin UI. It communicates with both the client and wallet models to give the user an up-to-date view of the current core state. @@ -93,8 +99,8 @@ class BitcoinGUI : public QMainWindow UnitDisplayStatusBarControl* unitDisplayControl = nullptr; QLabel* labelWalletEncryptionIcon = nullptr; QLabel* labelWalletHDStatusIcon = nullptr; - QLabel* labelProxyIcon = nullptr; - QLabel* connectionsControl = nullptr; + GUIUtil::ClickableLabel* labelProxyIcon = nullptr; + GUIUtil::ClickableLabel* connectionsControl = nullptr; QLabel* labelBlocksIcon = nullptr; QLabel* progressBarLabel = nullptr; QProgressBar* progressBar = nullptr; @@ -166,6 +172,9 @@ class BitcoinGUI : public QMainWindow void updateHeadersSyncProgressLabel(); + /** Open the OptionsDialog on the specified tab index */ + void openOptionsDialogWithTab(OptionsDialog::Tab tab); + Q_SIGNALS: /** Signal raised when a URI was entered or dragged to the GUI */ void receivedURI(const QString &uri); @@ -266,9 +275,6 @@ private Q_SLOTS: /** When hideTrayIcon setting is changed in OptionsModel hide or show the icon accordingly. */ void setTrayIconVisible(bool); - /** Toggle networking */ - void toggleNetworkActive(); - void showModalOverlay(); }; diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index a57343f036..79f4f7777a 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -170,6 +170,16 @@ void OptionsDialog::setModel(OptionsModel *_model) connect(ui->thirdPartyTxUrls, SIGNAL(textChanged(const QString &)), this, SLOT(showRestartWarning())); } +void OptionsDialog::setCurrentTab(OptionsDialog::Tab tab) +{ + QWidget *tab_widget = nullptr; + if (tab == OptionsDialog::Tab::TAB_NETWORK) tab_widget = ui->tabNetwork; + if (tab == OptionsDialog::Tab::TAB_MAIN) tab_widget = ui->tabMain; + if (tab_widget && ui->tabWidget->currentWidget() != tab_widget) { + ui->tabWidget->setCurrentWidget(tab_widget); + } +} + void OptionsDialog::setMapper() { /* Main */ diff --git a/src/qt/optionsdialog.h b/src/qt/optionsdialog.h index 5aad484ce7..482f61658e 100644 --- a/src/qt/optionsdialog.h +++ b/src/qt/optionsdialog.h @@ -40,8 +40,14 @@ class OptionsDialog : public QDialog explicit OptionsDialog(QWidget *parent, bool enableWallet); ~OptionsDialog(); + enum Tab { + TAB_MAIN, + TAB_NETWORK, + }; + void setModel(OptionsModel *model); void setMapper(); + void setCurrentTab(OptionsDialog::Tab tab); private Q_SLOTS: /* set OK button state (enabled / disabled) */ From 1ac3c983bfe06f75542e4f4e30142952802a46d8 Mon Sep 17 00:00:00 2001 From: practicalswift Date: Thu, 26 Jul 2018 17:15:32 +0200 Subject: [PATCH 0011/1200] Mark single-argument constructors "explicit" --- src/interfaces/handler.cpp | 2 +- src/interfaces/wallet.cpp | 4 ++-- src/key_io.cpp | 2 +- src/qt/addresstablemodel.cpp | 2 +- src/qt/rpcconsole.cpp | 2 +- src/qt/transactiontablemodel.cpp | 2 +- src/test/miner_tests.cpp | 2 +- src/test/validation_block_tests.cpp | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/interfaces/handler.cpp b/src/interfaces/handler.cpp index 80f461f4d3..ddf9b342d8 100644 --- a/src/interfaces/handler.cpp +++ b/src/interfaces/handler.cpp @@ -15,7 +15,7 @@ namespace { class HandlerImpl : public Handler { public: - HandlerImpl(boost::signals2::connection connection) : m_connection(std::move(connection)) {} + explicit HandlerImpl(boost::signals2::connection connection) : m_connection(std::move(connection)) {} void disconnect() override { m_connection.disconnect(); } diff --git a/src/interfaces/wallet.cpp b/src/interfaces/wallet.cpp index 28081c7c2c..ea6f5740ac 100644 --- a/src/interfaces/wallet.cpp +++ b/src/interfaces/wallet.cpp @@ -31,7 +31,7 @@ namespace { class PendingWalletTxImpl : public PendingWalletTx { public: - PendingWalletTxImpl(CWallet& wallet) : m_wallet(wallet), m_key(&wallet) {} + explicit PendingWalletTxImpl(CWallet& wallet) : m_wallet(wallet), m_key(&wallet) {} const CTransaction& get() override { return *m_tx; } @@ -117,7 +117,7 @@ WalletTxOut MakeWalletTxOut(CWallet& wallet, const CWalletTx& wtx, int n, int de class WalletImpl : public Wallet { public: - WalletImpl(const std::shared_ptr& wallet) : m_shared_wallet(wallet), m_wallet(*wallet.get()) {} + explicit WalletImpl(const std::shared_ptr& wallet) : m_shared_wallet(wallet), m_wallet(*wallet.get()) {} bool encryptWallet(const SecureString& wallet_passphrase) override { diff --git a/src/key_io.cpp b/src/key_io.cpp index c2dc511989..99a65830cd 100644 --- a/src/key_io.cpp +++ b/src/key_io.cpp @@ -24,7 +24,7 @@ class DestinationEncoder : public boost::static_visitor const CChainParams& m_params; public: - DestinationEncoder(const CChainParams& params) : m_params(params) {} + explicit DestinationEncoder(const CChainParams& params) : m_params(params) {} std::string operator()(const CKeyID& id) const { diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index 25b615e6f8..eb5cbd8890 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -71,7 +71,7 @@ class AddressTablePriv QList cachedAddressTable; AddressTableModel *parent; - AddressTablePriv(AddressTableModel *_parent): + explicit AddressTablePriv(AddressTableModel *_parent): parent(_parent) {} void refreshAddressTable(interfaces::Wallet& wallet) diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index f222357f27..4411bfaa33 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -82,7 +82,7 @@ class RPCExecutor : public QObject { Q_OBJECT public: - RPCExecutor(interfaces::Node& node) : m_node(node) {} + explicit RPCExecutor(interfaces::Node& node) : m_node(node) {} public Q_SLOTS: void request(const QString &command, const QString &walletID); diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 63a4afe191..dddae46c45 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -58,7 +58,7 @@ struct TxLessThan class TransactionTablePriv { public: - TransactionTablePriv(TransactionTableModel *_parent) : + explicit TransactionTablePriv(TransactionTableModel *_parent) : parent(_parent) { } diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 10c7fd00e8..c98320d1a6 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -29,7 +29,7 @@ BOOST_FIXTURE_TEST_SUITE(miner_tests, TestingSetup) // BOOST_CHECK_EXCEPTION predicates to check the specific validation error class HasReason { public: - HasReason(const std::string& reason) : m_reason(reason) {} + explicit HasReason(const std::string& reason) : m_reason(reason) {} bool operator() (const std::runtime_error& e) const { return std::string(e.what()).find(m_reason) != std::string::npos; }; diff --git a/src/test/validation_block_tests.cpp b/src/test/validation_block_tests.cpp index 37c4f79133..4316f37999 100644 --- a/src/test/validation_block_tests.cpp +++ b/src/test/validation_block_tests.cpp @@ -23,7 +23,7 @@ BOOST_FIXTURE_TEST_SUITE(validation_block_tests, RegtestingSetup) struct TestSubscriber : public CValidationInterface { uint256 m_expected_tip; - TestSubscriber(uint256 tip) : m_expected_tip(tip) {} + explicit TestSubscriber(uint256 tip) : m_expected_tip(tip) {} void UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload) override { From 23f434378153cf764230066662f3ec3ad614ff30 Mon Sep 17 00:00:00 2001 From: Ben Woosley Date: Wed, 11 Jul 2018 01:17:59 -0400 Subject: [PATCH 0012/1200] Add CMerkleTx::IsImmatureCoinBase method All but one call to GetBlocksToMaturity is testing it relative to 0 for the purposes of determining whether the coinbase tx is immature. In such case, the value greater than 0 implies that the tx is coinbase, so there is no need to separately test that status. This names the concept for easy singular use. --- src/wallet/rpcwallet.cpp | 4 ++-- src/wallet/wallet.cpp | 21 ++++++++++++--------- src/wallet/wallet.h | 7 +++++++ 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 73dfebf114..84fd55edef 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1851,7 +1851,7 @@ static void ListTransactions(CWallet* const pwallet, const CWalletTx& wtx, const { if (wtx.GetDepthInMainChain() < 1) entry.pushKV("category", "orphan"); - else if (wtx.GetBlocksToMaturity() > 0) + else if (wtx.IsImmatureCoinBase()) entry.pushKV("category", "immature"); else entry.pushKV("category", "generate"); @@ -2147,7 +2147,7 @@ static UniValue listaccounts(const JSONRPCRequest& request) std::list listReceived; std::list listSent; int nDepth = wtx.GetDepthInMainChain(); - if (wtx.GetBlocksToMaturity() > 0 || nDepth < 0) + if (wtx.IsImmatureCoinBase() || nDepth < 0) continue; wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount, includeWatchonly); mapAccountBalances[strSentAccount] -= nFee; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 3ec6aefaec..540a7b0fc6 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1894,7 +1894,7 @@ CAmount CWalletTx::GetDebit(const isminefilter& filter) const CAmount CWalletTx::GetCredit(const isminefilter& filter) const { // Must wait until coinbase is safely deep enough in the chain before valuing it - if (IsCoinBase() && GetBlocksToMaturity() > 0) + if (IsImmatureCoinBase()) return 0; CAmount credit = 0; @@ -1926,8 +1926,7 @@ CAmount CWalletTx::GetCredit(const isminefilter& filter) const CAmount CWalletTx::GetImmatureCredit(bool fUseCache) const { - if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain()) - { + if (IsImmatureCoinBase() && IsInMainChain()) { if (fUseCache && fImmatureCreditCached) return nImmatureCreditCached; nImmatureCreditCached = pwallet->GetCredit(*tx, ISMINE_SPENDABLE); @@ -1944,7 +1943,7 @@ CAmount CWalletTx::GetAvailableCredit(bool fUseCache, const isminefilter& filter return 0; // Must wait until coinbase is safely deep enough in the chain before valuing it - if (IsCoinBase() && GetBlocksToMaturity() > 0) + if (IsImmatureCoinBase()) return 0; CAmount* cache = nullptr; @@ -1985,8 +1984,7 @@ CAmount CWalletTx::GetAvailableCredit(bool fUseCache, const isminefilter& filter CAmount CWalletTx::GetImmatureWatchOnlyCredit(const bool fUseCache) const { - if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain()) - { + if (IsImmatureCoinBase() && IsInMainChain()) { if (fUseCache && fImmatureWatchCreditCached) return nImmatureWatchCreditCached; nImmatureWatchCreditCached = pwallet->GetCredit(*tx, ISMINE_WATCH_ONLY); @@ -2199,7 +2197,7 @@ CAmount CWallet::GetLegacyBalance(const isminefilter& filter, int minDepth, cons for (const auto& entry : mapWallet) { const CWalletTx& wtx = entry.second; const int depth = wtx.GetDepthInMainChain(); - if (depth < 0 || !CheckFinalTx(*wtx.tx) || wtx.GetBlocksToMaturity() > 0) { + if (depth < 0 || !CheckFinalTx(*wtx.tx) || wtx.IsImmatureCoinBase()) { continue; } @@ -2259,7 +2257,7 @@ void CWallet::AvailableCoins(std::vector &vCoins, bool fOnlySafe, const if (!CheckFinalTx(*pcoin->tx)) continue; - if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0) + if (pcoin->IsImmatureCoinBase()) continue; int nDepth = pcoin->GetDepthInMainChain(); @@ -3521,7 +3519,7 @@ std::map CWallet::GetAddressBalances() if (!pcoin->IsTrusted()) continue; - if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0) + if (pcoin->IsImmatureCoinBase()) continue; int nDepth = pcoin->GetDepthInMainChain(); @@ -4397,6 +4395,11 @@ int CMerkleTx::GetBlocksToMaturity() const return std::max(0, (COINBASE_MATURITY+1) - GetDepthInMainChain()); } +bool CMerkleTx::IsImmatureCoinBase() const +{ + // note GetBlocksToMaturity is 0 for non-coinbase tx + return GetBlocksToMaturity() > 0; +} bool CWalletTx::AcceptToMemoryPool(const CAmount& nAbsurdFee, CValidationState& state) { diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 2ada233514..8253dc1eba 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -266,6 +266,12 @@ class CMerkleTx */ int GetDepthInMainChain() const; bool IsInMainChain() const { return GetDepthInMainChain() > 0; } + + /** + * @return number of blocks to maturity for this transaction: + * 0 : is not a coinbase transaction, or is a mature coinbase transaction + * >0 : is a coinbase transaction which matures in this many blocks + */ int GetBlocksToMaturity() const; bool hashUnset() const { return (hashBlock.IsNull() || hashBlock == ABANDON_HASH); } bool isAbandoned() const { return (hashBlock == ABANDON_HASH); } @@ -273,6 +279,7 @@ class CMerkleTx const uint256& GetHash() const { return tx->GetHash(); } bool IsCoinBase() const { return tx->IsCoinBase(); } + bool IsImmatureCoinBase() const; }; //Get the marginal bytes of spending the specified output From ddd395f968a050be5dd0ae21ba7d189b6b7f73fd Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 28 Jul 2018 20:55:32 -0400 Subject: [PATCH 0013/1200] Mark CTxMemPoolEntry members that should not be modified const --- src/txmempool.cpp | 7 ++----- src/txmempool.h | 16 ++++++++-------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/txmempool.cpp b/src/txmempool.cpp index d68c38ad4e..257c88e5b2 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -20,13 +20,10 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTransactionRef& _tx, const CAmount& _nFee, int64_t _nTime, unsigned int _entryHeight, - bool _spendsCoinbase, int64_t _sigOpsCost, LockPoints lp): - tx(_tx), nFee(_nFee), nTime(_nTime), entryHeight(_entryHeight), + bool _spendsCoinbase, int64_t _sigOpsCost, LockPoints lp) + : tx(_tx), nFee(_nFee), nTxWeight(GetTransactionWeight(*tx)), nUsageSize(RecursiveDynamicUsage(tx)), nTime(_nTime), entryHeight(_entryHeight), spendsCoinbase(_spendsCoinbase), sigOpCost(_sigOpsCost), lockPoints(lp) { - nTxWeight = GetTransactionWeight(*tx); - nUsageSize = RecursiveDynamicUsage(tx); - nCountWithDescendants = 1; nSizeWithDescendants = GetTxSize(); nModFeesWithDescendants = nFee; diff --git a/src/txmempool.h b/src/txmempool.h index 0feea08f0b..2003783952 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -64,14 +64,14 @@ class CTxMemPool; class CTxMemPoolEntry { private: - CTransactionRef tx; - CAmount nFee; //!< Cached to avoid expensive parent-transaction lookups - size_t nTxWeight; //!< ... and avoid recomputing tx weight (also used for GetTxSize()) - size_t nUsageSize; //!< ... and total memory usage - int64_t nTime; //!< Local time when entering the mempool - unsigned int entryHeight; //!< Chain height when entering the mempool - bool spendsCoinbase; //!< keep track of transactions that spend a coinbase - int64_t sigOpCost; //!< Total sigop cost + const CTransactionRef tx; + const CAmount nFee; //!< Cached to avoid expensive parent-transaction lookups + const size_t nTxWeight; //!< ... and avoid recomputing tx weight (also used for GetTxSize()) + const size_t nUsageSize; //!< ... and total memory usage + const int64_t nTime; //!< Local time when entering the mempool + const unsigned int entryHeight; //!< Chain height when entering the mempool + const bool spendsCoinbase; //!< keep track of transactions that spend a coinbase + const int64_t sigOpCost; //!< Total sigop cost int64_t feeDelta; //!< Used for determining the priority of the transaction for mining in a block LockPoints lockPoints; //!< Track the height and time at which tx was final From fe5c49766c0dc5beaf186d77b568361242b20d5e Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 28 Jul 2018 21:10:02 -0400 Subject: [PATCH 0014/1200] tx pool: Use the entry's hash instead of the one passed to addUnchecked --- src/txmempool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 257c88e5b2..4d04b6ef6d 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -364,7 +364,7 @@ void CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, // Update transaction for any feeDelta created by PrioritiseTransaction // TODO: refactor so that the fee delta is calculated before inserting // into mapTx. - std::map::const_iterator pos = mapDeltas.find(hash); + std::map::const_iterator pos = mapDeltas.find(entry.GetTx().GetHash()); if (pos != mapDeltas.end()) { const CAmount &delta = pos->second; if (delta) { From fa587773e59721e187cadc998f4dc236ad3aef0b Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 30 Jul 2018 09:11:13 -0400 Subject: [PATCH 0015/1200] scripted-diff: Remove unused first argument to addUnchecked -BEGIN VERIFY SCRIPT- git grep -l addUnchecked | xargs sed --regexp-extended -i -e 's/addUnchecked\([^)][^,]+,\s*/addUnchecked(/g' -END VERIFY SCRIPT- --- src/bench/mempool_eviction.cpp | 2 +- src/test/blockencodings_tests.cpp | 6 +-- src/test/mempool_tests.cpp | 84 +++++++++++++++--------------- src/test/miner_tests.cpp | 48 ++++++++--------- src/test/policyestimator_tests.cpp | 6 +-- src/txmempool.cpp | 6 +-- src/txmempool.h | 4 +- src/validation.cpp | 2 +- 8 files changed, 79 insertions(+), 79 deletions(-) diff --git a/src/bench/mempool_eviction.cpp b/src/bench/mempool_eviction.cpp index d37291b900..4c5489fdc0 100644 --- a/src/bench/mempool_eviction.cpp +++ b/src/bench/mempool_eviction.cpp @@ -16,7 +16,7 @@ static void AddTx(const CTransactionRef& tx, const CAmount& nFee, CTxMemPool& po bool spendsCoinbase = false; unsigned int sigOpCost = 4; LockPoints lp; - pool.addUnchecked(tx->GetHash(), CTxMemPoolEntry( + pool.addUnchecked(CTxMemPoolEntry( tx, nFee, nTime, nHeight, spendsCoinbase, sigOpCost, lp)); } diff --git a/src/test/blockencodings_tests.cpp b/src/test/blockencodings_tests.cpp index df839884fe..e33c449051 100644 --- a/src/test/blockencodings_tests.cpp +++ b/src/test/blockencodings_tests.cpp @@ -63,7 +63,7 @@ BOOST_AUTO_TEST_CASE(SimpleRoundTripTest) CBlock block(BuildBlockTestCase()); LOCK(pool.cs); - pool.addUnchecked(block.vtx[2]->GetHash(), entry.FromTx(block.vtx[2])); + pool.addUnchecked(entry.FromTx(block.vtx[2])); BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 0); // Do a simple ShortTxIDs RT @@ -163,7 +163,7 @@ BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest) CBlock block(BuildBlockTestCase()); LOCK(pool.cs); - pool.addUnchecked(block.vtx[2]->GetHash(), entry.FromTx(block.vtx[2])); + pool.addUnchecked(entry.FromTx(block.vtx[2])); BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 0); uint256 txhash; @@ -233,7 +233,7 @@ BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest) CBlock block(BuildBlockTestCase()); LOCK(pool.cs); - pool.addUnchecked(block.vtx[1]->GetHash(), entry.FromTx(block.vtx[1])); + pool.addUnchecked(entry.FromTx(block.vtx[1])); BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[1]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 0); uint256 txhash; diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp index fb80599af7..b9970b9e6b 100644 --- a/src/test/mempool_tests.cpp +++ b/src/test/mempool_tests.cpp @@ -63,17 +63,17 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest) BOOST_CHECK_EQUAL(testPool.size(), poolSize); // Just the parent: - testPool.addUnchecked(txParent.GetHash(), entry.FromTx(txParent)); + testPool.addUnchecked(entry.FromTx(txParent)); poolSize = testPool.size(); testPool.removeRecursive(txParent); BOOST_CHECK_EQUAL(testPool.size(), poolSize - 1); // Parent, children, grandchildren: - testPool.addUnchecked(txParent.GetHash(), entry.FromTx(txParent)); + testPool.addUnchecked(entry.FromTx(txParent)); for (int i = 0; i < 3; i++) { - testPool.addUnchecked(txChild[i].GetHash(), entry.FromTx(txChild[i])); - testPool.addUnchecked(txGrandChild[i].GetHash(), entry.FromTx(txGrandChild[i])); + testPool.addUnchecked(entry.FromTx(txChild[i])); + testPool.addUnchecked(entry.FromTx(txGrandChild[i])); } // Remove Child[0], GrandChild[0] should be removed: poolSize = testPool.size(); @@ -95,8 +95,8 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest) // Add children and grandchildren, but NOT the parent (simulate the parent being in a block) for (int i = 0; i < 3; i++) { - testPool.addUnchecked(txChild[i].GetHash(), entry.FromTx(txChild[i])); - testPool.addUnchecked(txGrandChild[i].GetHash(), entry.FromTx(txGrandChild[i])); + testPool.addUnchecked(entry.FromTx(txChild[i])); + testPool.addUnchecked(entry.FromTx(txGrandChild[i])); } // Now remove the parent, as might happen if a block-re-org occurs but the parent cannot be // put into the mempool (maybe because it is non-standard): @@ -128,28 +128,28 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) tx1.vout.resize(1); tx1.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx1.vout[0].nValue = 10 * COIN; - pool.addUnchecked(tx1.GetHash(), entry.Fee(10000LL).FromTx(tx1)); + pool.addUnchecked(entry.Fee(10000LL).FromTx(tx1)); /* highest fee */ CMutableTransaction tx2 = CMutableTransaction(); tx2.vout.resize(1); tx2.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx2.vout[0].nValue = 2 * COIN; - pool.addUnchecked(tx2.GetHash(), entry.Fee(20000LL).FromTx(tx2)); + pool.addUnchecked(entry.Fee(20000LL).FromTx(tx2)); /* lowest fee */ CMutableTransaction tx3 = CMutableTransaction(); tx3.vout.resize(1); tx3.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx3.vout[0].nValue = 5 * COIN; - pool.addUnchecked(tx3.GetHash(), entry.Fee(0LL).FromTx(tx3)); + pool.addUnchecked(entry.Fee(0LL).FromTx(tx3)); /* 2nd highest fee */ CMutableTransaction tx4 = CMutableTransaction(); tx4.vout.resize(1); tx4.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx4.vout[0].nValue = 6 * COIN; - pool.addUnchecked(tx4.GetHash(), entry.Fee(15000LL).FromTx(tx4)); + pool.addUnchecked(entry.Fee(15000LL).FromTx(tx4)); /* equal fee rate to tx1, but newer */ CMutableTransaction tx5 = CMutableTransaction(); @@ -157,7 +157,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) tx5.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx5.vout[0].nValue = 11 * COIN; entry.nTime = 1; - pool.addUnchecked(tx5.GetHash(), entry.Fee(10000LL).FromTx(tx5)); + pool.addUnchecked(entry.Fee(10000LL).FromTx(tx5)); BOOST_CHECK_EQUAL(pool.size(), 5U); std::vector sortedOrder; @@ -175,7 +175,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) tx6.vout.resize(1); tx6.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx6.vout[0].nValue = 20 * COIN; - pool.addUnchecked(tx6.GetHash(), entry.Fee(0LL).FromTx(tx6)); + pool.addUnchecked(entry.Fee(0LL).FromTx(tx6)); BOOST_CHECK_EQUAL(pool.size(), 6U); // Check that at this point, tx6 is sorted low sortedOrder.insert(sortedOrder.begin(), tx6.GetHash().ToString()); @@ -198,7 +198,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) BOOST_CHECK_EQUAL(pool.CalculateMemPoolAncestors(entry.Fee(2000000LL).FromTx(tx7), setAncestorsCalculated, 100, 1000000, 1000, 1000000, dummy), true); BOOST_CHECK(setAncestorsCalculated == setAncestors); - pool.addUnchecked(tx7.GetHash(), entry.FromTx(tx7), setAncestors); + pool.addUnchecked(entry.FromTx(tx7), setAncestors); BOOST_CHECK_EQUAL(pool.size(), 7U); // Now tx6 should be sorted higher (high fee child): tx7, tx6, tx2, ... @@ -216,7 +216,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) tx8.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx8.vout[0].nValue = 10 * COIN; setAncestors.insert(pool.mapTx.find(tx7.GetHash())); - pool.addUnchecked(tx8.GetHash(), entry.Fee(0LL).Time(2).FromTx(tx8), setAncestors); + pool.addUnchecked(entry.Fee(0LL).Time(2).FromTx(tx8), setAncestors); // Now tx8 should be sorted low, but tx6/tx both high sortedOrder.insert(sortedOrder.begin(), tx8.GetHash().ToString()); @@ -230,7 +230,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) tx9.vout.resize(1); tx9.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx9.vout[0].nValue = 1 * COIN; - pool.addUnchecked(tx9.GetHash(), entry.Fee(0LL).Time(3).FromTx(tx9), setAncestors); + pool.addUnchecked(entry.Fee(0LL).Time(3).FromTx(tx9), setAncestors); // tx9 should be sorted low BOOST_CHECK_EQUAL(pool.size(), 9U); @@ -256,7 +256,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) BOOST_CHECK_EQUAL(pool.CalculateMemPoolAncestors(entry.Fee(200000LL).Time(4).FromTx(tx10), setAncestorsCalculated, 100, 1000000, 1000, 1000000, dummy), true); BOOST_CHECK(setAncestorsCalculated == setAncestors); - pool.addUnchecked(tx10.GetHash(), entry.FromTx(tx10), setAncestors); + pool.addUnchecked(entry.FromTx(tx10), setAncestors); /** * tx8 and tx9 should both now be sorted higher @@ -301,14 +301,14 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest) tx1.vout.resize(1); tx1.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx1.vout[0].nValue = 10 * COIN; - pool.addUnchecked(tx1.GetHash(), entry.Fee(10000LL).FromTx(tx1)); + pool.addUnchecked(entry.Fee(10000LL).FromTx(tx1)); /* highest fee */ CMutableTransaction tx2 = CMutableTransaction(); tx2.vout.resize(1); tx2.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx2.vout[0].nValue = 2 * COIN; - pool.addUnchecked(tx2.GetHash(), entry.Fee(20000LL).FromTx(tx2)); + pool.addUnchecked(entry.Fee(20000LL).FromTx(tx2)); uint64_t tx2Size = GetVirtualTransactionSize(tx2); /* lowest fee */ @@ -316,21 +316,21 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest) tx3.vout.resize(1); tx3.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx3.vout[0].nValue = 5 * COIN; - pool.addUnchecked(tx3.GetHash(), entry.Fee(0LL).FromTx(tx3)); + pool.addUnchecked(entry.Fee(0LL).FromTx(tx3)); /* 2nd highest fee */ CMutableTransaction tx4 = CMutableTransaction(); tx4.vout.resize(1); tx4.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx4.vout[0].nValue = 6 * COIN; - pool.addUnchecked(tx4.GetHash(), entry.Fee(15000LL).FromTx(tx4)); + pool.addUnchecked(entry.Fee(15000LL).FromTx(tx4)); /* equal fee rate to tx1, but newer */ CMutableTransaction tx5 = CMutableTransaction(); tx5.vout.resize(1); tx5.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx5.vout[0].nValue = 11 * COIN; - pool.addUnchecked(tx5.GetHash(), entry.Fee(10000LL).FromTx(tx5)); + pool.addUnchecked(entry.Fee(10000LL).FromTx(tx5)); BOOST_CHECK_EQUAL(pool.size(), 5U); std::vector sortedOrder; @@ -359,7 +359,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest) tx6.vout[0].nValue = 20 * COIN; uint64_t tx6Size = GetVirtualTransactionSize(tx6); - pool.addUnchecked(tx6.GetHash(), entry.Fee(0LL).FromTx(tx6)); + pool.addUnchecked(entry.Fee(0LL).FromTx(tx6)); BOOST_CHECK_EQUAL(pool.size(), 6U); // Ties are broken by hash if (tx3.GetHash() < tx6.GetHash()) @@ -381,7 +381,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest) /* set the fee to just below tx2's feerate when including ancestor */ CAmount fee = (20000/tx2Size)*(tx7Size + tx6Size) - 1; - pool.addUnchecked(tx7.GetHash(), entry.Fee(fee).FromTx(tx7)); + pool.addUnchecked(entry.Fee(fee).FromTx(tx7)); BOOST_CHECK_EQUAL(pool.size(), 7U); sortedOrder.insert(sortedOrder.begin()+1, tx7.GetHash().ToString()); CheckSort(pool, sortedOrder); @@ -413,7 +413,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest) // Check that we sort by min(feerate, ancestor_feerate): // set the fee so that the ancestor feerate is above tx1/5, // but the transaction's own feerate is lower - pool.addUnchecked(tx8.GetHash(), entry.Fee(5000LL).FromTx(tx8)); + pool.addUnchecked(entry.Fee(5000LL).FromTx(tx8)); sortedOrder.insert(sortedOrder.end()-1, tx8.GetHash().ToString()); CheckSort(pool, sortedOrder); } @@ -431,7 +431,7 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) tx1.vout.resize(1); tx1.vout[0].scriptPubKey = CScript() << OP_1 << OP_EQUAL; tx1.vout[0].nValue = 10 * COIN; - pool.addUnchecked(tx1.GetHash(), entry.Fee(10000LL).FromTx(tx1)); + pool.addUnchecked(entry.Fee(10000LL).FromTx(tx1)); CMutableTransaction tx2 = CMutableTransaction(); tx2.vin.resize(1); @@ -439,7 +439,7 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) tx2.vout.resize(1); tx2.vout[0].scriptPubKey = CScript() << OP_2 << OP_EQUAL; tx2.vout[0].nValue = 10 * COIN; - pool.addUnchecked(tx2.GetHash(), entry.Fee(5000LL).FromTx(tx2)); + pool.addUnchecked(entry.Fee(5000LL).FromTx(tx2)); pool.TrimToSize(pool.DynamicMemoryUsage()); // should do nothing BOOST_CHECK(pool.exists(tx1.GetHash())); @@ -449,7 +449,7 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) BOOST_CHECK(pool.exists(tx1.GetHash())); BOOST_CHECK(!pool.exists(tx2.GetHash())); - pool.addUnchecked(tx2.GetHash(), entry.FromTx(tx2)); + pool.addUnchecked(entry.FromTx(tx2)); CMutableTransaction tx3 = CMutableTransaction(); tx3.vin.resize(1); tx3.vin[0].prevout = COutPoint(tx2.GetHash(), 0); @@ -457,7 +457,7 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) tx3.vout.resize(1); tx3.vout[0].scriptPubKey = CScript() << OP_3 << OP_EQUAL; tx3.vout[0].nValue = 10 * COIN; - pool.addUnchecked(tx3.GetHash(), entry.Fee(20000LL).FromTx(tx3)); + pool.addUnchecked(entry.Fee(20000LL).FromTx(tx3)); pool.TrimToSize(pool.DynamicMemoryUsage() * 3 / 4); // tx3 should pay for tx2 (CPFP) BOOST_CHECK(!pool.exists(tx1.GetHash())); @@ -520,10 +520,10 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) tx7.vout[1].scriptPubKey = CScript() << OP_7 << OP_EQUAL; tx7.vout[1].nValue = 10 * COIN; - pool.addUnchecked(tx4.GetHash(), entry.Fee(7000LL).FromTx(tx4)); - pool.addUnchecked(tx5.GetHash(), entry.Fee(1000LL).FromTx(tx5)); - pool.addUnchecked(tx6.GetHash(), entry.Fee(1100LL).FromTx(tx6)); - pool.addUnchecked(tx7.GetHash(), entry.Fee(9000LL).FromTx(tx7)); + pool.addUnchecked(entry.Fee(7000LL).FromTx(tx4)); + pool.addUnchecked(entry.Fee(1000LL).FromTx(tx5)); + pool.addUnchecked(entry.Fee(1100LL).FromTx(tx6)); + pool.addUnchecked(entry.Fee(9000LL).FromTx(tx7)); // we only require this to remove, at max, 2 txn, because it's not clear what we're really optimizing for aside from that pool.TrimToSize(pool.DynamicMemoryUsage() - 1); @@ -532,8 +532,8 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) BOOST_CHECK(!pool.exists(tx7.GetHash())); if (!pool.exists(tx5.GetHash())) - pool.addUnchecked(tx5.GetHash(), entry.Fee(1000LL).FromTx(tx5)); - pool.addUnchecked(tx7.GetHash(), entry.Fee(9000LL).FromTx(tx7)); + pool.addUnchecked(entry.Fee(1000LL).FromTx(tx5)); + pool.addUnchecked(entry.Fee(9000LL).FromTx(tx7)); pool.TrimToSize(pool.DynamicMemoryUsage() / 2); // should maximize mempool size by only removing 5/7 BOOST_CHECK(pool.exists(tx4.GetHash())); @@ -541,8 +541,8 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) BOOST_CHECK(pool.exists(tx6.GetHash())); BOOST_CHECK(!pool.exists(tx7.GetHash())); - pool.addUnchecked(tx5.GetHash(), entry.Fee(1000LL).FromTx(tx5)); - pool.addUnchecked(tx7.GetHash(), entry.Fee(9000LL).FromTx(tx7)); + pool.addUnchecked(entry.Fee(1000LL).FromTx(tx5)); + pool.addUnchecked(entry.Fee(9000LL).FromTx(tx7)); std::vector vtx; SetMockTime(42); @@ -603,7 +603,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestryTests) // [tx1] // CTransactionRef tx1 = make_tx(/* output_values */ {10 * COIN}); - pool.addUnchecked(tx1->GetHash(), entry.Fee(10000LL).FromTx(tx1)); + pool.addUnchecked(entry.Fee(10000LL).FromTx(tx1)); // Ancestors / descendants should be 1 / 1 (itself / itself) pool.GetTransactionAncestry(tx1->GetHash(), ancestors, descendants); @@ -615,7 +615,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestryTests) // [tx1].0 <- [tx2] // CTransactionRef tx2 = make_tx(/* output_values */ {495 * CENT, 5 * COIN}, /* inputs */ {tx1}); - pool.addUnchecked(tx2->GetHash(), entry.Fee(10000LL).FromTx(tx2)); + pool.addUnchecked(entry.Fee(10000LL).FromTx(tx2)); // Ancestors / descendants should be: // transaction ancestors descendants @@ -634,7 +634,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestryTests) // [tx1].0 <- [tx2].0 <- [tx3] // CTransactionRef tx3 = make_tx(/* output_values */ {290 * CENT, 200 * CENT}, /* inputs */ {tx2}); - pool.addUnchecked(tx3->GetHash(), entry.Fee(10000LL).FromTx(tx3)); + pool.addUnchecked(entry.Fee(10000LL).FromTx(tx3)); // Ancestors / descendants should be: // transaction ancestors descendants @@ -659,7 +659,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestryTests) // \---1 <- [tx4] // CTransactionRef tx4 = make_tx(/* output_values */ {290 * CENT, 250 * CENT}, /* inputs */ {tx2}, /* input_indices */ {1}); - pool.addUnchecked(tx4->GetHash(), entry.Fee(10000LL).FromTx(tx4)); + pool.addUnchecked(entry.Fee(10000LL).FromTx(tx4)); // Ancestors / descendants should be: // transaction ancestors descendants @@ -696,13 +696,13 @@ BOOST_AUTO_TEST_CASE(MempoolAncestryTests) CTransactionRef& tyi = *ty[i]; tyi = make_tx(/* output_values */ {v}, /* inputs */ i > 0 ? std::vector{*ty[i - 1]} : std::vector{}); v -= 50 * CENT; - pool.addUnchecked(tyi->GetHash(), entry.Fee(10000LL).FromTx(tyi)); + pool.addUnchecked(entry.Fee(10000LL).FromTx(tyi)); pool.GetTransactionAncestry(tyi->GetHash(), ancestors, descendants); BOOST_CHECK_EQUAL(ancestors, i+1); BOOST_CHECK_EQUAL(descendants, i+1); } CTransactionRef ty6 = make_tx(/* output_values */ {5 * COIN}, /* inputs */ {tx3, ty5}); - pool.addUnchecked(ty6->GetHash(), entry.Fee(10000LL).FromTx(ty6)); + pool.addUnchecked(entry.Fee(10000LL).FromTx(ty6)); // Ancestors / descendants should be: // transaction ancestors descendants diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index e2424f012d..5e0d08fa84 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -115,19 +115,19 @@ static void TestPackageSelection(const CChainParams& chainparams, const CScript& tx.vout[0].nValue = 5000000000LL - 1000; // This tx has a low fee: 1000 satoshis uint256 hashParentTx = tx.GetHash(); // save this txid for later use - mempool.addUnchecked(hashParentTx, entry.Fee(1000).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); + mempool.addUnchecked(entry.Fee(1000).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); // This tx has a medium fee: 10000 satoshis tx.vin[0].prevout.hash = txFirst[1]->GetHash(); tx.vout[0].nValue = 5000000000LL - 10000; uint256 hashMediumFeeTx = tx.GetHash(); - mempool.addUnchecked(hashMediumFeeTx, entry.Fee(10000).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); + mempool.addUnchecked(entry.Fee(10000).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); // This tx has a high fee, but depends on the first transaction tx.vin[0].prevout.hash = hashParentTx; tx.vout[0].nValue = 5000000000LL - 1000 - 50000; // 50k satoshi fee uint256 hashHighFeeTx = tx.GetHash(); - mempool.addUnchecked(hashHighFeeTx, entry.Fee(50000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); + mempool.addUnchecked(entry.Fee(50000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); std::unique_ptr pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey); BOOST_CHECK(pblocktemplate->block.vtx[1]->GetHash() == hashParentTx); @@ -138,7 +138,7 @@ static void TestPackageSelection(const CChainParams& chainparams, const CScript& tx.vin[0].prevout.hash = hashHighFeeTx; tx.vout[0].nValue = 5000000000LL - 1000 - 50000; // 0 fee uint256 hashFreeTx = tx.GetHash(); - mempool.addUnchecked(hashFreeTx, entry.Fee(0).FromTx(tx)); + mempool.addUnchecked(entry.Fee(0).FromTx(tx)); size_t freeTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); // Calculate a fee on child transaction that will put the package just @@ -148,7 +148,7 @@ static void TestPackageSelection(const CChainParams& chainparams, const CScript& tx.vin[0].prevout.hash = hashFreeTx; tx.vout[0].nValue = 5000000000LL - 1000 - 50000 - feeToUse; uint256 hashLowFeeTx = tx.GetHash(); - mempool.addUnchecked(hashLowFeeTx, entry.Fee(feeToUse).FromTx(tx)); + mempool.addUnchecked(entry.Fee(feeToUse).FromTx(tx)); pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey); // Verify that the free tx and the low fee tx didn't get selected for (size_t i=0; iblock.vtx.size(); ++i) { @@ -162,7 +162,7 @@ static void TestPackageSelection(const CChainParams& chainparams, const CScript& mempool.removeRecursive(tx); tx.vout[0].nValue -= 2; // Now we should be just over the min relay fee hashLowFeeTx = tx.GetHash(); - mempool.addUnchecked(hashLowFeeTx, entry.Fee(feeToUse+2).FromTx(tx)); + mempool.addUnchecked(entry.Fee(feeToUse+2).FromTx(tx)); pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey); BOOST_CHECK(pblocktemplate->block.vtx[4]->GetHash() == hashFreeTx); BOOST_CHECK(pblocktemplate->block.vtx[5]->GetHash() == hashLowFeeTx); @@ -175,7 +175,7 @@ static void TestPackageSelection(const CChainParams& chainparams, const CScript& tx.vout[0].nValue = 5000000000LL - 100000000; tx.vout[1].nValue = 100000000; // 1BTC output uint256 hashFreeTx2 = tx.GetHash(); - mempool.addUnchecked(hashFreeTx2, entry.Fee(0).SpendsCoinbase(true).FromTx(tx)); + mempool.addUnchecked(entry.Fee(0).SpendsCoinbase(true).FromTx(tx)); // This tx can't be mined by itself tx.vin[0].prevout.hash = hashFreeTx2; @@ -183,7 +183,7 @@ static void TestPackageSelection(const CChainParams& chainparams, const CScript& feeToUse = blockMinFeeRate.GetFee(freeTxSize); tx.vout[0].nValue = 5000000000LL - 100000000 - feeToUse; uint256 hashLowFeeTx2 = tx.GetHash(); - mempool.addUnchecked(hashLowFeeTx2, entry.Fee(feeToUse).SpendsCoinbase(false).FromTx(tx)); + mempool.addUnchecked(entry.Fee(feeToUse).SpendsCoinbase(false).FromTx(tx)); pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey); // Verify that this tx isn't selected. @@ -196,7 +196,7 @@ static void TestPackageSelection(const CChainParams& chainparams, const CScript& // as well. tx.vin[0].prevout.n = 1; tx.vout[0].nValue = 100000000 - 10000; // 10k satoshi fee - mempool.addUnchecked(tx.GetHash(), entry.Fee(10000).FromTx(tx)); + mempool.addUnchecked(entry.Fee(10000).FromTx(tx)); pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey); BOOST_CHECK(pblocktemplate->block.vtx[8]->GetHash() == hashLowFeeTx2); } @@ -277,7 +277,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) hash = tx.GetHash(); bool spendsCoinbase = i == 0; // only first tx spends coinbase // If we don't set the # of sig ops in the CTxMemPoolEntry, template creation fails - mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); + mempool.addUnchecked(entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); tx.vin[0].prevout.hash = hash; } @@ -292,7 +292,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) hash = tx.GetHash(); bool spendsCoinbase = i == 0; // only first tx spends coinbase // If we do set the # of sig ops in the CTxMemPoolEntry, template creation passes - mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).SigOpsCost(80).FromTx(tx)); + mempool.addUnchecked(entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).SigOpsCost(80).FromTx(tx)); tx.vin[0].prevout.hash = hash; } BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); @@ -312,7 +312,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue -= LOWFEE; hash = tx.GetHash(); bool spendsCoinbase = i == 0; // only first tx spends coinbase - mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); + mempool.addUnchecked(entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); tx.vin[0].prevout.hash = hash; } BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); @@ -320,7 +320,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) // orphan in mempool, template creation fails hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).FromTx(tx)); + mempool.addUnchecked(entry.Fee(LOWFEE).Time(GetTime()).FromTx(tx)); BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error, HasReason("bad-txns-inputs-missingorspent")); mempool.clear(); @@ -329,7 +329,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vin[0].prevout.hash = txFirst[1]->GetHash(); tx.vout[0].nValue = BLOCKSUBSIDY-HIGHFEE; hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); + mempool.addUnchecked(entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); tx.vin[0].prevout.hash = hash; tx.vin.resize(2); tx.vin[1].scriptSig = CScript() << OP_1; @@ -337,7 +337,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vin[1].prevout.n = 0; tx.vout[0].nValue = tx.vout[0].nValue+BLOCKSUBSIDY-HIGHERFEE; //First txn output + fresh coinbase - new txn fee hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Fee(HIGHERFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); + mempool.addUnchecked(entry.Fee(HIGHERFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); mempool.clear(); @@ -348,7 +348,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue = 0; hash = tx.GetHash(); // give it a fee so it'll get mined - mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); + mempool.addUnchecked(entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); // Should throw bad-cb-multiple BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error, HasReason("bad-cb-multiple")); mempool.clear(); @@ -359,10 +359,10 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue = BLOCKSUBSIDY-HIGHFEE; tx.vout[0].scriptPubKey = CScript() << OP_1; hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); + mempool.addUnchecked(entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); tx.vout[0].scriptPubKey = CScript() << OP_2; hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); + mempool.addUnchecked(entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error, HasReason("bad-txns-inputs-missingorspent")); mempool.clear(); @@ -401,12 +401,12 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) script = CScript() << OP_0; tx.vout[0].scriptPubKey = GetScriptForDestination(CScriptID(script)); hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); + mempool.addUnchecked(entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); tx.vin[0].prevout.hash = hash; tx.vin[0].scriptSig = CScript() << std::vector(script.begin(), script.end()); tx.vout[0].nValue -= LOWFEE; hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); + mempool.addUnchecked(entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); // Should throw block-validation-failed BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error, HasReason("block-validation-failed")); mempool.clear(); @@ -440,7 +440,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].scriptPubKey = CScript() << OP_1; tx.nLockTime = 0; hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); + mempool.addUnchecked(entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); BOOST_CHECK(CheckFinalTx(tx, flags)); // Locktime passes BOOST_CHECK(!TestSequenceLocks(tx, flags)); // Sequence locks fail BOOST_CHECK(SequenceLocks(tx, flags, &prevheights, CreateBlockIndex(chainActive.Tip()->nHeight + 2))); // Sequence locks pass on 2nd block @@ -450,7 +450,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | (((chainActive.Tip()->GetMedianTimePast()+1-chainActive[1]->GetMedianTimePast()) >> CTxIn::SEQUENCE_LOCKTIME_GRANULARITY) + 1); // txFirst[1] is the 3rd block prevheights[0] = baseheight + 2; hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx)); + mempool.addUnchecked(entry.Time(GetTime()).FromTx(tx)); BOOST_CHECK(CheckFinalTx(tx, flags)); // Locktime passes BOOST_CHECK(!TestSequenceLocks(tx, flags)); // Sequence locks fail @@ -466,7 +466,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) prevheights[0] = baseheight + 3; tx.nLockTime = chainActive.Tip()->nHeight + 1; hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx)); + mempool.addUnchecked(entry.Time(GetTime()).FromTx(tx)); BOOST_CHECK(!CheckFinalTx(tx, flags)); // Locktime fails BOOST_CHECK(TestSequenceLocks(tx, flags)); // Sequence locks pass BOOST_CHECK(IsFinalTx(tx, chainActive.Tip()->nHeight + 2, chainActive.Tip()->GetMedianTimePast())); // Locktime passes on 2nd block @@ -477,7 +477,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) prevheights.resize(1); prevheights[0] = baseheight + 4; hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx)); + mempool.addUnchecked(entry.Time(GetTime()).FromTx(tx)); BOOST_CHECK(!CheckFinalTx(tx, flags)); // Locktime fails BOOST_CHECK(TestSequenceLocks(tx, flags)); // Sequence locks pass BOOST_CHECK(IsFinalTx(tx, chainActive.Tip()->nHeight + 2, chainActive.Tip()->GetMedianTimePast() + 1)); // Locktime passes 1 second later diff --git a/src/test/policyestimator_tests.cpp b/src/test/policyestimator_tests.cpp index e45fb6d17e..df2b1c0fc3 100644 --- a/src/test/policyestimator_tests.cpp +++ b/src/test/policyestimator_tests.cpp @@ -58,7 +58,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) for (int k = 0; k < 4; k++) { // add 4 fee txs tx.vin[0].prevout.n = 10000*blocknum+100*j+k; // make transaction unique uint256 hash = tx.GetHash(); - mpool.addUnchecked(hash, entry.Fee(feeV[j]).Time(GetTime()).Height(blocknum).FromTx(tx)); + mpool.addUnchecked(entry.Fee(feeV[j]).Time(GetTime()).Height(blocknum).FromTx(tx)); txHashes[j].push_back(hash); } } @@ -129,7 +129,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) for (int k = 0; k < 4; k++) { // add 4 fee txs tx.vin[0].prevout.n = 10000*blocknum+100*j+k; uint256 hash = tx.GetHash(); - mpool.addUnchecked(hash, entry.Fee(feeV[j]).Time(GetTime()).Height(blocknum).FromTx(tx)); + mpool.addUnchecked(entry.Fee(feeV[j]).Time(GetTime()).Height(blocknum).FromTx(tx)); txHashes[j].push_back(hash); } } @@ -164,7 +164,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) for (int k = 0; k < 4; k++) { // add 4 fee txs tx.vin[0].prevout.n = 10000*blocknum+100*j+k; uint256 hash = tx.GetHash(); - mpool.addUnchecked(hash, entry.Fee(feeV[j]).Time(GetTime()).Height(blocknum).FromTx(tx)); + mpool.addUnchecked(entry.Fee(feeV[j]).Time(GetTime()).Height(blocknum).FromTx(tx)); CTransactionRef ptx = mpool.get(hash); if (ptx) block.push_back(ptx); diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 4d04b6ef6d..e6cc9abe08 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -352,7 +352,7 @@ void CTxMemPool::AddTransactionsUpdated(unsigned int n) nTransactionsUpdated += n; } -void CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, setEntries &setAncestors, bool validFeeEstimate) +void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, setEntries &setAncestors, bool validFeeEstimate) { NotifyEntryAdded(entry.GetSharedTx()); // Add to memory pool without checking anything. @@ -925,13 +925,13 @@ int CTxMemPool::Expire(int64_t time) { return stage.size(); } -void CTxMemPool::addUnchecked(const uint256&hash, const CTxMemPoolEntry &entry, bool validFeeEstimate) +void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, bool validFeeEstimate) { setEntries setAncestors; uint64_t nNoLimit = std::numeric_limits::max(); std::string dummy; CalculateMemPoolAncestors(entry, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy); - return addUnchecked(hash, entry, setAncestors, validFeeEstimate); + return addUnchecked(entry, setAncestors, validFeeEstimate); } void CTxMemPool::UpdateChild(txiter entry, txiter child, bool add) diff --git a/src/txmempool.h b/src/txmempool.h index 2003783952..13c993e1ba 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -539,8 +539,8 @@ class CTxMemPool // Note that addUnchecked is ONLY called from ATMP outside of tests // and any other callers may break wallet's in-mempool tracking (due to // lack of CValidationInterface::TransactionAddedToMempool callbacks). - void addUnchecked(const uint256& hash, const CTxMemPoolEntry& entry, bool validFeeEstimate = true) EXCLUSIVE_LOCKS_REQUIRED(cs); - void addUnchecked(const uint256& hash, const CTxMemPoolEntry& entry, setEntries& setAncestors, bool validFeeEstimate = true) EXCLUSIVE_LOCKS_REQUIRED(cs); + void addUnchecked(const CTxMemPoolEntry& entry, bool validFeeEstimate = true) EXCLUSIVE_LOCKS_REQUIRED(cs); + void addUnchecked(const CTxMemPoolEntry& entry, setEntries& setAncestors, bool validFeeEstimate = true) EXCLUSIVE_LOCKS_REQUIRED(cs); void removeRecursive(const CTransaction &tx, MemPoolRemovalReason reason = MemPoolRemovalReason::UNKNOWN); void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags); diff --git a/src/validation.cpp b/src/validation.cpp index 702a8d7e05..38469e1f9c 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -974,7 +974,7 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool bool validForFeeEstimation = !fReplacementTransaction && !bypass_limits && IsCurrentForFeeEstimation() && pool.HasNoInputsOf(tx); // Store transaction in memory - pool.addUnchecked(hash, entry, setAncestors, validForFeeEstimation); + pool.addUnchecked(entry, setAncestors, validForFeeEstimation); // trim mempool and check if tx was trimmed if (!bypass_limits) { From 46f83453701fc6116d97de6a16986388ba63488f Mon Sep 17 00:00:00 2001 From: Chun Kuan Lee Date: Thu, 26 Jul 2018 17:35:52 +0800 Subject: [PATCH 0016/1200] contrib: Support github pull request gitian-build --- contrib/gitian-build.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/contrib/gitian-build.py b/contrib/gitian-build.py index 5b8db1e73d..0e53c3dfd5 100755 --- a/contrib/gitian-build.py +++ b/contrib/gitian-build.py @@ -135,6 +135,7 @@ def main(): parser = argparse.ArgumentParser(usage='%(prog)s [options] signer version') parser.add_argument('-c', '--commit', action='store_true', dest='commit', help='Indicate that the version argument is for a commit or branch') + parser.add_argument('-p', '--pull', action='store_true', dest='pull', help='Indicate that the version argument is the number of a github repository pull request') parser.add_argument('-u', '--url', dest='url', default='https://github.com/bitcoin/bitcoin', help='Specify the URL of the repository. Default is %(default)s') parser.add_argument('-v', '--verify', action='store_true', dest='verify', help='Verify the Gitian build') parser.add_argument('-b', '--build', action='store_true', dest='build', help='Do a Gitian build') @@ -196,13 +197,21 @@ def main(): exit(1) # Add leading 'v' for tags + if args.commit and args.pull: + raise Exception('Cannot have both commit and pull') args.commit = ('' if args.commit else 'v') + args.version - print(args.commit) if args.setup: setup() os.chdir('bitcoin') + if args.pull: + subprocess.check_call(['git', 'fetch', args.url, 'refs/pull/'+args.version+'/merge']) + os.chdir('../gitian-builder/inputs/bitcoin') + subprocess.check_call(['git', 'fetch', args.url, 'refs/pull/'+args.version+'/merge']) + args.commit = subprocess.check_output(['git', 'show', '-s', '--format=%H', 'FETCH_HEAD'], universal_newlines=True).strip() + args.version = 'pull-' + args.version + print(args.commit) subprocess.check_call(['git', 'fetch']) subprocess.check_call(['git', 'checkout', args.commit]) os.chdir(workdir) From d795c610d3095eeff1bfe5c1a34877cf0a841823 Mon Sep 17 00:00:00 2001 From: Sjors Provoost Date: Wed, 1 Aug 2018 18:43:46 +0200 Subject: [PATCH 0017/1200] [qt] TransactionView: highlight replacement tx after fee bump --- src/qt/transactionview.cpp | 13 ++++++++++++- src/qt/transactionview.h | 2 ++ src/qt/walletmodel.cpp | 5 ++--- src/qt/walletmodel.h | 2 +- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index e60a387934..2fd2b815aa 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -19,6 +19,7 @@ #include +#include #include #include #include @@ -198,6 +199,11 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa connect(copyTxPlainText, SIGNAL(triggered()), this, SLOT(copyTxPlainText())); connect(editLabelAction, SIGNAL(triggered()), this, SLOT(editLabel())); connect(showDetailsAction, SIGNAL(triggered()), this, SLOT(showDetails())); + + // Highlight transaction after fee bump + connect(this, &TransactionView::bumpedFee, [this](const uint256& txid) { + focusTransaction(txid); + }); } void TransactionView::setModel(WalletModel *_model) @@ -428,9 +434,14 @@ void TransactionView::bumpFee() hash.SetHex(hashQStr.toStdString()); // Bump tx fee over the walletModel - if (model->bumpFee(hash)) { + uint256 newHash; + if (model->bumpFee(hash, newHash)) { // Update the table + transactionView->selectionModel()->clearSelection(); model->getTransactionTableModel()->updateTransaction(hashQStr, CT_UPDATED, true); + + qApp->processEvents(); + Q_EMIT bumpedFee(newHash); } } diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h index 66dc5bc86b..9819fb4325 100644 --- a/src/qt/transactionview.h +++ b/src/qt/transactionview.h @@ -110,6 +110,8 @@ private Q_SLOTS: /** Fired when a message should be reported to the user */ void message(const QString &title, const QString &message, unsigned int style); + void bumpedFee(const uint256& txid); + public Q_SLOTS: void chooseDate(int idx); void chooseType(int idx); diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index cd55b40b71..17df1bd4d1 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -492,7 +492,7 @@ bool WalletModel::saveReceiveRequest(const std::string &sAddress, const int64_t return m_wallet->addDestData(dest, key, sRequest); } -bool WalletModel::bumpFee(uint256 hash) +bool WalletModel::bumpFee(uint256 hash, uint256& new_hash) { CCoinControl coin_control; coin_control.m_signal_bip125_rbf = true; @@ -544,8 +544,7 @@ bool WalletModel::bumpFee(uint256 hash) return false; } // commit the bumped transaction - uint256 txid; - if(!m_wallet->commitBumpTransaction(hash, std::move(mtx), errors, txid)) { + if(!m_wallet->commitBumpTransaction(hash, std::move(mtx), errors, new_hash)) { QMessageBox::critical(0, tr("Fee bump error"), tr("Could not commit transaction") + "
(" + QString::fromStdString(errors[0])+")"); return false; diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index d8935c2fa8..2d53a7dc4d 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -194,7 +194,7 @@ class WalletModel : public QObject void loadReceiveRequests(std::vector& vReceiveRequests); bool saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest); - bool bumpFee(uint256 hash); + bool bumpFee(uint256 hash, uint256& new_hash); static bool isWalletEnabled(); bool privateKeysDisabled() const; From cdf4089457856bdfe336b6f4b337d7e1ea4fdbd3 Mon Sep 17 00:00:00 2001 From: practicalswift Date: Thu, 26 Jul 2018 16:33:45 +0200 Subject: [PATCH 0018/1200] Remove redundant assignments (dead stores) --- src/bench/crypto_hash.cpp | 6 ++---- src/bench/rollingbloom.cpp | 3 +-- src/test/script_tests.cpp | 8 +++++--- src/txmempool.cpp | 7 +------ 4 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/bench/crypto_hash.cpp b/src/bench/crypto_hash.cpp index 7d907eaf10..3ff106cb87 100644 --- a/src/bench/crypto_hash.cpp +++ b/src/bench/crypto_hash.cpp @@ -80,18 +80,16 @@ static void SipHash_32b(benchmark::State& state) static void FastRandom_32bit(benchmark::State& state) { FastRandomContext rng(true); - uint32_t x = 0; while (state.KeepRunning()) { - x += rng.rand32(); + rng.rand32(); } } static void FastRandom_1bit(benchmark::State& state) { FastRandomContext rng(true); - uint32_t x = 0; while (state.KeepRunning()) { - x += rng.randbool(); + rng.randbool(); } } diff --git a/src/bench/rollingbloom.cpp b/src/bench/rollingbloom.cpp index f7f72605d7..f1363557f2 100644 --- a/src/bench/rollingbloom.cpp +++ b/src/bench/rollingbloom.cpp @@ -12,7 +12,6 @@ static void RollingBloom(benchmark::State& state) CRollingBloomFilter filter(120000, 0.000001); std::vector data(32); uint32_t count = 0; - uint64_t match = 0; while (state.KeepRunning()) { count++; data[0] = count; @@ -25,7 +24,7 @@ static void RollingBloom(benchmark::State& state) data[1] = count >> 16; data[2] = count >> 8; data[3] = count; - match += filter.contains(data); + filter.contains(data); } } diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 510910e149..643da90f09 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -937,17 +937,19 @@ BOOST_AUTO_TEST_CASE(script_build) } } +#ifdef UPDATE_JSON_TESTS std::string strGen; - +#endif for (TestBuilder& test : tests) { test.Test(); std::string str = JSONPrettyPrint(test.GetJSON()); -#ifndef UPDATE_JSON_TESTS +#ifdef UPDATE_JSON_TESTS + strGen += str + ",\n"; +#else if (tests_set.count(str) == 0) { BOOST_CHECK_MESSAGE(false, "Missing auto script_valid test: " + test.GetComment()); } #endif - strGen += str + ",\n"; } #ifdef UPDATE_JSON_TESTS diff --git a/src/txmempool.cpp b/src/txmempool.cpp index d68c38ad4e..88ee3a3d43 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -640,8 +640,6 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const innerUsage += memusage::DynamicUsage(links.parents) + memusage::DynamicUsage(links.children); bool fDependsWait = false; setEntries setParentCheck; - int64_t parentSizes = 0; - int64_t parentSigOpCost = 0; for (const CTxIn &txin : tx.vin) { // Check that every mempool transaction's inputs refer to available coins, or other mempool tx's. indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash); @@ -649,10 +647,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const const CTransaction& tx2 = it2->GetTx(); assert(tx2.vout.size() > txin.prevout.n && !tx2.vout[txin.prevout.n].IsNull()); fDependsWait = true; - if (setParentCheck.insert(it2).second) { - parentSizes += it2->GetTxSize(); - parentSigOpCost += it2->GetSigOpCost(); - } + setParentCheck.insert(it2); } else { assert(pcoins->HaveCoin(txin.prevout)); } From dd777f3e1220dd1a76e8a29cafdd4fe6244c5c0f Mon Sep 17 00:00:00 2001 From: practicalswift Date: Thu, 2 Aug 2018 09:22:44 +0200 Subject: [PATCH 0019/1200] Remove unused variable --- src/test/descriptor_tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/descriptor_tests.cpp b/src/test/descriptor_tests.cpp index f189222be8..e739b84a48 100644 --- a/src/test/descriptor_tests.cpp +++ b/src/test/descriptor_tests.cpp @@ -64,7 +64,7 @@ void Check(const std::string& prv, const std::string& pub, int flags, const std: BOOST_CHECK_EQUAL(pub, pub2); // Check that both can be serialized with private key back to the private version, but not without private key. - std::string prv1, prv2; + std::string prv1; BOOST_CHECK(parse_priv->ToPrivateString(keys_priv, prv1)); BOOST_CHECK_EQUAL(prv, prv1); BOOST_CHECK(!parse_priv->ToPrivateString(keys_pub, prv1)); From 384273260a6ccbcf79dade0830011f528e5a1581 Mon Sep 17 00:00:00 2001 From: Ben Woosley Date: Fri, 11 May 2018 20:17:55 -0700 Subject: [PATCH 0020/1200] test: Add testing of value_ret for SelectCoinsBnB Fix that the early bailout optimization tests did not test the actual selection because their utxo pool was polluted by the make_hard_case test preceding. --- src/wallet/test/coinselector_tests.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/wallet/test/coinselector_tests.cpp b/src/wallet/test/coinselector_tests.cpp index 1561760577..f36b224344 100644 --- a/src/wallet/test/coinselector_tests.cpp +++ b/src/wallet/test/coinselector_tests.cpp @@ -150,6 +150,7 @@ BOOST_AUTO_TEST_CASE(bnb_search_test) add_coin(1 * CENT, 1, actual_selection); BOOST_CHECK(SelectCoinsBnB(GroupCoins(utxo_pool), 1 * CENT, 0.5 * CENT, selection, value_ret, not_input_fees)); BOOST_CHECK(equal_sets(selection, actual_selection)); + BOOST_CHECK_EQUAL(value_ret, 1 * CENT); actual_selection.clear(); selection.clear(); @@ -157,6 +158,7 @@ BOOST_AUTO_TEST_CASE(bnb_search_test) add_coin(2 * CENT, 2, actual_selection); BOOST_CHECK(SelectCoinsBnB(GroupCoins(utxo_pool), 2 * CENT, 0.5 * CENT, selection, value_ret, not_input_fees)); BOOST_CHECK(equal_sets(selection, actual_selection)); + BOOST_CHECK_EQUAL(value_ret, 2 * CENT); actual_selection.clear(); selection.clear(); @@ -165,6 +167,7 @@ BOOST_AUTO_TEST_CASE(bnb_search_test) add_coin(2 * CENT, 2, actual_selection); BOOST_CHECK(SelectCoinsBnB(GroupCoins(utxo_pool), 5 * CENT, 0.5 * CENT, selection, value_ret, not_input_fees)); BOOST_CHECK(equal_sets(selection, actual_selection)); + BOOST_CHECK_EQUAL(value_ret, 5 * CENT); actual_selection.clear(); selection.clear(); @@ -181,6 +184,7 @@ BOOST_AUTO_TEST_CASE(bnb_search_test) add_coin(1 * CENT, 1, actual_selection); BOOST_CHECK(SelectCoinsBnB(GroupCoins(utxo_pool), 10 * CENT, 0.5 * CENT, selection, value_ret, not_input_fees)); BOOST_CHECK(equal_sets(selection, actual_selection)); + BOOST_CHECK_EQUAL(value_ret, 10 * CENT); actual_selection.clear(); selection.clear(); @@ -190,6 +194,9 @@ BOOST_AUTO_TEST_CASE(bnb_search_test) add_coin(3 * CENT, 3, actual_selection); add_coin(2 * CENT, 2, actual_selection); BOOST_CHECK(SelectCoinsBnB(GroupCoins(utxo_pool), 10 * CENT, 5000, selection, value_ret, not_input_fees)); + BOOST_CHECK_EQUAL(value_ret, 10 * CENT); + // FIXME: this test is redundant with the above, because 1 Cent is selected, not "too small" + // BOOST_CHECK(equal_sets(selection, actual_selection)); // Select 0.25 Cent, not possible BOOST_CHECK(!SelectCoinsBnB(GroupCoins(utxo_pool), 0.25 * CENT, 0.5 * CENT, selection, value_ret, not_input_fees)); @@ -203,6 +210,7 @@ BOOST_AUTO_TEST_CASE(bnb_search_test) BOOST_CHECK(SelectCoinsBnB(GroupCoins(utxo_pool), target, 0, selection, value_ret, not_input_fees)); // Should not exhaust // Test same value early bailout optimization + utxo_pool.clear(); add_coin(7 * CENT, 7, actual_selection); add_coin(7 * CENT, 7, actual_selection); add_coin(7 * CENT, 7, actual_selection); @@ -217,6 +225,8 @@ BOOST_AUTO_TEST_CASE(bnb_search_test) add_coin(5 * CENT, 7, utxo_pool); } BOOST_CHECK(SelectCoinsBnB(GroupCoins(utxo_pool), 30 * CENT, 5000, selection, value_ret, not_input_fees)); + BOOST_CHECK_EQUAL(value_ret, 30 * CENT); + BOOST_CHECK(equal_sets(selection, actual_selection)); //////////////////// // Behavior tests // From 41b88e93375d57db12da923f45f87b9a2db8e730 Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Wed, 8 Nov 2017 15:28:35 -0500 Subject: [PATCH 0021/1200] Add unit test for DEBUG_LOCKORDER code --- src/Makefile.test.include | 1 + src/sync.cpp | 8 +++++++- src/sync.h | 7 +++++++ src/test/sync_tests.cpp | 41 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 src/test/sync_tests.cpp diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 6f401636f5..516059917c 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -81,6 +81,7 @@ BITCOIN_TESTS =\ test/sigopcount_tests.cpp \ test/skiplist_tests.cpp \ test/streams_tests.cpp \ + test/sync_tests.cpp \ test/timedata_tests.cpp \ test/torcontrol_tests.cpp \ test/transaction_tests.cpp \ diff --git a/src/sync.cpp b/src/sync.cpp index 28a4e37e68..96ea61b211 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -100,7 +100,11 @@ static void potential_deadlock_detected(const std::pair& mismatch, } LogPrintf(" %s\n", i.second.ToString()); } - assert(false); + if (g_debug_lockorder_abort) { + fprintf(stderr, "Assertion failed: detected inconsistent lock order at %s:%i, details in debug log.\n", __FILE__, __LINE__); + abort(); + } + throw std::logic_error("potential deadlock detected"); } static void push_lock(void* c, const CLockLocation& locklocation) @@ -189,4 +193,6 @@ void DeleteLock(void* cs) } } +bool g_debug_lockorder_abort = true; + #endif /* DEBUG_LOCKORDER */ diff --git a/src/sync.h b/src/sync.h index 882ad5dc4c..b8cb84f79f 100644 --- a/src/sync.h +++ b/src/sync.h @@ -77,6 +77,13 @@ std::string LocksHeld(); void AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs) ASSERT_EXCLUSIVE_LOCK(cs); void AssertLockNotHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs); void DeleteLock(void* cs); + +/** + * Call abort() if a potential lock order deadlock bug is detected, instead of + * just logging information and throwing a logic_error. Defaults to true, and + * set to false in DEBUG_LOCKORDER unit tests. + */ +extern bool g_debug_lockorder_abort; #else void static inline EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false) {} void static inline LeaveCritical() {} diff --git a/src/test/sync_tests.cpp b/src/test/sync_tests.cpp new file mode 100644 index 0000000000..2e0951c3a9 --- /dev/null +++ b/src/test/sync_tests.cpp @@ -0,0 +1,41 @@ +// 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 +#include + +#include + +BOOST_FIXTURE_TEST_SUITE(sync_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(potential_deadlock_detected) +{ + #ifdef DEBUG_LOCKORDER + bool prev = g_debug_lockorder_abort; + g_debug_lockorder_abort = false; + #endif + + CCriticalSection mutex1, mutex2; + { + LOCK2(mutex1, mutex2); + } + bool error_thrown = false; + try { + LOCK2(mutex2, mutex1); + } catch (const std::logic_error& e) { + BOOST_CHECK_EQUAL(e.what(), "potential deadlock detected"); + error_thrown = true; + } + #ifdef DEBUG_LOCKORDER + BOOST_CHECK(error_thrown); + #else + BOOST_CHECK(!error_thrown); + #endif + + #ifdef DEBUG_LOCKORDER + g_debug_lockorder_abort = prev; + #endif +} + +BOOST_AUTO_TEST_SUITE_END() From ba1f095aadf29bddb0bd8176d2e0b908f92a5623 Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Thu, 7 Dec 2017 12:01:53 -0500 Subject: [PATCH 0022/1200] MOVEONLY Move AnnotatedMixin declaration Move AnnotatedMixin closer to where it's used, and after the DEBUG_LOCKORDER function declarations so it can call them. --- src/sync.h | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/sync.h b/src/sync.h index b8cb84f79f..c9a950799e 100644 --- a/src/sync.h +++ b/src/sync.h @@ -46,30 +46,6 @@ LEAVE_CRITICAL_SECTION(mutex); // no RAII // // /////////////////////////////// -/** - * Template mixin that adds -Wthread-safety locking - * annotations to a subset of the mutex API. - */ -template -class LOCKABLE AnnotatedMixin : public PARENT -{ -public: - void lock() EXCLUSIVE_LOCK_FUNCTION() - { - PARENT::lock(); - } - - void unlock() UNLOCK_FUNCTION() - { - PARENT::unlock(); - } - - bool try_lock() EXCLUSIVE_TRYLOCK_FUNCTION(true) - { - return PARENT::try_lock(); - } -}; - #ifdef DEBUG_LOCKORDER void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false); void LeaveCritical(); @@ -94,6 +70,30 @@ void static inline DeleteLock(void* cs) {} #define AssertLockHeld(cs) AssertLockHeldInternal(#cs, __FILE__, __LINE__, &cs) #define AssertLockNotHeld(cs) AssertLockNotHeldInternal(#cs, __FILE__, __LINE__, &cs) +/** + * Template mixin that adds -Wthread-safety locking + * annotations to a subset of the mutex API. + */ +template +class LOCKABLE AnnotatedMixin : public PARENT +{ +public: + void lock() EXCLUSIVE_LOCK_FUNCTION() + { + PARENT::lock(); + } + + void unlock() UNLOCK_FUNCTION() + { + PARENT::unlock(); + } + + bool try_lock() EXCLUSIVE_TRYLOCK_FUNCTION(true) + { + return PARENT::try_lock(); + } +}; + /** * Wrapped mutex: supports recursive locking, but no waiting * TODO: We should move away from using the recursive lock by default. From 1382913e61f5db6ba849b1e261e8aefcd5a1ae68 Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Wed, 8 Nov 2017 16:21:13 -0500 Subject: [PATCH 0023/1200] Make LOCK, LOCK2, TRY_LOCK work with CWaitableCriticalSection They should also work with any other mutex type which std::unique_lock supports. There is no change in behavior for current code that calls these macros with CCriticalSection mutexes. --- src/sync.h | 61 ++++++++++++++++++++++------------------- src/test/sync_tests.cpp | 29 ++++++++++++++------ 2 files changed, 53 insertions(+), 37 deletions(-) diff --git a/src/sync.h b/src/sync.h index c9a950799e..339a7e2c18 100644 --- a/src/sync.h +++ b/src/sync.h @@ -71,13 +71,17 @@ void static inline DeleteLock(void* cs) {} #define AssertLockNotHeld(cs) AssertLockNotHeldInternal(#cs, __FILE__, __LINE__, &cs) /** - * Template mixin that adds -Wthread-safety locking - * annotations to a subset of the mutex API. + * Template mixin that adds -Wthread-safety locking annotations and lock order + * checking to a subset of the mutex API. */ template class LOCKABLE AnnotatedMixin : public PARENT { public: + ~AnnotatedMixin() { + DeleteLock((void*)this); + } + void lock() EXCLUSIVE_LOCK_FUNCTION() { PARENT::lock(); @@ -92,19 +96,15 @@ class LOCKABLE AnnotatedMixin : public PARENT { return PARENT::try_lock(); } + + using UniqueLock = std::unique_lock; }; /** * Wrapped mutex: supports recursive locking, but no waiting * TODO: We should move away from using the recursive lock by default. */ -class CCriticalSection : public AnnotatedMixin -{ -public: - ~CCriticalSection() { - DeleteLock((void*)this); - } -}; +typedef AnnotatedMixin CCriticalSection; /** Wrapped mutex: supports waiting but not recursive locking */ typedef AnnotatedMixin CWaitableCriticalSection; @@ -119,20 +119,19 @@ typedef std::unique_lock WaitableLock; void PrintLockContention(const char* pszName, const char* pszFile, int nLine); #endif -/** Wrapper around std::unique_lock */ -class SCOPED_LOCKABLE CCriticalBlock +/** Wrapper around std::unique_lock style lock for Mutex. */ +template +class SCOPED_LOCKABLE CCriticalBlock : public Base { private: - std::unique_lock lock; - void Enter(const char* pszName, const char* pszFile, int nLine) { - EnterCritical(pszName, pszFile, nLine, (void*)(lock.mutex())); + EnterCritical(pszName, pszFile, nLine, (void*)(Base::mutex())); #ifdef DEBUG_LOCKCONTENTION - if (!lock.try_lock()) { + if (!Base::try_lock()) { PrintLockContention(pszName, pszFile, nLine); #endif - lock.lock(); + Base::lock(); #ifdef DEBUG_LOCKCONTENTION } #endif @@ -140,15 +139,15 @@ class SCOPED_LOCKABLE CCriticalBlock bool TryEnter(const char* pszName, const char* pszFile, int nLine) { - EnterCritical(pszName, pszFile, nLine, (void*)(lock.mutex()), true); - lock.try_lock(); - if (!lock.owns_lock()) + EnterCritical(pszName, pszFile, nLine, (void*)(Base::mutex()), true); + Base::try_lock(); + if (!Base::owns_lock()) LeaveCritical(); - return lock.owns_lock(); + return Base::owns_lock(); } public: - CCriticalBlock(CCriticalSection& mutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(mutexIn) : lock(mutexIn, std::defer_lock) + CCriticalBlock(Mutex& mutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(mutexIn) : Base(mutexIn, std::defer_lock) { if (fTry) TryEnter(pszName, pszFile, nLine); @@ -156,11 +155,11 @@ class SCOPED_LOCKABLE CCriticalBlock Enter(pszName, pszFile, nLine); } - CCriticalBlock(CCriticalSection* pmutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(pmutexIn) + CCriticalBlock(Mutex* pmutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(pmutexIn) { if (!pmutexIn) return; - lock = std::unique_lock(*pmutexIn, std::defer_lock); + *static_cast(this) = Base(*pmutexIn, std::defer_lock); if (fTry) TryEnter(pszName, pszFile, nLine); else @@ -169,22 +168,28 @@ class SCOPED_LOCKABLE CCriticalBlock ~CCriticalBlock() UNLOCK_FUNCTION() { - if (lock.owns_lock()) + if (Base::owns_lock()) LeaveCritical(); } operator bool() { - return lock.owns_lock(); + return Base::owns_lock(); } }; +template +using DebugLock = CCriticalBlock::type>::type>; + #define PASTE(x, y) x ## y #define PASTE2(x, y) PASTE(x, y) -#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) -#define LOCK2(cs1, cs2) CCriticalBlock criticalblock1(cs1, #cs1, __FILE__, __LINE__), criticalblock2(cs2, #cs2, __FILE__, __LINE__) -#define TRY_LOCK(cs, name) CCriticalBlock name(cs, #cs, __FILE__, __LINE__, true) +#define LOCK(cs) DebugLock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) +#define LOCK2(cs1, cs2) \ + DebugLock criticalblock1(cs1, #cs1, __FILE__, __LINE__); \ + DebugLock criticalblock2(cs2, #cs2, __FILE__, __LINE__); +#define TRY_LOCK(cs, name) DebugLock name(cs, #cs, __FILE__, __LINE__, true) +#define WAIT_LOCK(cs, name) DebugLock name(cs, #cs, __FILE__, __LINE__) #define ENTER_CRITICAL_SECTION(cs) \ { \ diff --git a/src/test/sync_tests.cpp b/src/test/sync_tests.cpp index 2e0951c3a9..539e2ff3ab 100644 --- a/src/test/sync_tests.cpp +++ b/src/test/sync_tests.cpp @@ -7,16 +7,10 @@ #include -BOOST_FIXTURE_TEST_SUITE(sync_tests, BasicTestingSetup) - -BOOST_AUTO_TEST_CASE(potential_deadlock_detected) +namespace { +template +void TestPotentialDeadLockDetected(MutexType& mutex1, MutexType& mutex2) { - #ifdef DEBUG_LOCKORDER - bool prev = g_debug_lockorder_abort; - g_debug_lockorder_abort = false; - #endif - - CCriticalSection mutex1, mutex2; { LOCK2(mutex1, mutex2); } @@ -32,6 +26,23 @@ BOOST_AUTO_TEST_CASE(potential_deadlock_detected) #else BOOST_CHECK(!error_thrown); #endif +} +} // namespace + +BOOST_FIXTURE_TEST_SUITE(sync_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(potential_deadlock_detected) +{ + #ifdef DEBUG_LOCKORDER + bool prev = g_debug_lockorder_abort; + g_debug_lockorder_abort = false; + #endif + + CCriticalSection rmutex1, rmutex2; + TestPotentialDeadLockDetected(rmutex1, rmutex2); + + CWaitableCriticalSection mutex1, mutex2; + TestPotentialDeadLockDetected(mutex1, mutex2); #ifdef DEBUG_LOCKORDER g_debug_lockorder_abort = prev; From 9c4dc597ddc66acfd58a945a5ab11f833731abba Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Wed, 8 Nov 2017 17:07:40 -0500 Subject: [PATCH 0024/1200] Use LOCK macros for non-recursive locks Instead of std::unique_lock. --- src/httpserver.cpp | 8 ++++---- src/init.cpp | 4 ++-- src/net.cpp | 4 ++-- src/net.h | 2 +- src/random.cpp | 7 ++++--- src/rpc/blockchain.cpp | 8 ++++---- src/rpc/mining.cpp | 2 +- src/sync.h | 3 --- src/threadinterrupt.cpp | 6 ++++-- src/threadinterrupt.h | 4 +++- src/validation.cpp | 2 +- 11 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 9daf3d1968..ceddc7c2c5 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -69,7 +69,7 @@ class WorkQueue { private: /** Mutex protects entire object */ - std::mutex cs; + CWaitableCriticalSection cs; std::condition_variable cond; std::deque> queue; bool running; @@ -88,7 +88,7 @@ class WorkQueue /** Enqueue a work item */ bool Enqueue(WorkItem* item) { - std::unique_lock lock(cs); + LOCK(cs); if (queue.size() >= maxDepth) { return false; } @@ -102,7 +102,7 @@ class WorkQueue while (true) { std::unique_ptr i; { - std::unique_lock lock(cs); + WAIT_LOCK(cs, lock); while (running && queue.empty()) cond.wait(lock); if (!running) @@ -116,7 +116,7 @@ class WorkQueue /** Interrupt and exit loops */ void Interrupt() { - std::unique_lock lock(cs); + LOCK(cs); running = false; cond.notify_all(); } diff --git a/src/init.cpp b/src/init.cpp index 21445929dc..8ab5790aea 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -566,7 +566,7 @@ static void BlockNotifyGenesisWait(bool, const CBlockIndex *pBlockIndex) { if (pBlockIndex != nullptr) { { - WaitableLock lock_GenesisWait(cs_GenesisWait); + LOCK(cs_GenesisWait); fHaveGenesis = true; } condvar_GenesisWait.notify_all(); @@ -1660,7 +1660,7 @@ bool AppInitMain() // Wait for genesis block to be processed { - WaitableLock lock(cs_GenesisWait); + WAIT_LOCK(cs_GenesisWait, lock); // We previously could hang here if StartShutdown() is called prior to // ThreadImport getting started, so instead we just wait on a timer to // check ShutdownRequested() regularly. diff --git a/src/net.cpp b/src/net.cpp index 5be91fd4f3..37b452a71e 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2064,7 +2064,7 @@ void CConnman::ThreadMessageHandler() pnode->Release(); } - std::unique_lock lock(mutexMsgProc); + WAIT_LOCK(mutexMsgProc, lock); if (!fMoreWork) { condMsgProc.wait_until(lock, std::chrono::steady_clock::now() + std::chrono::milliseconds(100), [this] { return fMsgProcWake; }); } @@ -2346,7 +2346,7 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions) flagInterruptMsgProc = false; { - std::unique_lock lock(mutexMsgProc); + LOCK(mutexMsgProc); fMsgProcWake = false; } diff --git a/src/net.h b/src/net.h index 36c2a4b8f5..5c47f9695c 100644 --- a/src/net.h +++ b/src/net.h @@ -425,7 +425,7 @@ class CConnman bool fMsgProcWake; std::condition_variable condMsgProc; - std::mutex mutexMsgProc; + CWaitableCriticalSection mutexMsgProc; std::atomic flagInterruptMsgProc; CThreadInterrupt interruptNet; diff --git a/src/random.cpp b/src/random.cpp index fee6c2d92a..7f05bcf9a2 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -12,6 +12,7 @@ #include #endif #include // for LogPrint() +#include // for WAIT_LOCK #include // for GetTime() #include @@ -295,7 +296,7 @@ void RandAddSeedSleep() } -static std::mutex cs_rng_state; +static CWaitableCriticalSection cs_rng_state; static unsigned char rng_state[32] = {0}; static uint64_t rng_counter = 0; @@ -305,7 +306,7 @@ static void AddDataToRng(void* data, size_t len) { hasher.Write((const unsigned char*)data, len); unsigned char buf[64]; { - std::unique_lock lock(cs_rng_state); + WAIT_LOCK(cs_rng_state, lock); hasher.Write(rng_state, sizeof(rng_state)); hasher.Write((const unsigned char*)&rng_counter, sizeof(rng_counter)); ++rng_counter; @@ -337,7 +338,7 @@ void GetStrongRandBytes(unsigned char* out, int num) // Combine with and update state { - std::unique_lock lock(cs_rng_state); + WAIT_LOCK(cs_rng_state, lock); hasher.Write(rng_state, sizeof(rng_state)); hasher.Write((const unsigned char*)&rng_counter, sizeof(rng_counter)); ++rng_counter; diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 46dec4ca6e..3aa01914a6 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -49,7 +49,7 @@ struct CUpdatedBlock int height; }; -static std::mutex cs_blockchange; +static CWaitableCriticalSection cs_blockchange; static std::condition_variable cond_blockchange; static CUpdatedBlock latestblock; @@ -224,7 +224,7 @@ static UniValue waitfornewblock(const JSONRPCRequest& request) CUpdatedBlock block; { - std::unique_lock lock(cs_blockchange); + WAIT_LOCK(cs_blockchange, lock); block = latestblock; if(timeout) cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&block]{return latestblock.height != block.height || latestblock.hash != block.hash || !IsRPCRunning(); }); @@ -266,7 +266,7 @@ static UniValue waitforblock(const JSONRPCRequest& request) CUpdatedBlock block; { - std::unique_lock lock(cs_blockchange); + WAIT_LOCK(cs_blockchange, lock); if(timeout) cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&hash]{return latestblock.hash == hash || !IsRPCRunning();}); else @@ -309,7 +309,7 @@ static UniValue waitforblockheight(const JSONRPCRequest& request) CUpdatedBlock block; { - std::unique_lock lock(cs_blockchange); + WAIT_LOCK(cs_blockchange, lock); if(timeout) cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&height]{return latestblock.height >= height || !IsRPCRunning();}); else diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index e751587dc7..59bf0c98ab 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -470,7 +470,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request) { checktxtime = std::chrono::steady_clock::now() + std::chrono::minutes(1); - WaitableLock lock(g_best_block_mutex); + WAIT_LOCK(g_best_block_mutex, lock); while (g_best_block == hashWatchedChain && IsRPCRunning()) { if (g_best_block_cv.wait_until(lock, checktxtime) == std::cv_status::timeout) diff --git a/src/sync.h b/src/sync.h index 339a7e2c18..7306e7285e 100644 --- a/src/sync.h +++ b/src/sync.h @@ -112,9 +112,6 @@ typedef AnnotatedMixin CWaitableCriticalSection; /** Just a typedef for std::condition_variable, can be wrapped later if desired */ typedef std::condition_variable CConditionVariable; -/** Just a typedef for std::unique_lock, can be wrapped later if desired */ -typedef std::unique_lock WaitableLock; - #ifdef DEBUG_LOCKCONTENTION void PrintLockContention(const char* pszName, const char* pszFile, int nLine); #endif diff --git a/src/threadinterrupt.cpp b/src/threadinterrupt.cpp index 7da4e136ef..1efc6f3114 100644 --- a/src/threadinterrupt.cpp +++ b/src/threadinterrupt.cpp @@ -5,6 +5,8 @@ #include +#include + CThreadInterrupt::CThreadInterrupt() : flag(false) {} CThreadInterrupt::operator bool() const @@ -20,7 +22,7 @@ void CThreadInterrupt::reset() void CThreadInterrupt::operator()() { { - std::unique_lock lock(mut); + LOCK(mut); flag.store(true, std::memory_order_release); } cond.notify_all(); @@ -28,7 +30,7 @@ void CThreadInterrupt::operator()() bool CThreadInterrupt::sleep_for(std::chrono::milliseconds rel_time) { - std::unique_lock lock(mut); + WAIT_LOCK(mut, lock); return !cond.wait_for(lock, rel_time, [this]() { return flag.load(std::memory_order_acquire); }); } diff --git a/src/threadinterrupt.h b/src/threadinterrupt.h index d373e3c371..8ba6b12367 100644 --- a/src/threadinterrupt.h +++ b/src/threadinterrupt.h @@ -5,6 +5,8 @@ #ifndef BITCOIN_THREADINTERRUPT_H #define BITCOIN_THREADINTERRUPT_H +#include + #include #include #include @@ -28,7 +30,7 @@ class CThreadInterrupt private: std::condition_variable cond; - std::mutex mut; + CWaitableCriticalSection mut; std::atomic flag; }; diff --git a/src/validation.cpp b/src/validation.cpp index 702a8d7e05..2d6ac4b234 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2254,7 +2254,7 @@ void static UpdateTip(const CBlockIndex *pindexNew, const CChainParams& chainPar mempool.AddTransactionsUpdated(1); { - WaitableLock lock(g_best_block_mutex); + LOCK(g_best_block_mutex); g_best_block = pindexNew->GetBlockHash(); g_best_block_cv.notify_all(); } From 1c5d22585384c8bb05a27a04eab5c57b31d623fb Mon Sep 17 00:00:00 2001 From: Chun Kuan Lee Date: Sun, 22 Jul 2018 05:58:29 +0800 Subject: [PATCH 0025/1200] Drop boost::scoped_array --- src/qt/guiutil.cpp | 31 +++++++------------------------ test/lint/lint-includes.sh | 1 - 2 files changed, 7 insertions(+), 25 deletions(-) diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 9dde2c392c..f49d5df389 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -38,8 +38,6 @@ #include #endif -#include - #include #include #include @@ -547,40 +545,28 @@ bool SetStartOnSystemStartup(bool fAutoStart) CoInitialize(nullptr); // Get a pointer to the IShellLink interface. - IShellLink* psl = nullptr; + IShellLinkW* psl = nullptr; HRESULT hres = CoCreateInstance(CLSID_ShellLink, nullptr, - CLSCTX_INPROC_SERVER, IID_IShellLink, + CLSCTX_INPROC_SERVER, IID_IShellLinkW, reinterpret_cast(&psl)); if (SUCCEEDED(hres)) { // Get the current executable path - TCHAR pszExePath[MAX_PATH]; - GetModuleFileName(nullptr, pszExePath, sizeof(pszExePath)); + WCHAR pszExePath[MAX_PATH]; + GetModuleFileNameW(nullptr, pszExePath, ARRAYSIZE(pszExePath)); // Start client minimized QString strArgs = "-min"; // Set -testnet /-regtest options strArgs += QString::fromStdString(strprintf(" -testnet=%d -regtest=%d", gArgs.GetBoolArg("-testnet", false), gArgs.GetBoolArg("-regtest", false))); -#ifdef UNICODE - boost::scoped_array args(new TCHAR[strArgs.length() + 1]); - // Convert the QString to TCHAR* - strArgs.toWCharArray(args.get()); - // Add missing '\0'-termination to string - args[strArgs.length()] = '\0'; -#endif - // Set the path to the shortcut target psl->SetPath(pszExePath); - PathRemoveFileSpec(pszExePath); + PathRemoveFileSpecW(pszExePath); psl->SetWorkingDirectory(pszExePath); psl->SetShowCmd(SW_SHOWMINNOACTIVE); -#ifndef UNICODE - psl->SetArguments(strArgs.toStdString().c_str()); -#else - psl->SetArguments(args.get()); -#endif + psl->SetArguments(strArgs.toStdWString().c_str()); // Query IShellLink for the IPersistFile interface for // saving the shortcut in persistent storage. @@ -588,11 +574,8 @@ bool SetStartOnSystemStartup(bool fAutoStart) hres = psl->QueryInterface(IID_IPersistFile, reinterpret_cast(&ppf)); if (SUCCEEDED(hres)) { - WCHAR pwsz[MAX_PATH]; - // Ensure that the string is ANSI. - MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().string().c_str(), -1, pwsz, MAX_PATH); // Save the link by calling IPersistFile::Save. - hres = ppf->Save(pwsz, TRUE); + hres = ppf->Save(StartupShortcutPath().wstring().c_str(), TRUE); ppf->Release(); psl->Release(); CoUninitialize(); diff --git a/test/lint/lint-includes.sh b/test/lint/lint-includes.sh index 8f7a1fd76b..2e8569a509 100755 --- a/test/lint/lint-includes.sh +++ b/test/lint/lint-includes.sh @@ -65,7 +65,6 @@ EXPECTED_BOOST_INCLUDES=( boost/optional.hpp boost/preprocessor/cat.hpp boost/preprocessor/stringize.hpp - boost/scoped_array.hpp boost/signals2/connection.hpp boost/signals2/last_value.hpp boost/signals2/signal.hpp From bb6ca65f9890e8280ace32de5a37774e14705859 Mon Sep 17 00:00:00 2001 From: Chun Kuan Lee Date: Tue, 31 Jul 2018 23:03:52 +0800 Subject: [PATCH 0026/1200] gui: get special folder in unicode --- src/util.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/util.cpp b/src/util.cpp index 2f81f50a71..c2c93d966a 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1118,14 +1118,14 @@ void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length) { #ifdef WIN32 fs::path GetSpecialFolderPath(int nFolder, bool fCreate) { - char pszPath[MAX_PATH] = ""; + WCHAR pszPath[MAX_PATH] = L""; - if(SHGetSpecialFolderPathA(nullptr, pszPath, nFolder, fCreate)) + if(SHGetSpecialFolderPathW(nullptr, pszPath, nFolder, fCreate)) { return fs::path(pszPath); } - LogPrintf("SHGetSpecialFolderPathA() failed, could not obtain requested path.\n"); + LogPrintf("SHGetSpecialFolderPathW() failed, could not obtain requested path.\n"); return fs::path(""); } #endif From b2f23c41538eaadd71c373ada75dd3a982eeb8bf Mon Sep 17 00:00:00 2001 From: John Newbery Date: Mon, 6 Aug 2018 10:50:50 -0400 Subject: [PATCH 0027/1200] [RPC] Remove getinfo deprecation warning --- src/rpc/misc.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 09812bb980..c4df764c11 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -456,18 +456,6 @@ static UniValue echo(const JSONRPCRequest& request) return request.params; } -static UniValue getinfo_deprecated(const JSONRPCRequest& request) -{ - throw JSONRPCError(RPC_METHOD_NOT_FOUND, - "getinfo\n" - "\nThis call was removed in version 0.16.0. Use the appropriate fields from:\n" - "- getblockchaininfo: blocks, difficulty, chain\n" - "- getnetworkinfo: version, protocolversion, timeoffset, connections, proxy, relayfee, warnings\n" - "- getwalletinfo: balance, keypoololdest, keypoolsize, paytxfee, unlocked_until, walletversion\n" - "\nbitcoin-cli has the option -getinfo to collect and format these in the old format." - ); -} - static const CRPCCommand commands[] = { // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- @@ -482,7 +470,6 @@ static const CRPCCommand commands[] = { "hidden", "setmocktime", &setmocktime, {"timestamp"}}, { "hidden", "echo", &echo, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}}, { "hidden", "echojson", &echo, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}}, - { "hidden", "getinfo", &getinfo_deprecated, {}}, }; void RegisterMiscRPCCommands(CRPCTable &t) From a9e90e500228f96935649234ed1f446668d9d9d4 Mon Sep 17 00:00:00 2001 From: practicalswift Date: Mon, 6 Aug 2018 23:52:35 +0200 Subject: [PATCH 0028/1200] Remove redundant redeclaration of rescanblockchain(...) in same scope --- src/wallet/rpcwallet.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 73dfebf114..4817e9e4d8 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4761,7 +4761,6 @@ extern UniValue importwallet(const JSONRPCRequest& request); extern UniValue importprunedfunds(const JSONRPCRequest& request); extern UniValue removeprunedfunds(const JSONRPCRequest& request); extern UniValue importmulti(const JSONRPCRequest& request); -extern UniValue rescanblockchain(const JSONRPCRequest& request); static const CRPCCommand commands[] = { // category name actor (function) argNames From f04bb1361ccac2a4351fb058c5ca408b00bfd901 Mon Sep 17 00:00:00 2001 From: practicalswift Date: Mon, 6 Aug 2018 23:53:01 +0200 Subject: [PATCH 0029/1200] Enable -Wredundant-decls (gcc) if available --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 5851413cf4..287646f041 100644 --- a/configure.ac +++ b/configure.ac @@ -303,6 +303,7 @@ if test "x$CXXFLAGS_overridden" = "xno"; then AX_CHECK_COMPILE_FLAG([-Wformat-security],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wformat-security"],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-Wthread-safety-analysis],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wthread-safety-analysis"],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-Wrange-loop-analysis],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wrange-loop-analysis"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wredundant-decls],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wredundant-decls"],,[[$CXXFLAG_WERROR]]) ## Some compilers (gcc) ignore unknown -Wno-* options, but warn about all ## unknown options if any other warning is produced. Test the -Wfoo case, and From d56b73f21768585615c06f5d14d526b9ff1eec73 Mon Sep 17 00:00:00 2001 From: practicalswift Date: Tue, 7 Aug 2018 09:34:45 +0200 Subject: [PATCH 0030/1200] Remove redundant extern --- src/wallet/rpcwallet.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 4817e9e4d8..a9b03685a4 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4751,16 +4751,16 @@ UniValue walletcreatefundedpsbt(const JSONRPCRequest& request) return result; } -extern UniValue abortrescan(const JSONRPCRequest& request); // in rpcdump.cpp -extern UniValue dumpprivkey(const JSONRPCRequest& request); // in rpcdump.cpp -extern UniValue importprivkey(const JSONRPCRequest& request); -extern UniValue importaddress(const JSONRPCRequest& request); -extern UniValue importpubkey(const JSONRPCRequest& request); -extern UniValue dumpwallet(const JSONRPCRequest& request); -extern UniValue importwallet(const JSONRPCRequest& request); -extern UniValue importprunedfunds(const JSONRPCRequest& request); -extern UniValue removeprunedfunds(const JSONRPCRequest& request); -extern UniValue importmulti(const JSONRPCRequest& request); +UniValue abortrescan(const JSONRPCRequest& request); // in rpcdump.cpp +UniValue dumpprivkey(const JSONRPCRequest& request); // in rpcdump.cpp +UniValue importprivkey(const JSONRPCRequest& request); +UniValue importaddress(const JSONRPCRequest& request); +UniValue importpubkey(const JSONRPCRequest& request); +UniValue dumpwallet(const JSONRPCRequest& request); +UniValue importwallet(const JSONRPCRequest& request); +UniValue importprunedfunds(const JSONRPCRequest& request); +UniValue removeprunedfunds(const JSONRPCRequest& request); +UniValue importmulti(const JSONRPCRequest& request); static const CRPCCommand commands[] = { // category name actor (function) argNames From fa5ce27385bc60cdf6d9a4eeb2d32c916c9e07eb Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 11 Jul 2018 08:00:15 -0400 Subject: [PATCH 0031/1200] ui: Compile boost:signals2 only once --- src/init.cpp | 12 +++++----- src/interfaces/node.cpp | 22 ++++++++--------- src/noui.cpp | 6 ++--- src/ui_interface.cpp | 52 +++++++++++++++++++++++++++++++++++++++++ src/ui_interface.h | 37 ++++++++++++++++++----------- 5 files changed, 95 insertions(+), 34 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 66b0b65eb4..be5d0de6be 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -326,12 +326,12 @@ static void registerSignalHandler(int signal, void(*handler)(int)) static void OnRPCStarted() { - uiInterface.NotifyBlockTip.connect(&RPCNotifyBlockChange); + uiInterface.NotifyBlockTip_connect(&RPCNotifyBlockChange); } static void OnRPCStopped() { - uiInterface.NotifyBlockTip.disconnect(&RPCNotifyBlockChange); + uiInterface.NotifyBlockTip_disconnect(&RPCNotifyBlockChange); RPCNotifyBlockChange(false, nullptr); g_best_block_cv.notify_all(); LogPrint(BCLog::RPC, "RPC stopped.\n"); @@ -1290,7 +1290,7 @@ bool AppInitMain() */ if (gArgs.GetBoolArg("-server", false)) { - uiInterface.InitMessage.connect(SetRPCWarmupStatus); + uiInterface.InitMessage_connect(SetRPCWarmupStatus); if (!AppInitServers()) return InitError(_("Unable to start HTTP server. See debug log for details.")); } @@ -1647,13 +1647,13 @@ bool AppInitMain() // Either install a handler to notify us when genesis activates, or set fHaveGenesis directly. // No locking, as this happens before any background thread is started. if (chainActive.Tip() == nullptr) { - uiInterface.NotifyBlockTip.connect(BlockNotifyGenesisWait); + uiInterface.NotifyBlockTip_connect(BlockNotifyGenesisWait); } else { fHaveGenesis = true; } if (gArgs.IsArgSet("-blocknotify")) - uiInterface.NotifyBlockTip.connect(BlockNotifyCallback); + uiInterface.NotifyBlockTip_connect(BlockNotifyCallback); std::vector vImportFiles; for (const std::string& strFile : gArgs.GetArgs("-loadblock")) { @@ -1671,7 +1671,7 @@ bool AppInitMain() while (!fHaveGenesis && !ShutdownRequested()) { condvar_GenesisWait.wait_for(lock, std::chrono::milliseconds(500)); } - uiInterface.NotifyBlockTip.disconnect(BlockNotifyGenesisWait); + uiInterface.NotifyBlockTip_disconnect(BlockNotifyGenesisWait); } if (ShutdownRequested()) { diff --git a/src/interfaces/node.cpp b/src/interfaces/node.cpp index db371d104e..399e991995 100644 --- a/src/interfaces/node.cpp +++ b/src/interfaces/node.cpp @@ -233,44 +233,44 @@ class NodeImpl : public Node } std::unique_ptr handleInitMessage(InitMessageFn fn) override { - return MakeHandler(::uiInterface.InitMessage.connect(fn)); + return MakeHandler(::uiInterface.InitMessage_connect(fn)); } std::unique_ptr handleMessageBox(MessageBoxFn fn) override { - return MakeHandler(::uiInterface.ThreadSafeMessageBox.connect(fn)); + return MakeHandler(::uiInterface.ThreadSafeMessageBox_connect(fn)); } std::unique_ptr handleQuestion(QuestionFn fn) override { - return MakeHandler(::uiInterface.ThreadSafeQuestion.connect(fn)); + return MakeHandler(::uiInterface.ThreadSafeQuestion_connect(fn)); } std::unique_ptr handleShowProgress(ShowProgressFn fn) override { - return MakeHandler(::uiInterface.ShowProgress.connect(fn)); + return MakeHandler(::uiInterface.ShowProgress_connect(fn)); } std::unique_ptr handleLoadWallet(LoadWalletFn fn) override { CHECK_WALLET( - return MakeHandler(::uiInterface.LoadWallet.connect([fn](std::shared_ptr wallet) { fn(MakeWallet(wallet)); }))); + return MakeHandler(::uiInterface.LoadWallet_connect([fn](std::shared_ptr wallet) { fn(MakeWallet(wallet)); }))); } std::unique_ptr handleNotifyNumConnectionsChanged(NotifyNumConnectionsChangedFn fn) override { - return MakeHandler(::uiInterface.NotifyNumConnectionsChanged.connect(fn)); + return MakeHandler(::uiInterface.NotifyNumConnectionsChanged_connect(fn)); } std::unique_ptr handleNotifyNetworkActiveChanged(NotifyNetworkActiveChangedFn fn) override { - return MakeHandler(::uiInterface.NotifyNetworkActiveChanged.connect(fn)); + return MakeHandler(::uiInterface.NotifyNetworkActiveChanged_connect(fn)); } std::unique_ptr handleNotifyAlertChanged(NotifyAlertChangedFn fn) override { - return MakeHandler(::uiInterface.NotifyAlertChanged.connect(fn)); + return MakeHandler(::uiInterface.NotifyAlertChanged_connect(fn)); } std::unique_ptr handleBannedListChanged(BannedListChangedFn fn) override { - return MakeHandler(::uiInterface.BannedListChanged.connect(fn)); + return MakeHandler(::uiInterface.BannedListChanged_connect(fn)); } std::unique_ptr handleNotifyBlockTip(NotifyBlockTipFn fn) override { - return MakeHandler(::uiInterface.NotifyBlockTip.connect([fn](bool initial_download, const CBlockIndex* block) { + return MakeHandler(::uiInterface.NotifyBlockTip_connect([fn](bool initial_download, const CBlockIndex* block) { fn(initial_download, block->nHeight, block->GetBlockTime(), GuessVerificationProgress(Params().TxData(), block)); })); @@ -278,7 +278,7 @@ class NodeImpl : public Node std::unique_ptr handleNotifyHeaderTip(NotifyHeaderTipFn fn) override { return MakeHandler( - ::uiInterface.NotifyHeaderTip.connect([fn](bool initial_download, const CBlockIndex* block) { + ::uiInterface.NotifyHeaderTip_connect([fn](bool initial_download, const CBlockIndex* block) { fn(initial_download, block->nHeight, block->GetBlockTime(), GuessVerificationProgress(Params().TxData(), block)); })); diff --git a/src/noui.cpp b/src/noui.cpp index efe6f28246..905ebb4fed 100644 --- a/src/noui.cpp +++ b/src/noui.cpp @@ -52,7 +52,7 @@ static void noui_InitMessage(const std::string& message) void noui_connect() { // Connect bitcoind signal handlers - uiInterface.ThreadSafeMessageBox.connect(noui_ThreadSafeMessageBox); - uiInterface.ThreadSafeQuestion.connect(noui_ThreadSafeQuestion); - uiInterface.InitMessage.connect(noui_InitMessage); + uiInterface.ThreadSafeMessageBox_connect(noui_ThreadSafeMessageBox); + uiInterface.ThreadSafeQuestion_connect(noui_ThreadSafeQuestion); + uiInterface.InitMessage_connect(noui_InitMessage); } diff --git a/src/ui_interface.cpp b/src/ui_interface.cpp index 72e04f488a..e1fb13592c 100644 --- a/src/ui_interface.cpp +++ b/src/ui_interface.cpp @@ -5,8 +5,60 @@ #include #include +#include +#include + CClientUIInterface uiInterface; +struct UISignals { + boost::signals2::signal> ThreadSafeMessageBox; + boost::signals2::signal> ThreadSafeQuestion; + boost::signals2::signal InitMessage; + boost::signals2::signal NotifyNumConnectionsChanged; + boost::signals2::signal NotifyNetworkActiveChanged; + boost::signals2::signal NotifyAlertChanged; + boost::signals2::signal LoadWallet; + boost::signals2::signal ShowProgress; + boost::signals2::signal NotifyBlockTip; + boost::signals2::signal NotifyHeaderTip; + boost::signals2::signal BannedListChanged; +} g_ui_signals; + +#define ADD_SIGNALS_IMPL_WRAPPER(signal_name) \ + boost::signals2::connection CClientUIInterface::signal_name##_connect(std::function fn) \ + { \ + return g_ui_signals.signal_name.connect(fn); \ + } \ + void CClientUIInterface::signal_name##_disconnect(std::function fn) \ + { \ + return g_ui_signals.signal_name.disconnect(&fn); \ + } + +ADD_SIGNALS_IMPL_WRAPPER(ThreadSafeMessageBox); +ADD_SIGNALS_IMPL_WRAPPER(ThreadSafeQuestion); +ADD_SIGNALS_IMPL_WRAPPER(InitMessage); +ADD_SIGNALS_IMPL_WRAPPER(NotifyNumConnectionsChanged); +ADD_SIGNALS_IMPL_WRAPPER(NotifyNetworkActiveChanged); +ADD_SIGNALS_IMPL_WRAPPER(NotifyAlertChanged); +ADD_SIGNALS_IMPL_WRAPPER(LoadWallet); +ADD_SIGNALS_IMPL_WRAPPER(ShowProgress); +ADD_SIGNALS_IMPL_WRAPPER(NotifyBlockTip); +ADD_SIGNALS_IMPL_WRAPPER(NotifyHeaderTip); +ADD_SIGNALS_IMPL_WRAPPER(BannedListChanged); + +bool CClientUIInterface::ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style) { return g_ui_signals.ThreadSafeMessageBox(message, caption, style); } +bool CClientUIInterface::ThreadSafeQuestion(const std::string& message, const std::string& non_interactive_message, const std::string& caption, unsigned int style) { return g_ui_signals.ThreadSafeQuestion(message, non_interactive_message, caption, style); } +void CClientUIInterface::InitMessage(const std::string& message) { return g_ui_signals.InitMessage(message); } +void CClientUIInterface::NotifyNumConnectionsChanged(int newNumConnections) { return g_ui_signals.NotifyNumConnectionsChanged(newNumConnections); } +void CClientUIInterface::NotifyNetworkActiveChanged(bool networkActive) { return g_ui_signals.NotifyNetworkActiveChanged(networkActive); } +void CClientUIInterface::NotifyAlertChanged() { return g_ui_signals.NotifyAlertChanged(); } +void CClientUIInterface::LoadWallet(std::shared_ptr wallet) { return g_ui_signals.LoadWallet(wallet); } +void CClientUIInterface::ShowProgress(const std::string& title, int nProgress, bool resume_possible) { return g_ui_signals.ShowProgress(title, nProgress, resume_possible); } +void CClientUIInterface::NotifyBlockTip(bool b, const CBlockIndex* i) { return g_ui_signals.NotifyBlockTip(b, i); } +void CClientUIInterface::NotifyHeaderTip(bool b, const CBlockIndex* i) { return g_ui_signals.NotifyHeaderTip(b, i); } +void CClientUIInterface::BannedListChanged() { return g_ui_signals.BannedListChanged(); } + + bool InitError(const std::string& str) { uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_ERROR); diff --git a/src/ui_interface.h b/src/ui_interface.h index 3add369df0..1afb27e3c8 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -6,15 +6,18 @@ #ifndef BITCOIN_UI_INTERFACE_H #define BITCOIN_UI_INTERFACE_H +#include #include #include #include -#include -#include - class CWallet; class CBlockIndex; +namespace boost { +namespace signals2 { +class connection; +} +} // namespace boost /** General change type (added, updated, removed). */ enum ChangeType @@ -72,43 +75,49 @@ class CClientUIInterface MSG_ERROR = (ICON_ERROR | BTN_OK | MODAL) }; +#define ADD_SIGNALS_DECL_WRAPPER(signal_name, rtype, args...) \ + rtype signal_name(args); \ + using signal_name##Sig = rtype(args); \ + boost::signals2::connection signal_name##_connect(std::function fn); \ + void signal_name##_disconnect(std::function fn); + /** Show message box. */ - boost::signals2::signal > ThreadSafeMessageBox; + ADD_SIGNALS_DECL_WRAPPER(ThreadSafeMessageBox, bool, const std::string& message, const std::string& caption, unsigned int style); /** If possible, ask the user a question. If not, falls back to ThreadSafeMessageBox(noninteractive_message, caption, style) and returns false. */ - boost::signals2::signal > ThreadSafeQuestion; + ADD_SIGNALS_DECL_WRAPPER(ThreadSafeQuestion, bool, const std::string& message, const std::string& noninteractive_message, const std::string& caption, unsigned int style); /** Progress message during initialization. */ - boost::signals2::signal InitMessage; + ADD_SIGNALS_DECL_WRAPPER(InitMessage, void, const std::string& message); /** Number of network connections changed. */ - boost::signals2::signal NotifyNumConnectionsChanged; + ADD_SIGNALS_DECL_WRAPPER(NotifyNumConnectionsChanged, void, int newNumConnections); /** Network activity state changed. */ - boost::signals2::signal NotifyNetworkActiveChanged; + ADD_SIGNALS_DECL_WRAPPER(NotifyNetworkActiveChanged, void, bool networkActive); /** * Status bar alerts changed. */ - boost::signals2::signal NotifyAlertChanged; + ADD_SIGNALS_DECL_WRAPPER(NotifyAlertChanged, void, ); /** A wallet has been loaded. */ - boost::signals2::signal wallet)> LoadWallet; + ADD_SIGNALS_DECL_WRAPPER(LoadWallet, void, std::shared_ptr wallet); /** * Show progress e.g. for verifychain. * resume_possible indicates shutting down now will result in the current progress action resuming upon restart. */ - boost::signals2::signal ShowProgress; + ADD_SIGNALS_DECL_WRAPPER(ShowProgress, void, const std::string& title, int nProgress, bool resume_possible); /** New block has been accepted */ - boost::signals2::signal NotifyBlockTip; + ADD_SIGNALS_DECL_WRAPPER(NotifyBlockTip, void, bool, const CBlockIndex*); /** Best header has changed */ - boost::signals2::signal NotifyHeaderTip; + ADD_SIGNALS_DECL_WRAPPER(NotifyHeaderTip, void, bool, const CBlockIndex*); /** Banlist did change. */ - boost::signals2::signal BannedListChanged; + ADD_SIGNALS_DECL_WRAPPER(BannedListChanged, void, void); }; /** Show warning message **/ From 5eb20f81d9568284dca735e4f770f41a48aa5660 Mon Sep 17 00:00:00 2001 From: Ben Woosley Date: Fri, 8 Jun 2018 11:16:07 -0700 Subject: [PATCH 0032/1200] Consistently use ParseHashV to validate hash inputs in rpc ParseHashV validates the length and encoding of the string and throws an informative RPC error on failure, which is as good or better than these alternative calls. Note I switched ParseHashV to check string length first, because IsHex tests that the length is even, and an error like: "must be of length 64 (not 63, for X)" is much more informative than "must be hexadecimal string (not X)" --- src/rpc/blockchain.cpp | 25 +++++++------------ src/rpc/mining.cpp | 4 +-- src/rpc/rawtransaction.cpp | 6 ++--- src/rpc/server.cpp | 12 +++------ src/wallet/rpcdump.cpp | 3 +-- src/wallet/rpcwallet.cpp | 20 +++++---------- .../mining_prioritisetransaction.py | 3 ++- test/functional/p2p_compactblocks.py | 2 +- test/functional/p2p_sendheaders.py | 2 +- test/functional/rpc_blockchain.py | 8 ++++-- test/functional/rpc_rawtransaction.py | 12 +++++---- test/functional/rpc_txoutproof.py | 8 +++++- test/functional/wallet_basic.py | 8 +++++- test/functional/wallet_listsinceblock.py | 4 ++- 14 files changed, 58 insertions(+), 59 deletions(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index f70d506e13..b809fd0f5d 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -252,7 +252,7 @@ static UniValue waitforblock(const JSONRPCRequest& request) ); int timeout = 0; - uint256 hash = uint256S(request.params[0].get_str()); + uint256 hash(ParseHashV(request.params[0], "blockhash")); if (!request.params[1].isNull()) timeout = request.params[1].get_int(); @@ -706,8 +706,7 @@ static UniValue getblockheader(const JSONRPCRequest& request) LOCK(cs_main); - std::string strHash = request.params[0].get_str(); - uint256 hash(uint256S(strHash)); + uint256 hash(ParseHashV(request.params[0], "hash")); bool fVerbose = true; if (!request.params[1].isNull()) @@ -800,8 +799,7 @@ static UniValue getblock(const JSONRPCRequest& request) LOCK(cs_main); - std::string strHash = request.params[0].get_str(); - uint256 hash(uint256S(strHash)); + uint256 hash(ParseHashV(request.params[0], "blockhash")); int verbosity = 1; if (!request.params[1].isNull()) { @@ -1033,8 +1031,7 @@ UniValue gettxout(const JSONRPCRequest& request) UniValue ret(UniValue::VOBJ); - std::string strHash = request.params[0].get_str(); - uint256 hash(uint256S(strHash)); + uint256 hash(ParseHashV(request.params[0], "txid")); int n = request.params[1].get_int(); COutPoint out(hash, n); bool fMempool = true; @@ -1442,8 +1439,7 @@ static UniValue preciousblock(const JSONRPCRequest& request) + HelpExampleRpc("preciousblock", "\"blockhash\"") ); - std::string strHash = request.params[0].get_str(); - uint256 hash(uint256S(strHash)); + uint256 hash(ParseHashV(request.params[0], "blockhash")); CBlockIndex* pblockindex; { @@ -1478,8 +1474,7 @@ static UniValue invalidateblock(const JSONRPCRequest& request) + HelpExampleRpc("invalidateblock", "\"blockhash\"") ); - std::string strHash = request.params[0].get_str(); - uint256 hash(uint256S(strHash)); + uint256 hash(ParseHashV(request.params[0], "blockhash")); CValidationState state; { @@ -1518,8 +1513,7 @@ static UniValue reconsiderblock(const JSONRPCRequest& request) + HelpExampleRpc("reconsiderblock", "\"blockhash\"") ); - std::string strHash = request.params[0].get_str(); - uint256 hash(uint256S(strHash)); + uint256 hash(ParseHashV(request.params[0], "blockhash")); { LOCK(cs_main); @@ -1572,7 +1566,7 @@ static UniValue getchaintxstats(const JSONRPCRequest& request) LOCK(cs_main); pindex = chainActive.Tip(); } else { - uint256 hash = uint256S(request.params[1].get_str()); + uint256 hash(ParseHashV(request.params[1], "blockhash")); LOCK(cs_main); pindex = LookupBlockIndex(hash); if (!pindex) { @@ -1711,8 +1705,7 @@ static UniValue getblockstats(const JSONRPCRequest& request) pindex = chainActive[height]; } else { - const std::string strHash = request.params[0].get_str(); - const uint256 hash(uint256S(strHash)); + const uint256 hash(ParseHashV(request.params[0], "hash_or_height")); pindex = LookupBlockIndex(hash); if (!pindex) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 85b864e6b9..c95145b204 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -247,7 +247,7 @@ static UniValue prioritisetransaction(const JSONRPCRequest& request) LOCK(cs_main); - uint256 hash = ParseHashStr(request.params[0].get_str(), "txid"); + uint256 hash(ParseHashV(request.params[0], "txid")); CAmount nAmount = request.params[2].get_int64(); if (!(request.params[1].isNull() || request.params[1].get_real() == 0)) { @@ -456,7 +456,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request) // Format: std::string lpstr = lpval.get_str(); - hashWatchedChain.SetHex(lpstr.substr(0, 64)); + hashWatchedChain = ParseHashV(lpstr.substr(0, 64), "longpollid"); nTransactionsUpdatedLastLP = atoi64(lpstr.substr(64)); } else diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 3b3f43edea..9f94307949 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -229,9 +229,7 @@ static UniValue gettxoutproof(const JSONRPCRequest& request) UniValue txids = request.params[0].get_array(); for (unsigned int idx = 0; idx < txids.size(); idx++) { const UniValue& txid = txids[idx]; - if (txid.get_str().length() != 64 || !IsHex(txid.get_str())) - throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid txid ")+txid.get_str()); - uint256 hash(uint256S(txid.get_str())); + uint256 hash(ParseHashV(txid, "txid")); if (setTxids.count(hash)) throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated txid: ")+txid.get_str()); setTxids.insert(hash); @@ -242,7 +240,7 @@ static UniValue gettxoutproof(const JSONRPCRequest& request) uint256 hashBlock; if (!request.params[1].isNull()) { LOCK(cs_main); - hashBlock = uint256S(request.params[1].get_str()); + hashBlock = ParseHashV(request.params[1], "blockhash"); pblockindex = LookupBlockIndex(hashBlock); if (!pblockindex) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 10040b1255..85383eb3bc 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -117,16 +117,12 @@ CAmount AmountFromValue(const UniValue& value) uint256 ParseHashV(const UniValue& v, std::string strName) { - std::string strHex; - if (v.isStr()) - strHex = v.get_str(); + std::string strHex(v.get_str()); + if (64 != strHex.length()) + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s must be of length %d (not %d, for '%s')", strName, 64, strHex.length(), strHex)); if (!IsHex(strHex)) // Note: IsHex("") is false throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')"); - if (64 != strHex.length()) - throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s must be of length %d (not %d)", strName, 64, strHex.length())); - uint256 result; - result.SetHex(strHex); - return result; + return uint256S(strHex); } uint256 ParseHashO(const UniValue& o, std::string strKey) { diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index d09af1dbd1..d08b80cc20 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -416,8 +416,7 @@ UniValue removeprunedfunds(const JSONRPCRequest& request) LOCK2(cs_main, pwallet->cs_wallet); - uint256 hash; - hash.SetHex(request.params[0].get_str()); + uint256 hash(ParseHashV(request.params[0], "txid")); std::vector vHash; vHash.push_back(hash); std::vector vHashOut; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 456f08bc14..fec8f69019 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2231,9 +2231,8 @@ static UniValue listsinceblock(const JSONRPCRequest& request) isminefilter filter = ISMINE_SPENDABLE; if (!request.params[0].isNull() && !request.params[0].get_str().empty()) { - uint256 blockId; + uint256 blockId(ParseHashV(request.params[0], "blockhash")); - blockId.SetHex(request.params[0].get_str()); paltindex = pindex = LookupBlockIndex(blockId); if (!pindex) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); @@ -2362,8 +2361,7 @@ static UniValue gettransaction(const JSONRPCRequest& request) LOCK2(cs_main, pwallet->cs_wallet); - uint256 hash; - hash.SetHex(request.params[0].get_str()); + uint256 hash(ParseHashV(request.params[0], "txid")); isminefilter filter = ISMINE_SPENDABLE; if(!request.params[1].isNull()) @@ -2430,8 +2428,7 @@ static UniValue abandontransaction(const JSONRPCRequest& request) LOCK2(cs_main, pwallet->cs_wallet); - uint256 hash; - hash.SetHex(request.params[0].get_str()); + uint256 hash(ParseHashV(request.params[0], "txid")); if (!pwallet->mapWallet.count(hash)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); @@ -2836,17 +2833,13 @@ static UniValue lockunspent(const JSONRPCRequest& request) {"vout", UniValueType(UniValue::VNUM)}, }); - const std::string& txid = find_value(o, "txid").get_str(); - if (!IsHex(txid)) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected hex txid"); - } - + const uint256 txid(ParseHashO(o, "txid")); const int nOutput = find_value(o, "vout").get_int(); if (nOutput < 0) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive"); } - const COutPoint outpt(uint256S(txid), nOutput); + const COutPoint outpt(txid, nOutput); const auto it = pwallet->mapWallet.find(outpt.hash); if (it == pwallet->mapWallet.end()) { @@ -3701,8 +3694,7 @@ static UniValue bumpfee(const JSONRPCRequest& request) } RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VOBJ}); - uint256 hash; - hash.SetHex(request.params[0].get_str()); + uint256 hash(ParseHashV(request.params[0], "txid")); // optional parameters CAmount totalFee = 0; diff --git a/test/functional/mining_prioritisetransaction.py b/test/functional/mining_prioritisetransaction.py index 85f1af6682..e16e1e242f 100755 --- a/test/functional/mining_prioritisetransaction.py +++ b/test/functional/mining_prioritisetransaction.py @@ -24,7 +24,8 @@ def run_test(self): assert_raises_rpc_error(-1, "prioritisetransaction", self.nodes[0].prioritisetransaction, '', 0, 0, 0) # Test `prioritisetransaction` invalid `txid` - assert_raises_rpc_error(-1, "txid must be hexadecimal string", self.nodes[0].prioritisetransaction, txid='foo', fee_delta=0) + assert_raises_rpc_error(-8, "txid must be of length 64 (not 3, for 'foo')", self.nodes[0].prioritisetransaction, txid='foo', fee_delta=0) + assert_raises_rpc_error(-8, "txid must be hexadecimal string (not 'Zd1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000')", self.nodes[0].prioritisetransaction, txid='Zd1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000', fee_delta=0) # Test `prioritisetransaction` invalid `dummy` txid = '1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000' diff --git a/test/functional/p2p_compactblocks.py b/test/functional/p2p_compactblocks.py index cb4c9867a3..36cd8f5b09 100755 --- a/test/functional/p2p_compactblocks.py +++ b/test/functional/p2p_compactblocks.py @@ -287,7 +287,7 @@ def test_compactblock_construction(self, node, test_node, version, use_witness_a block_hash = int(node.generate(1)[0], 16) # Store the raw block in our internal format. - block = FromHex(CBlock(), node.getblock("%02x" % block_hash, False)) + block = FromHex(CBlock(), node.getblock("%064x" % block_hash, False)) for tx in block.vtx: tx.calc_sha256() block.rehash() diff --git a/test/functional/p2p_sendheaders.py b/test/functional/p2p_sendheaders.py index 095cc4b734..ff377721cb 100755 --- a/test/functional/p2p_sendheaders.py +++ b/test/functional/p2p_sendheaders.py @@ -402,7 +402,7 @@ def test_nonnull_locators(self, test_node, inv_node): block_time += 9 - fork_point = self.nodes[0].getblock("%02x" % new_block_hashes[0])["previousblockhash"] + fork_point = self.nodes[0].getblock("%064x" % new_block_hashes[0])["previousblockhash"] fork_point = int(fork_point, 16) # Use getblocks/getdata diff --git a/test/functional/rpc_blockchain.py b/test/functional/rpc_blockchain.py index 17e24453e5..a908596ab3 100755 --- a/test/functional/rpc_blockchain.py +++ b/test/functional/rpc_blockchain.py @@ -125,7 +125,9 @@ def _test_getchaintxstats(self): # Test `getchaintxstats` invalid `blockhash` assert_raises_rpc_error(-1, "JSON value is not a string as expected", self.nodes[0].getchaintxstats, blockhash=0) - assert_raises_rpc_error(-5, "Block not found", self.nodes[0].getchaintxstats, blockhash='0') + assert_raises_rpc_error(-8, "blockhash must be of length 64 (not 1, for '0')", self.nodes[0].getchaintxstats, blockhash='0') + assert_raises_rpc_error(-8, "blockhash must be hexadecimal string (not 'ZZZ0000000000000000000000000000000000000000000000000000000000000')", self.nodes[0].getchaintxstats, blockhash='ZZZ0000000000000000000000000000000000000000000000000000000000000') + assert_raises_rpc_error(-5, "Block not found", self.nodes[0].getchaintxstats, blockhash='0000000000000000000000000000000000000000000000000000000000000000') blockhash = self.nodes[0].getblockhash(200) self.nodes[0].invalidateblock(blockhash) assert_raises_rpc_error(-8, "Block is not in main chain", self.nodes[0].getchaintxstats, blockhash=blockhash) @@ -206,7 +208,9 @@ def _test_gettxoutsetinfo(self): def _test_getblockheader(self): node = self.nodes[0] - assert_raises_rpc_error(-5, "Block not found", node.getblockheader, "nonsense") + assert_raises_rpc_error(-8, "hash must be of length 64 (not 8, for 'nonsense')", node.getblockheader, "nonsense") + assert_raises_rpc_error(-8, "hash must be hexadecimal string (not 'ZZZ7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844')", node.getblockheader, "ZZZ7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844") + assert_raises_rpc_error(-5, "Block not found", node.getblockheader, "0cf7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844") besthash = node.getbestblockhash() secondbesthash = node.getblockhash(199) diff --git a/test/functional/rpc_rawtransaction.py b/test/functional/rpc_rawtransaction.py index 48b4a4a9db..a1bfb00e16 100755 --- a/test/functional/rpc_rawtransaction.py +++ b/test/functional/rpc_rawtransaction.py @@ -76,8 +76,9 @@ def run_test(self): txid = '1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000' assert_raises_rpc_error(-3, "Expected type array", self.nodes[0].createrawtransaction, 'foo', {}) assert_raises_rpc_error(-1, "JSON value is not an object as expected", self.nodes[0].createrawtransaction, ['foo'], {}) - assert_raises_rpc_error(-8, "txid must be hexadecimal string", self.nodes[0].createrawtransaction, [{}], {}) - assert_raises_rpc_error(-8, "txid must be hexadecimal string", self.nodes[0].createrawtransaction, [{'txid': 'foo'}], {}) + assert_raises_rpc_error(-1, "JSON value is not a string as expected", self.nodes[0].createrawtransaction, [{}], {}) + assert_raises_rpc_error(-8, "txid must be of length 64 (not 3, for 'foo')", self.nodes[0].createrawtransaction, [{'txid': 'foo'}], {}) + assert_raises_rpc_error(-8, "txid must be hexadecimal string (not 'ZZZ7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844')", self.nodes[0].createrawtransaction, [{'txid': 'ZZZ7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844'}], {}) assert_raises_rpc_error(-8, "Invalid parameter, missing vout key", self.nodes[0].createrawtransaction, [{'txid': txid}], {}) assert_raises_rpc_error(-8, "Invalid parameter, missing vout key", self.nodes[0].createrawtransaction, [{'txid': txid, 'vout': 'foo'}], {}) assert_raises_rpc_error(-8, "Invalid parameter, vout must be positive", self.nodes[0].createrawtransaction, [{'txid': txid, 'vout': -1}], {}) @@ -165,9 +166,10 @@ def run_test(self): # We should not get the tx if we provide an unrelated block assert_raises_rpc_error(-5, "No such transaction found", self.nodes[0].getrawtransaction, tx, True, block2) # An invalid block hash should raise the correct errors - assert_raises_rpc_error(-8, "parameter 3 must be hexadecimal", self.nodes[0].getrawtransaction, tx, True, True) - assert_raises_rpc_error(-8, "parameter 3 must be hexadecimal", self.nodes[0].getrawtransaction, tx, True, "foobar") - assert_raises_rpc_error(-8, "parameter 3 must be of length 64", self.nodes[0].getrawtransaction, tx, True, "abcd1234") + assert_raises_rpc_error(-1, "JSON value is not a string as expected", self.nodes[0].getrawtransaction, tx, True, True) + assert_raises_rpc_error(-8, "parameter 3 must be of length 64 (not 6, for 'foobar')", self.nodes[0].getrawtransaction, tx, True, "foobar") + assert_raises_rpc_error(-8, "parameter 3 must be of length 64 (not 8, for 'abcd1234')", self.nodes[0].getrawtransaction, tx, True, "abcd1234") + assert_raises_rpc_error(-8, "parameter 3 must be hexadecimal string (not 'ZZZ0000000000000000000000000000000000000000000000000000000000000')", self.nodes[0].getrawtransaction, tx, True, "ZZZ0000000000000000000000000000000000000000000000000000000000000") assert_raises_rpc_error(-5, "Block hash not found", self.nodes[0].getrawtransaction, tx, True, "0000000000000000000000000000000000000000000000000000000000000000") # Undo the blocks and check in_active_chain self.nodes[0].invalidateblock(block1) diff --git a/test/functional/rpc_txoutproof.py b/test/functional/rpc_txoutproof.py index c52a7397dc..26abed414a 100755 --- a/test/functional/rpc_txoutproof.py +++ b/test/functional/rpc_txoutproof.py @@ -62,12 +62,18 @@ def run_test(self): txid_spent = txin_spent["txid"] txid_unspent = txid1 if txin_spent["txid"] != txid1 else txid2 + # Invalid txids + assert_raises_rpc_error(-8, "txid must be of length 64 (not 32, for '00000000000000000000000000000000')", self.nodes[2].gettxoutproof, ["00000000000000000000000000000000"], blockhash) + assert_raises_rpc_error(-8, "txid must be hexadecimal string (not 'ZZZ0000000000000000000000000000000000000000000000000000000000000')", self.nodes[2].gettxoutproof, ["ZZZ0000000000000000000000000000000000000000000000000000000000000"], blockhash) + # Invalid blockhashes + assert_raises_rpc_error(-8, "blockhash must be of length 64 (not 32, for '00000000000000000000000000000000')", self.nodes[2].gettxoutproof, [txid_spent], "00000000000000000000000000000000") + assert_raises_rpc_error(-8, "blockhash must be hexadecimal string (not 'ZZZ0000000000000000000000000000000000000000000000000000000000000')", self.nodes[2].gettxoutproof, [txid_spent], "ZZZ0000000000000000000000000000000000000000000000000000000000000") # We can't find the block from a fully-spent tx assert_raises_rpc_error(-5, "Transaction not yet in block", self.nodes[2].gettxoutproof, [txid_spent]) # We can get the proof if we specify the block assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid_spent], blockhash)), [txid_spent]) # We can't get the proof if we specify a non-existent block - assert_raises_rpc_error(-5, "Block not found", self.nodes[2].gettxoutproof, [txid_spent], "00000000000000000000000000000000") + assert_raises_rpc_error(-5, "Block not found", self.nodes[2].gettxoutproof, [txid_spent], "0000000000000000000000000000000000000000000000000000000000000000") # We can get the proof if the transaction is unspent assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid_unspent])), [txid_unspent]) # We can get the proof if we provide a list of transactions and one of them is unspent. The ordering of the list should not matter. diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py index 9c58b84819..add7b7629d 100755 --- a/test/functional/wallet_basic.py +++ b/test/functional/wallet_basic.py @@ -122,9 +122,15 @@ def run_test(self): assert_equal([unspent_0], self.nodes[2].listlockunspent()) self.nodes[2].lockunspent(True, [unspent_0]) assert_equal(len(self.nodes[2].listlockunspent()), 0) - assert_raises_rpc_error(-8, "Invalid parameter, unknown transaction", + assert_raises_rpc_error(-8, "txid must be of length 64 (not 34, for '0000000000000000000000000000000000')", self.nodes[2].lockunspent, False, [{"txid": "0000000000000000000000000000000000", "vout": 0}]) + assert_raises_rpc_error(-8, "txid must be hexadecimal string (not 'ZZZ0000000000000000000000000000000000000000000000000000000000000')", + self.nodes[2].lockunspent, False, + [{"txid": "ZZZ0000000000000000000000000000000000000000000000000000000000000", "vout": 0}]) + assert_raises_rpc_error(-8, "Invalid parameter, unknown transaction", + self.nodes[2].lockunspent, False, + [{"txid": "0000000000000000000000000000000000000000000000000000000000000000", "vout": 0}]) assert_raises_rpc_error(-8, "Invalid parameter, vout index out of bounds", self.nodes[2].lockunspent, False, [{"txid": unspent_0["txid"], "vout": 999}]) diff --git a/test/functional/wallet_listsinceblock.py b/test/functional/wallet_listsinceblock.py index 63c179411c..a49be78f2b 100755 --- a/test/functional/wallet_listsinceblock.py +++ b/test/functional/wallet_listsinceblock.py @@ -50,8 +50,10 @@ def test_invalid_blockhash(self): "42759cde25462784395a337460bde75f58e73d3f08bd31fdc3507cbac856a2c4") assert_raises_rpc_error(-5, "Block not found", self.nodes[0].listsinceblock, "0000000000000000000000000000000000000000000000000000000000000000") - assert_raises_rpc_error(-5, "Block not found", self.nodes[0].listsinceblock, + assert_raises_rpc_error(-8, "blockhash must be of length 64 (not 11, for 'invalid-hex')", self.nodes[0].listsinceblock, "invalid-hex") + assert_raises_rpc_error(-8, "blockhash must be hexadecimal string (not 'Z000000000000000000000000000000000000000000000000000000000000000')", self.nodes[0].listsinceblock, + "Z000000000000000000000000000000000000000000000000000000000000000") def test_reorg(self): ''' From e58985c916fda39b8ccf08d0db00426af939749a Mon Sep 17 00:00:00 2001 From: Daniel Kraft Date: Wed, 8 Aug 2018 13:22:13 +0200 Subject: [PATCH 0033/1200] Log progress while verifying blocks at level 4. When verifying blocks at startup, the progress is printed in 10% increments to logs. When -checklevel=4, however, the second half of the verification (connecting the blocks again) does not log the progress anymore. (It is still computed and shown in the UI, but not printed to logs.) This change makes the behaviour consistent, by adding the missing progress logging also for level-4 checks. --- src/validation.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/validation.cpp b/src/validation.cpp index fceb135854..c47186ad77 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -3990,7 +3990,7 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, LogPrintf("[0%%]..."); /* Continued */ for (pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev) { boost::this_thread::interruption_point(); - int percentageDone = std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100)))); + const int percentageDone = std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100)))); if (reportDone < percentageDone/10) { // report every 10% step LogPrintf("[%d%%]...", percentageDone); /* Continued */ @@ -4048,7 +4048,13 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, if (nCheckLevel >= 4) { while (pindex != chainActive.Tip()) { boost::this_thread::interruption_point(); - uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * 50))), false); + const int percentageDone = std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * 50))); + if (reportDone < percentageDone/10) { + // report every 10% step + LogPrintf("[%d%%]...", percentageDone); /* Continued */ + reportDone = percentageDone/10; + } + uiInterface.ShowProgress(_("Verifying blocks..."), percentageDone, false); pindex = chainActive.Next(pindex); CBlock block; if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus())) From 96dda8b0589affb88a909aaf62e95bebc4c18ba2 Mon Sep 17 00:00:00 2001 From: Chun Kuan Lee Date: Thu, 19 Jul 2018 05:04:00 +0000 Subject: [PATCH 0034/1200] [depends] Add riscv qt depends support for cross compiling bitcoin-qt --- depends/packages/libX11.mk | 4 ++++ depends/packages/libXau.mk | 4 ++++ depends/packages/libXext.mk | 4 ++++ depends/packages/libxcb.mk | 1 + depends/packages/protobuf.mk | 5 +++++ depends/packages/qrencode.mk | 4 ++++ depends/packages/qt.mk | 4 +++- depends/packages/xproto.mk | 4 ++++ depends/packages/xtrans.mk | 4 ++++ depends/patches/qt/fix_riscv64_arch.patch | 14 ++++++++++++++ 10 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 depends/patches/qt/fix_riscv64_arch.patch diff --git a/depends/packages/libX11.mk b/depends/packages/libX11.mk index 178d592ee6..298616bea4 100644 --- a/depends/packages/libX11.mk +++ b/depends/packages/libX11.mk @@ -10,6 +10,10 @@ $(package)_config_opts=--disable-xkb --disable-static $(package)_config_opts_linux=--with-pic endef +define $(package)_preprocess_cmds + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub . +endef + define $(package)_config_cmds $($(package)_autoconf) endef diff --git a/depends/packages/libXau.mk b/depends/packages/libXau.mk index e87df2e4de..304494e3c5 100644 --- a/depends/packages/libXau.mk +++ b/depends/packages/libXau.mk @@ -10,6 +10,10 @@ define $(package)_set_vars $(package)_config_opts_linux=--with-pic endef +define $(package)_preprocess_cmds + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub . +endef + define $(package)_config_cmds $($(package)_autoconf) endef diff --git a/depends/packages/libXext.mk b/depends/packages/libXext.mk index 4db836066f..c0565dd672 100644 --- a/depends/packages/libXext.mk +++ b/depends/packages/libXext.mk @@ -9,6 +9,10 @@ define $(package)_set_vars $(package)_config_opts=--disable-static endef +define $(package)_preprocess_cmds + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub . +endef + define $(package)_config_cmds $($(package)_autoconf) endef diff --git a/depends/packages/libxcb.mk b/depends/packages/libxcb.mk index 28f2bd6f25..3f346d9728 100644 --- a/depends/packages/libxcb.mk +++ b/depends/packages/libxcb.mk @@ -10,6 +10,7 @@ $(package)_config_opts=--disable-static endef define $(package)_preprocess_cmds + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub build-aux &&\ sed "s/pthread-stubs//" -i configure endef diff --git a/depends/packages/protobuf.mk b/depends/packages/protobuf.mk index 54d3fd9245..d201d1183f 100644 --- a/depends/packages/protobuf.mk +++ b/depends/packages/protobuf.mk @@ -11,6 +11,11 @@ define $(package)_set_vars $(package)_config_opts_linux=--with-pic endef +define $(package)_preprocess_cmds + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub . &&\ + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub gtest/build-aux +endef + define $(package)_config_cmds $($(package)_autoconf) endef diff --git a/depends/packages/qrencode.mk b/depends/packages/qrencode.mk index 44fdf1c295..313e4adf2a 100644 --- a/depends/packages/qrencode.mk +++ b/depends/packages/qrencode.mk @@ -9,6 +9,10 @@ $(package)_config_opts=--disable-shared -without-tools --disable-sdltest $(package)_config_opts_linux=--with-pic endef +define $(package)_preprocess_cmds + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub use +endef + define $(package)_config_cmds $($(package)_autoconf) endef diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 71b7f83db9..422a1c2b19 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -8,7 +8,7 @@ $(package)_dependencies=openssl zlib $(package)_linux_dependencies=freetype fontconfig libxcb libX11 xproto libXext $(package)_build_subdir=qtbase $(package)_qt_libs=corelib network widgets gui plugins testlib -$(package)_patches=fix_qt_pkgconfig.patch mac-qmake.conf fix_configure_mac.patch fix_no_printer.patch fix_rcc_determinism.patch +$(package)_patches=fix_qt_pkgconfig.patch mac-qmake.conf fix_configure_mac.patch fix_no_printer.patch fix_rcc_determinism.patch fix_riscv64_arch.patch $(package)_qttranslations_file_name=qttranslations-$($(package)_suffix) $(package)_qttranslations_sha256_hash=9822084f8e2d2939ba39f4af4c0c2320e45d5996762a9423f833055607604ed8 @@ -93,6 +93,7 @@ $(package)_config_opts_arm_linux += -platform linux-g++ -xplatform bitcoin-linux $(package)_config_opts_i686_linux = -xplatform linux-g++-32 $(package)_config_opts_x86_64_linux = -xplatform linux-g++-64 $(package)_config_opts_aarch64_linux = -xplatform linux-aarch64-gnu-g++ +$(package)_config_opts_riscv64_linux = -platform linux-g++ -xplatform bitcoin-linux-g++ $(package)_config_opts_mingw32 = -no-opengl -xplatform win32-g++ -device-option CROSS_COMPILE="$(host)-" $(package)_build_env = QT_RCC_TEST=1 $(package)_build_env += QT_RCC_SOURCE_DATE_OVERRIDE=1 @@ -139,6 +140,7 @@ define $(package)_preprocess_cmds echo "!host_build: QMAKE_CFLAGS += $($(package)_cflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ echo "!host_build: QMAKE_CXXFLAGS += $($(package)_cxxflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ echo "!host_build: QMAKE_LFLAGS += $($(package)_ldflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ + patch -p1 -i $($(package)_patch_dir)/fix_riscv64_arch.patch &&\ echo "QMAKE_LINK_OBJECT_MAX = 10" >> qtbase/mkspecs/win32-g++/qmake.conf &&\ echo "QMAKE_LINK_OBJECT_SCRIPT = object_script" >> qtbase/mkspecs/win32-g++/qmake.conf &&\ sed -i.old "s|QMAKE_CFLAGS = |!host_build: QMAKE_CFLAGS = $($(package)_cflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \ diff --git a/depends/packages/xproto.mk b/depends/packages/xproto.mk index 50a90b2685..5328ec8481 100644 --- a/depends/packages/xproto.mk +++ b/depends/packages/xproto.mk @@ -8,6 +8,10 @@ define $(package)_set_vars $(package)_config_opts=--disable-shared endef +define $(package)_preprocess_cmds + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub . +endef + define $(package)_config_cmds $($(package)_autoconf) endef diff --git a/depends/packages/xtrans.mk b/depends/packages/xtrans.mk index 99eefa6d5e..c313b1f609 100644 --- a/depends/packages/xtrans.mk +++ b/depends/packages/xtrans.mk @@ -9,6 +9,10 @@ define $(package)_set_vars $(package)_config_opts_linux=--with-pic --disable-static endef +define $(package)_preprocess_cmds + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub . +endef + define $(package)_config_cmds $($(package)_autoconf) endef diff --git a/depends/patches/qt/fix_riscv64_arch.patch b/depends/patches/qt/fix_riscv64_arch.patch new file mode 100644 index 0000000000..e7f29f01f9 --- /dev/null +++ b/depends/patches/qt/fix_riscv64_arch.patch @@ -0,0 +1,14 @@ +diff --git a/qtbase/src/3rdparty/double-conversion/include/double-conversion/utils.h b/qtbase/src/3rdparty/double-conversion/include/double-conversion/utils.h +index 20bfd36..93729fa 100644 +--- a/qtbase/src/3rdparty/double-conversion/include/double-conversion/utils.h ++++ b/qtbase/src/3rdparty/double-conversion/include/double-conversion/utils.h +@@ -65,7 +65,8 @@ + defined(__sparc__) || defined(__sparc) || defined(__s390__) || \ + defined(__SH4__) || defined(__alpha__) || \ + defined(_MIPS_ARCH_MIPS32R2) || \ +- defined(__AARCH64EL__) ++ defined(__AARCH64EL__) || defined(__aarch64__) || \ ++ defined(__riscv) + #define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 + #elif defined(_M_IX86) || defined(__i386__) || defined(__i386) + #if defined(_WIN32) From c4aecd1d80801f3e3dd4bde887b5d1a11e8452b7 Mon Sep 17 00:00:00 2001 From: Chun Kuan Lee Date: Sat, 14 Jul 2018 01:39:24 +0000 Subject: [PATCH 0035/1200] Add risc-v 64-bit to gitian --- contrib/gitian-descriptors/gitian-linux.yml | 38 +++++++++++++-------- src/compat/glibc_compat.cpp | 2 ++ 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 4255fb0c9a..fd22df8873 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -8,15 +8,19 @@ architectures: packages: - "curl" - "g++-aarch64-linux-gnu" -- "g++-7-aarch64-linux-gnu" -- "gcc-7-aarch64-linux-gnu" +- "g++-8-aarch64-linux-gnu" +- "gcc-8-aarch64-linux-gnu" - "binutils-aarch64-linux-gnu" - "g++-arm-linux-gnueabihf" -- "g++-7-arm-linux-gnueabihf" -- "gcc-7-arm-linux-gnueabihf" +- "g++-8-arm-linux-gnueabihf" +- "gcc-8-arm-linux-gnueabihf" - "binutils-arm-linux-gnueabihf" -- "g++-7-multilib" -- "gcc-7-multilib" +- "g++-riscv64-linux-gnu" +- "g++-8-riscv64-linux-gnu" +- "gcc-8-riscv64-linux-gnu" +- "binutils-riscv64-linux-gnu" +- "g++-8-multilib" +- "gcc-8-multilib" - "binutils-gold" - "git" - "pkg-config" @@ -34,9 +38,9 @@ files: [] script: | WRAP_DIR=$HOME/wrapped - HOSTS="i686-pc-linux-gnu x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu" + HOSTS="i686-pc-linux-gnu x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu riscv64-linux-gnu" CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports --disable-bench --disable-gui-tests" - FAKETIME_HOST_PROGS="" + FAKETIME_HOST_PROGS="gcc g++" FAKETIME_PROGS="date ar ranlib nm" HOST_CFLAGS="-O2 -g" HOST_CXXFLAGS="-O2 -g" @@ -69,12 +73,15 @@ script: | function create_per-host_faketime_wrappers { for i in $HOSTS; do for prog in ${FAKETIME_HOST_PROGS}; do - echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} - echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} - echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} - echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} - echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} - chmod +x ${WRAP_DIR}/${i}-${prog} + if which ${i}-${prog}-8 + then + echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} + echo "REAL=\`which -a ${i}-${prog}-8 | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} + echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} + echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} + echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} + chmod +x ${WRAP_DIR}/${i}-${prog} + fi done done } @@ -100,7 +107,7 @@ script: | rm -f ${WRAP_DIR}/${prog} cat << EOF > ${WRAP_DIR}/${prog} #!/usr/bin/env bash - REAL="`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1`" + REAL="`which -a ${prog}-8 | grep -v ${WRAP_DIR}/${prog} | head -1`" for var in "\$@" do if [ "\$var" = "-m32" ]; then @@ -174,6 +181,7 @@ script: | case $i in aarch64-*) : ;; arm-*) : ;; + riscv64-*) : ;; *) make ${MAKEOPTS} -C src check-symbols ;; esac diff --git a/src/compat/glibc_compat.cpp b/src/compat/glibc_compat.cpp index b1cbe9f72a..202a4f6278 100644 --- a/src/compat/glibc_compat.cpp +++ b/src/compat/glibc_compat.cpp @@ -67,6 +67,8 @@ __asm(".symver log2f_old,log2f@GLIBC_2.2.5"); __asm(".symver log2f_old,log2f@GLIBC_2.4"); #elif defined(__aarch64__) __asm(".symver log2f_old,log2f@GLIBC_2.17"); +#elif defined(__riscv) +__asm(".symver log2f_old,log2f@GLIBC_2.27"); #endif extern "C" float __wrap_log2f(float x) { From 0e534d4dcae91ecf7ebd7a667227f7c26b4d5755 Mon Sep 17 00:00:00 2001 From: practicalswift Date: Wed, 8 Aug 2018 21:12:14 +0200 Subject: [PATCH 0036/1200] Fix incorrect Doxygen comments --- src/policy/fees.h | 90 +++++++++++++++++++++---------------------- src/qt/bitcoingui.h | 2 +- src/qt/rpcconsole.cpp | 2 +- src/wallet/wallet.h | 2 +- 4 files changed, 47 insertions(+), 49 deletions(-) diff --git a/src/policy/fees.h b/src/policy/fees.h index 8c34bee237..717eabd74b 100644 --- a/src/policy/fees.h +++ b/src/policy/fees.h @@ -22,51 +22,6 @@ class CTxMemPoolEntry; class CTxMemPool; class TxConfirmStats; -/** \class CBlockPolicyEstimator - * The BlockPolicyEstimator is used for estimating the feerate needed - * for a transaction to be included in a block within a certain number of - * blocks. - * - * At a high level the algorithm works by grouping transactions into buckets - * based on having similar feerates and then tracking how long it - * takes transactions in the various buckets to be mined. It operates under - * the assumption that in general transactions of higher feerate will be - * included in blocks before transactions of lower feerate. So for - * example if you wanted to know what feerate you should put on a transaction to - * be included in a block within the next 5 blocks, you would start by looking - * at the bucket with the highest feerate transactions and verifying that a - * sufficiently high percentage of them were confirmed within 5 blocks and - * then you would look at the next highest feerate bucket, and so on, stopping at - * the last bucket to pass the test. The average feerate of transactions in this - * bucket will give you an indication of the lowest feerate you can put on a - * transaction and still have a sufficiently high chance of being confirmed - * within your desired 5 blocks. - * - * Here is a brief description of the implementation: - * When a transaction enters the mempool, we track the height of the block chain - * at entry. All further calculations are conducted only on this set of "seen" - * transactions. Whenever a block comes in, we count the number of transactions - * in each bucket and the total amount of feerate paid in each bucket. Then we - * calculate how many blocks Y it took each transaction to be mined. We convert - * from a number of blocks to a number of periods Y' each encompassing "scale" - * blocks. This is tracked in 3 different data sets each up to a maximum - * number of periods. Within each data set we have an array of counters in each - * feerate bucket and we increment all the counters from Y' up to max periods - * representing that a tx was successfully confirmed in less than or equal to - * that many periods. We want to save a history of this information, so at any - * time we have a counter of the total number of transactions that happened in a - * given feerate bucket and the total number that were confirmed in each of the - * periods or less for any bucket. We save this history by keeping an - * exponentially decaying moving average of each one of these stats. This is - * done for a different decay in each of the 3 data sets to keep relevant data - * from different time horizons. Furthermore we also keep track of the number - * unmined (in mempool or left mempool without being included in a block) - * transactions in each bucket and for how many blocks they have been - * outstanding and use both of these numbers to increase the number of transactions - * we've seen in that feerate bucket when calculating an estimate for any number - * of confirmations below the number of blocks they've been outstanding. - */ - /* Identifier for each of the 3 different TxConfirmStats which will track * history over different time horizons. */ enum class FeeEstimateHorizon { @@ -130,7 +85,50 @@ struct FeeCalculation int returnedTarget = 0; }; -/** +/** \class CBlockPolicyEstimator + * The BlockPolicyEstimator is used for estimating the feerate needed + * for a transaction to be included in a block within a certain number of + * blocks. + * + * At a high level the algorithm works by grouping transactions into buckets + * based on having similar feerates and then tracking how long it + * takes transactions in the various buckets to be mined. It operates under + * the assumption that in general transactions of higher feerate will be + * included in blocks before transactions of lower feerate. So for + * example if you wanted to know what feerate you should put on a transaction to + * be included in a block within the next 5 blocks, you would start by looking + * at the bucket with the highest feerate transactions and verifying that a + * sufficiently high percentage of them were confirmed within 5 blocks and + * then you would look at the next highest feerate bucket, and so on, stopping at + * the last bucket to pass the test. The average feerate of transactions in this + * bucket will give you an indication of the lowest feerate you can put on a + * transaction and still have a sufficiently high chance of being confirmed + * within your desired 5 blocks. + * + * Here is a brief description of the implementation: + * When a transaction enters the mempool, we track the height of the block chain + * at entry. All further calculations are conducted only on this set of "seen" + * transactions. Whenever a block comes in, we count the number of transactions + * in each bucket and the total amount of feerate paid in each bucket. Then we + * calculate how many blocks Y it took each transaction to be mined. We convert + * from a number of blocks to a number of periods Y' each encompassing "scale" + * blocks. This is tracked in 3 different data sets each up to a maximum + * number of periods. Within each data set we have an array of counters in each + * feerate bucket and we increment all the counters from Y' up to max periods + * representing that a tx was successfully confirmed in less than or equal to + * that many periods. We want to save a history of this information, so at any + * time we have a counter of the total number of transactions that happened in a + * given feerate bucket and the total number that were confirmed in each of the + * periods or less for any bucket. We save this history by keeping an + * exponentially decaying moving average of each one of these stats. This is + * done for a different decay in each of the 3 data sets to keep relevant data + * from different time horizons. Furthermore we also keep track of the number + * unmined (in mempool or left mempool without being included in a block) + * transactions in each bucket and for how many blocks they have been + * outstanding and use both of these numbers to increase the number of transactions + * we've seen in that feerate bucket when calculating an estimate for any number + * of confirmations below the number of blocks they've been outstanding. + * * We want to be able to estimate feerates that are needed on tx's to be included in * a certain number of blocks. Every time a block is added to the best chain, this class records * stats on the transactions included in that block diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index d7ca8081d1..34f80210c4 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -202,7 +202,7 @@ public Q_SLOTS: void setEncryptionStatus(int status); /** Set the hd-enabled status as shown in the UI. - @param[in] status current hd enabled status + @param[in] hdEnabled current hd enabled status @see WalletModel::EncryptionStatus */ void setHDStatus(int hdEnabled); diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index f222357f27..e3fd24b9c7 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -144,7 +144,7 @@ class QtRPCTimerInterface: public RPCTimerInterface * - Within single quotes, no escaping is possible and no special interpretation takes place * * @param[in] node optional node to execute command on - * @param[out] result stringified Result from the executed command(chain) + * @param[out] strResult stringified result from the executed command(chain) * @param[in] strCommand Command line to split * @param[in] fExecute set true if you want the command to be executed * @param[out] pstrFilteredOut Command line, filtered to remove any sensitive data diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 06a7c0a752..ac87cbd2fd 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -989,7 +989,7 @@ class CWallet final : public CCryptoKeyStore, public CValidationInterface unsigned int m_confirm_target{DEFAULT_TX_CONFIRM_TARGET}; bool m_spend_zero_conf_change{DEFAULT_SPEND_ZEROCONF_CHANGE}; bool m_signal_rbf{DEFAULT_WALLET_RBF}; - bool m_allow_fallback_fee{true}; // Date: Fri, 13 Jul 2018 19:15:30 -0700 Subject: [PATCH 0037/1200] Move BerkeleyEnvironment deletion from internal method to callsite Instead of having the object destroy itself, having the caller destroy it. --- src/wallet/db.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index d0fe51801e..536243be4f 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -697,7 +697,6 @@ void BerkeleyEnvironment::Flush(bool fShutdown) if (!fMockDb) { fs::remove_all(fs::path(strPath) / "database"); } - g_dbenvs.erase(strPath); } } } @@ -796,6 +795,10 @@ void BerkeleyDatabase::Flush(bool shutdown) { if (!IsDummy()) { env->Flush(shutdown); - if (shutdown) env = nullptr; + if (shutdown) { + LOCK(cs_db); + g_dbenvs.erase(env->Directory().string()); + env = nullptr; + } } } From 5d296ac810755dc47f105eb95b52b7e2bcb8aea8 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Tue, 20 Feb 2018 15:28:42 -0500 Subject: [PATCH 0038/1200] Add function to close all Db's and reload the databae environment Adds a ReloadDbEnv function to BerkeleyEnvironment in order to close all Db instances, closes the environment, resets it, and then reopens the BerkeleyEnvironment. Also adds a ReloadDbEnv function to BerkeleyDatabase that calls BerkeleyEnvironment's ReloadDbEnv. --- src/wallet/db.cpp | 34 ++++++++++++++++++++++++++++++++++ src/wallet/db.h | 4 ++++ 2 files changed, 38 insertions(+) diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index 536243be4f..2d57c92ccc 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -556,6 +556,7 @@ void BerkeleyBatch::Close() LOCK(cs_db); --env->mapFileUseCount[strFile]; } + env->m_db_in_use.notify_all(); } void BerkeleyEnvironment::CloseDb(const std::string& strFile) @@ -572,6 +573,32 @@ void BerkeleyEnvironment::CloseDb(const std::string& strFile) } } +void BerkeleyEnvironment::ReloadDbEnv() +{ + // Make sure that no Db's are in use + AssertLockNotHeld(cs_db); + std::unique_lock lock(cs_db); + m_db_in_use.wait(lock, [this](){ + for (auto& count : mapFileUseCount) { + if (count.second > 0) return false; + } + return true; + }); + + std::vector filenames; + for (auto it : mapDb) { + filenames.push_back(it.first); + } + // Close the individual Db's + for (const std::string& filename : filenames) { + CloseDb(filename); + } + // Reset the environment + Flush(true); // This will flush and close the environment + Reset(); + Open(true); +} + bool BerkeleyBatch::Rewrite(BerkeleyDatabase& database, const char* pszSkip) { if (database.IsDummy()) { @@ -802,3 +829,10 @@ void BerkeleyDatabase::Flush(bool shutdown) } } } + +void BerkeleyDatabase::ReloadDbEnv() +{ + if (!IsDummy()) { + env->ReloadDbEnv(); + } +} diff --git a/src/wallet/db.h b/src/wallet/db.h index b078edab7b..467ed13b45 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -38,6 +38,7 @@ class BerkeleyEnvironment std::unique_ptr dbenv; std::map mapFileUseCount; std::map mapDb; + std::condition_variable_any m_db_in_use; BerkeleyEnvironment(const fs::path& env_directory); ~BerkeleyEnvironment(); @@ -75,6 +76,7 @@ class BerkeleyEnvironment void CheckpointLSN(const std::string& strFile); void CloseDb(const std::string& strFile); + void ReloadDbEnv(); DbTxn* TxnBegin(int flags = DB_TXN_WRITE_NOSYNC) { @@ -145,6 +147,8 @@ class BerkeleyDatabase void IncrementUpdateCounter(); + void ReloadDbEnv(); + std::atomic nUpdateCounter; unsigned int nLastSeen; unsigned int nLastFlushed; From d7637c5a3f1d62922594cdfb6272e30dacf60ce9 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Tue, 20 Feb 2018 16:08:36 -0500 Subject: [PATCH 0039/1200] After encrypting the wallet, reload the database environment Calls ReloadDbEnv after encrypting the wallet so that the database environment is flushed, closed, and reopened to prevent unencrypted keys from being saved on disk. --- src/wallet/wallet.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 597d108aef..61d0686228 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -719,6 +719,11 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) // bits of the unencrypted private key in slack space in the database file. database->Rewrite(); + // BDB seems to have a bad habit of writing old data into + // slack space in .dat files; that is bad if the old data is + // unencrypted private keys. So: + database->ReloadDbEnv(); + } NotifyStatusChanged(this); From c1dde3a949b36ce9c2155777b3fa1372e7ed97d8 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Tue, 20 Feb 2018 16:09:51 -0500 Subject: [PATCH 0040/1200] No longer shutdown after encrypting the wallet Since the database environment is flushed, closed, and reopened during EncryptWallet, there is no need to shut down the software anymore. --- src/qt/askpassphrasedialog.cpp | 5 ++--- src/wallet/rpcwallet.cpp | 7 +------ test/functional/rpc_fundrawtransaction.py | 6 ++---- test/functional/test_framework/test_node.py | 8 -------- test/functional/wallet_bumpfee.py | 3 +-- test/functional/wallet_dump.py | 3 +-- test/functional/wallet_encryption.py | 3 +-- test/functional/wallet_keypool.py | 4 +--- 8 files changed, 9 insertions(+), 30 deletions(-) diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index 812d2251e1..612331523e 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -123,16 +123,15 @@ void AskPassphraseDialog::accept() { QMessageBox::warning(this, tr("Wallet encrypted"), "" + - tr("%1 will close now to finish the encryption process. " + tr("Your wallet is now encrypted. " "Remember that encrypting your wallet cannot fully protect " - "your bitcoins from being stolen by malware infecting your computer.").arg(tr(PACKAGE_NAME)) + + "your bitcoins from being stolen by malware infecting your computer.") + "

" + tr("IMPORTANT: Any previous backups you have made of your wallet file " "should be replaced with the newly generated, encrypted wallet file. " "For security reasons, previous backups of the unencrypted wallet file " "will become useless as soon as you start using the new, encrypted wallet.") + "
"); - QApplication::quit(); } else { diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 73dfebf114..a1d58aba05 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2729,7 +2729,6 @@ static UniValue encryptwallet(const JSONRPCRequest& request) "will require the passphrase to be set prior the making these calls.\n" "Use the walletpassphrase call for this, and then walletlock call.\n" "If the wallet is already encrypted, use the walletpassphrasechange call.\n" - "Note that this will shutdown the server.\n" "\nArguments:\n" "1. \"passphrase\" (string) The pass phrase to encrypt the wallet with. It must be at least 1 character, but should be long.\n" "\nExamples:\n" @@ -2767,11 +2766,7 @@ static UniValue encryptwallet(const JSONRPCRequest& request) throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Error: Failed to encrypt the wallet."); } - // BDB seems to have a bad habit of writing old data into - // slack space in .dat files; that is bad if the old data is - // unencrypted private keys. So: - StartShutdown(); - return "wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet. The keypool has been flushed and a new HD seed was generated (if you are using HD). You need to make a new backup."; + return "wallet encrypted; The keypool has been flushed and a new HD seed was generated (if you are using HD). You need to make a new backup."; } static UniValue lockunspent(const JSONRPCRequest& request) diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py index a806de43b4..a4985a7a18 100755 --- a/test/functional/rpc_fundrawtransaction.py +++ b/test/functional/rpc_fundrawtransaction.py @@ -475,10 +475,8 @@ def run_test(self): ############################################################ # locked wallet test - self.stop_node(0) - self.nodes[1].node_encrypt_wallet("test") - self.stop_node(2) - self.stop_node(3) + self.nodes[1].encryptwallet("test") + self.stop_nodes() self.start_nodes() # This test is not meant to test fee estimation and we'd like diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py index 56ea110f16..792d74de51 100755 --- a/test/functional/test_framework/test_node.py +++ b/test/functional/test_framework/test_node.py @@ -268,14 +268,6 @@ def assert_start_raises_init_error(self, extra_args=None, expected_msg=None, mat assert_msg = "bitcoind should have exited with expected error " + expected_msg self._raise_assertion_error(assert_msg) - def node_encrypt_wallet(self, passphrase): - """"Encrypts the wallet. - - This causes bitcoind to shutdown, so this method takes - care of cleaning up resources.""" - self.encryptwallet(passphrase) - self.wait_until_stopped() - def add_p2p_connection(self, p2p_conn, *, wait_for_verack=True, **kwargs): """Add a p2p connection to the node. diff --git a/test/functional/wallet_bumpfee.py b/test/functional/wallet_bumpfee.py index 356393cfa4..5a7a1375ae 100755 --- a/test/functional/wallet_bumpfee.py +++ b/test/functional/wallet_bumpfee.py @@ -36,8 +36,7 @@ def set_test_params(self): def run_test(self): # Encrypt wallet for test_locked_wallet_fails test - self.nodes[1].node_encrypt_wallet(WALLET_PASSPHRASE) - self.start_node(1) + self.nodes[1].encryptwallet(WALLET_PASSPHRASE) self.nodes[1].walletpassphrase(WALLET_PASSPHRASE, WALLET_PASSPHRASE_TIMEOUT) connect_nodes_bi(self.nodes, 0, 1) diff --git a/test/functional/wallet_dump.py b/test/functional/wallet_dump.py index 63316d9644..7ddfd2c808 100755 --- a/test/functional/wallet_dump.py +++ b/test/functional/wallet_dump.py @@ -121,8 +121,7 @@ def run_test(self): assert_equal(witness_addr_ret, witness_addr) # p2sh-p2wsh address added to the first key #encrypt wallet, restart, unlock and dump - self.nodes[0].node_encrypt_wallet('test') - self.start_node(0) + self.nodes[0].encryptwallet('test') self.nodes[0].walletpassphrase('test', 10) # Should be a no-op: self.nodes[0].keypoolrefill() diff --git a/test/functional/wallet_encryption.py b/test/functional/wallet_encryption.py index cec9660259..d5e797164b 100755 --- a/test/functional/wallet_encryption.py +++ b/test/functional/wallet_encryption.py @@ -30,8 +30,7 @@ def run_test(self): assert_equal(len(privkey), 52) # Encrypt the wallet - self.nodes[0].node_encrypt_wallet(passphrase) - self.start_node(0) + self.nodes[0].encryptwallet(passphrase) # Test that the wallet is encrypted assert_raises_rpc_error(-13, "Please enter the wallet passphrase with walletpassphrase first", self.nodes[0].dumpprivkey, address) diff --git a/test/functional/wallet_keypool.py b/test/functional/wallet_keypool.py index b00649162e..1d8e0cdf32 100755 --- a/test/functional/wallet_keypool.py +++ b/test/functional/wallet_keypool.py @@ -20,9 +20,7 @@ def run_test(self): assert(addr_before_encrypting_data['hdseedid'] == wallet_info_old['hdseedid']) # Encrypt wallet and wait to terminate - nodes[0].node_encrypt_wallet('test') - # Restart node 0 - self.start_node(0) + nodes[0].encryptwallet('test') # Keep creating keys addr = nodes[0].getnewaddress() addr_data = nodes[0].getaddressinfo(addr) From ef7beaea6abcaab389ccb486a8f25bc4512b99ed Mon Sep 17 00:00:00 2001 From: Aaron Clauson Date: Fri, 10 Aug 2018 09:19:00 +0200 Subject: [PATCH 0041/1200] Visual Studio build configuration for Bitcoin Core --- build_msvc/.gitignore | 10 + build_msvc/README.md | 50 + .../bench_bitcoin/bench_bitcoin.vcxproj | 217 ++++ build_msvc/bitcoin-cli/bitcoin-cli.vcxproj | 180 ++++ build_msvc/bitcoin-tx/bitcoin-tx.vcxproj | 180 ++++ build_msvc/bitcoin.sln | 172 ++++ build_msvc/bitcoin_config.h | 424 ++++++++ build_msvc/bitcoind/bitcoind.vcxproj | 185 ++++ build_msvc/common.init.vcxproj | 14 + build_msvc/common.vcxproj | 15 + .../libbitcoin_cli/libbitcoin_cli.vcxproj | 162 +++ .../libbitcoin_common.vcxproj | 210 ++++ .../libbitcoin_crypto.vcxproj | 175 ++++ .../libbitcoin_qt/libbitcoin_qt.vcxproj | 955 ++++++++++++++++++ .../libbitcoin_server.vcxproj | 212 ++++ .../libbitcoin_util/libbitcoin_util.vcxproj | 196 ++++ .../libbitcoin_wallet.vcxproj | 177 ++++ .../libbitcoin_zmq/libbitcoin_zmq.vcxproj | 169 ++++ .../libbitcoinconsensus.vcxproj | 199 ++++ build_msvc/libunivalue/libunivalue.vcxproj | 160 +++ build_msvc/msbuild/tasks/hexdump.targets | 53 + .../test_bitcoin-qt/test_bitcoin-qt.vcxproj | 146 +++ build_msvc/test_bitcoin/test_bitcoin.vcxproj | 269 +++++ build_msvc/testconsensus/testconsensus.cpp | 50 + .../testconsensus/testconsensus.vcxproj | 173 ++++ 25 files changed, 4753 insertions(+) create mode 100644 build_msvc/.gitignore create mode 100644 build_msvc/README.md create mode 100644 build_msvc/bench_bitcoin/bench_bitcoin.vcxproj create mode 100644 build_msvc/bitcoin-cli/bitcoin-cli.vcxproj create mode 100644 build_msvc/bitcoin-tx/bitcoin-tx.vcxproj create mode 100644 build_msvc/bitcoin.sln create mode 100644 build_msvc/bitcoin_config.h create mode 100644 build_msvc/bitcoind/bitcoind.vcxproj create mode 100644 build_msvc/common.init.vcxproj create mode 100644 build_msvc/common.vcxproj create mode 100644 build_msvc/libbitcoin_cli/libbitcoin_cli.vcxproj create mode 100644 build_msvc/libbitcoin_common/libbitcoin_common.vcxproj create mode 100644 build_msvc/libbitcoin_crypto/libbitcoin_crypto.vcxproj create mode 100644 build_msvc/libbitcoin_qt/libbitcoin_qt.vcxproj create mode 100644 build_msvc/libbitcoin_server/libbitcoin_server.vcxproj create mode 100644 build_msvc/libbitcoin_util/libbitcoin_util.vcxproj create mode 100644 build_msvc/libbitcoin_wallet/libbitcoin_wallet.vcxproj create mode 100644 build_msvc/libbitcoin_zmq/libbitcoin_zmq.vcxproj create mode 100644 build_msvc/libbitcoinconsensus/libbitcoinconsensus.vcxproj create mode 100644 build_msvc/libunivalue/libunivalue.vcxproj create mode 100644 build_msvc/msbuild/tasks/hexdump.targets create mode 100644 build_msvc/test_bitcoin-qt/test_bitcoin-qt.vcxproj create mode 100644 build_msvc/test_bitcoin/test_bitcoin.vcxproj create mode 100644 build_msvc/testconsensus/testconsensus.cpp create mode 100644 build_msvc/testconsensus/testconsensus.vcxproj diff --git a/build_msvc/.gitignore b/build_msvc/.gitignore new file mode 100644 index 0000000000..fbcd1077b3 --- /dev/null +++ b/build_msvc/.gitignore @@ -0,0 +1,10 @@ +# Build directories +Debug/* +Release/* +.vs +packages/* +*/Obj +*/Debug +*/Release +*/x64 +*.vcxproj.user diff --git a/build_msvc/README.md b/build_msvc/README.md new file mode 100644 index 0000000000..6de464e92f --- /dev/null +++ b/build_msvc/README.md @@ -0,0 +1,50 @@ +Building Bitcoin Core with Visual Studio +======================================== + +Introduction +--------------------- +Solution and project files to build the Bitcoin Core applications (except Qt dependent ones) with Visual Studio 2017 can be found in the build_msvc directory. + +Building with Visual Studio is an alternative to the Linux based [cross-compiler build](https://github.com/bitcoin/bitcoin/blob/master/doc/build-windows.md). + +Dependencies +--------------------- +A number of [open source libraries](https://github.com/bitcoin/bitcoin/blob/master/doc/dependencies.md) are required in order to be able to build Bitcoin. + +Options for installing the dependencies in a Visual Studio compatible manner are: + +- Use Microsoft's [vcpkg](https://docs.microsoft.com/en-us/cpp/vcpkg) to download the source packages and build locally. This is the recommended approach. +- Download the source code, build each dependency, add the required include paths, link libraries and binary tools to the Visual Studio project files. +- Use [nuget](https://www.nuget.org/) packages with the understanding that any binary files have been compiled by an untrusted third party. + +The external dependencies required for the Visual Studio build are (see the [dependencies doc](https://github.com/bitcoin/bitcoin/blob/master/doc/dependencies.md) for versions): + +- Berkeley DB, +- OpenSSL, +- Boost, +- libevent, +- ZeroMQ + +Additional dependencies required from the [bitcoin-core](https://github.com/bitcoin-core) github repository are: +- SECP256K1, +- LevelDB + +Building +--------------------- +The instructions below use vcpkg to install the dependencies. + +- Clone and vcpkg from the [github repository](https://github.com/Microsoft/vcpkg) and install as per the instructions in the main README.md. +- Install the required packages (replace x64 with x86 as required): +- Install the required dependencies with vcpkg: + +``` + PS >.\vcpkg install boost:x64-windows-static ` + libevent:x64-windows-static ` + openssl:x64-windows-static ` + zeromq:x64-windows-static ` + berkeleydb:x64-windows-static ` + secp256k1:x64-windows-static ` + leveldb:x64-windows-static +``` + +- Build in Visual Studio. \ No newline at end of file diff --git a/build_msvc/bench_bitcoin/bench_bitcoin.vcxproj b/build_msvc/bench_bitcoin/bench_bitcoin.vcxproj new file mode 100644 index 0000000000..b987a337c0 --- /dev/null +++ b/build_msvc/bench_bitcoin/bench_bitcoin.vcxproj @@ -0,0 +1,217 @@ + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + {2b384fa8-9ee1-4544-93cb-0d733c25e8ce} + + + {7c87e378-df58-482e-aa2f-1bc129bc19ce} + + + {6190199c-6cf4-4dad-bfbd-93fa72a760c1} + + + {460fee33-1fe1-483f-b3bf-931ff8e969a5} + + + {b53a5535-ee9d-4c6f-9a26-f79ee3bc3754} + + + {93b86837-b543-48a5-a89b-7c87abb77df2} + + + {792d487f-f14c-49fc-a9de-3fc150f31c3f} + + + {5724ba7d-a09a-4ba8-800b-c4c1561b3d69} + + + + 15.0 + {1125654E-E1B2-4431-8B5C-62EA9A2FEECB} + Win32Proj + bench_bitcoin + x86-windows-static + x64-windows-static + + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + false + static + + + true + static + + + true + static + + + false + static + + + + NotUsing + Level3 + MaxSpeed + true + true + NOMINMAX;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src; + MultiThreaded + + + Console + true + true + true + crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + NotUsing + Level3 + Disabled + NOMINMAX;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src; + MultiThreadedDebug + + + Console + true + crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + NotUsing + Level3 + Disabled + NOMINMAX;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src; + MultiThreadedDebug + + + Console + true + crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + NotUsing + Level3 + MaxSpeed + true + true + NOMINMAX;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src; + MultiThreaded + + + Console + true + true + true + crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + There was an error executing the raw bench header generation task. + + + + + + + + + diff --git a/build_msvc/bitcoin-cli/bitcoin-cli.vcxproj b/build_msvc/bitcoin-cli/bitcoin-cli.vcxproj new file mode 100644 index 0000000000..32f0354fad --- /dev/null +++ b/build_msvc/bitcoin-cli/bitcoin-cli.vcxproj @@ -0,0 +1,180 @@ + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + {0667528c-d734-4009-adf9-c0d6c4a5a5a6} + + + {6190199c-6cf4-4dad-bfbd-93fa72a760c1} + + + {b53a5535-ee9d-4c6f-9a26-f79ee3bc3754} + + + {5724ba7d-a09a-4ba8-800b-c4c1561b3d69} + + + + 15.0 + {0B2D7431-F876-4A58-87BF-F748338CD3BF} + Win32Proj + bitcoincli + x86-windows-static + x64-windows-static + + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + false + + + true + + + true + + + false + + + + NotUsing + Level3 + MaxSpeed + true + true + HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreaded + + + Console + true + true + true + crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + NotUsing + Level3 + Disabled + HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreadedDebug + + + Console + true + crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + NotUsing + Level3 + Disabled + HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreadedDebug + + + Console + true + crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + NotUsing + Level3 + MaxSpeed + true + true + HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreaded + + + Console + true + true + true + crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + diff --git a/build_msvc/bitcoin-tx/bitcoin-tx.vcxproj b/build_msvc/bitcoin-tx/bitcoin-tx.vcxproj new file mode 100644 index 0000000000..a9fae6b739 --- /dev/null +++ b/build_msvc/bitcoin-tx/bitcoin-tx.vcxproj @@ -0,0 +1,180 @@ + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + {2b384fa8-9ee1-4544-93cb-0d733c25e8ce} + + + {7c87e378-df58-482e-aa2f-1bc129bc19ce} + + + {6190199c-6cf4-4dad-bfbd-93fa72a760c1} + + + {b53a5535-ee9d-4c6f-9a26-f79ee3bc3754} + + + {5724ba7d-a09a-4ba8-800b-c4c1561b3d69} + + + + 15.0 + {D3022AF6-AD33-4CE3-B358-87CB6A1B29CF} + Win32Proj + bitcointx + x86-windows-static + x64-windows-static + + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + false + + + true + + + true + + + false + + + + NotUsing + Level3 + MaxSpeed + true + true + HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreaded + + + Console + true + true + true + crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + NotUsing + Level3 + Disabled + HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreadedDebug + + + Console + true + crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + NotUsing + Level3 + Disabled + HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreadedDebug + + + Console + true + crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + NotUsing + Level3 + MaxSpeed + true + true + HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreaded + + + Console + true + true + true + crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + diff --git a/build_msvc/bitcoin.sln b/build_msvc/bitcoin.sln new file mode 100644 index 0000000000..32068d81f6 --- /dev/null +++ b/build_msvc/bitcoin.sln @@ -0,0 +1,172 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27130.2027 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbitcoin_consensus", "libbitcoinconsensus\libbitcoinconsensus.vcxproj", "{2B384FA8-9EE1-4544-93CB-0D733C25E8CE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_libbitcoinconsensus", "testconsensus\testconsensus.vcxproj", "{E78473E9-B850-456C-9120-276301E04C06}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bitcoind", "bitcoind\bitcoind.vcxproj", "{D4513DDF-6013-44DC-ADCC-12EAF6D1F038}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbitcoin_util", "libbitcoin_util\libbitcoin_util.vcxproj", "{B53A5535-EE9D-4C6F-9A26-F79EE3BC3754}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbitcoin_common", "libbitcoin_common\libbitcoin_common.vcxproj", "{7C87E378-DF58-482E-AA2F-1BC129BC19CE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbitcoin_crypto", "libbitcoin_crypto\libbitcoin_crypto.vcxproj", "{6190199C-6CF4-4DAD-BFBD-93FA72A760C1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbitcoin_server", "libbitcoin_server\libbitcoin_server.vcxproj", "{460FEE33-1FE1-483F-B3BF-931FF8E969A5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libunivalue", "libunivalue\libunivalue.vcxproj", "{5724BA7D-A09A-4BA8-800B-C4C1561B3D69}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbitcoin_wallet", "libbitcoin_wallet\libbitcoin_wallet.vcxproj", "{93B86837-B543-48A5-A89B-7C87ABB77DF2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbitcoin_zmq", "libbitcoin_zmq\libbitcoin_zmq.vcxproj", "{792D487F-F14C-49FC-A9DE-3FC150F31C3F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_bitcoin", "test_bitcoin\test_bitcoin.vcxproj", "{A56B73DB-D46D-4882-8374-1FE3FFA08F07}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbitcoin_cli", "libbitcoin_cli\libbitcoin_cli.vcxproj", "{0667528C-D734-4009-ADF9-C0D6C4A5A5A6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bitcoin-cli", "bitcoin-cli\bitcoin-cli.vcxproj", "{0B2D7431-F876-4A58-87BF-F748338CD3BF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bench_bitcoin", "bench_bitcoin\bench_bitcoin.vcxproj", "{1125654E-E1B2-4431-8B5C-62EA9A2FEECB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bitcoin-tx", "bitcoin-tx\bitcoin-tx.vcxproj", "{D3022AF6-AD33-4CE3-B358-87CB6A1B29CF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2B384FA8-9EE1-4544-93CB-0D733C25E8CE}.Debug|x64.ActiveCfg = Debug|x64 + {2B384FA8-9EE1-4544-93CB-0D733C25E8CE}.Debug|x64.Build.0 = Debug|x64 + {2B384FA8-9EE1-4544-93CB-0D733C25E8CE}.Debug|x86.ActiveCfg = Debug|Win32 + {2B384FA8-9EE1-4544-93CB-0D733C25E8CE}.Debug|x86.Build.0 = Debug|Win32 + {2B384FA8-9EE1-4544-93CB-0D733C25E8CE}.Release|x64.ActiveCfg = Release|x64 + {2B384FA8-9EE1-4544-93CB-0D733C25E8CE}.Release|x64.Build.0 = Release|x64 + {2B384FA8-9EE1-4544-93CB-0D733C25E8CE}.Release|x86.ActiveCfg = Release|Win32 + {2B384FA8-9EE1-4544-93CB-0D733C25E8CE}.Release|x86.Build.0 = Release|Win32 + {E78473E9-B850-456C-9120-276301E04C06}.Debug|x64.ActiveCfg = Debug|x64 + {E78473E9-B850-456C-9120-276301E04C06}.Debug|x64.Build.0 = Debug|x64 + {E78473E9-B850-456C-9120-276301E04C06}.Debug|x86.ActiveCfg = Debug|Win32 + {E78473E9-B850-456C-9120-276301E04C06}.Debug|x86.Build.0 = Debug|Win32 + {E78473E9-B850-456C-9120-276301E04C06}.Release|x64.ActiveCfg = Release|x64 + {E78473E9-B850-456C-9120-276301E04C06}.Release|x64.Build.0 = Release|x64 + {E78473E9-B850-456C-9120-276301E04C06}.Release|x86.ActiveCfg = Release|Win32 + {E78473E9-B850-456C-9120-276301E04C06}.Release|x86.Build.0 = Release|Win32 + {D4513DDF-6013-44DC-ADCC-12EAF6D1F038}.Debug|x64.ActiveCfg = Debug|x64 + {D4513DDF-6013-44DC-ADCC-12EAF6D1F038}.Debug|x64.Build.0 = Debug|x64 + {D4513DDF-6013-44DC-ADCC-12EAF6D1F038}.Debug|x86.ActiveCfg = Debug|Win32 + {D4513DDF-6013-44DC-ADCC-12EAF6D1F038}.Debug|x86.Build.0 = Debug|Win32 + {D4513DDF-6013-44DC-ADCC-12EAF6D1F038}.Release|x64.ActiveCfg = Release|x64 + {D4513DDF-6013-44DC-ADCC-12EAF6D1F038}.Release|x64.Build.0 = Release|x64 + {D4513DDF-6013-44DC-ADCC-12EAF6D1F038}.Release|x86.ActiveCfg = Release|Win32 + {D4513DDF-6013-44DC-ADCC-12EAF6D1F038}.Release|x86.Build.0 = Release|Win32 + {B53A5535-EE9D-4C6F-9A26-F79EE3BC3754}.Debug|x64.ActiveCfg = Debug|x64 + {B53A5535-EE9D-4C6F-9A26-F79EE3BC3754}.Debug|x64.Build.0 = Debug|x64 + {B53A5535-EE9D-4C6F-9A26-F79EE3BC3754}.Debug|x86.ActiveCfg = Debug|Win32 + {B53A5535-EE9D-4C6F-9A26-F79EE3BC3754}.Debug|x86.Build.0 = Debug|Win32 + {B53A5535-EE9D-4C6F-9A26-F79EE3BC3754}.Release|x64.ActiveCfg = Release|x64 + {B53A5535-EE9D-4C6F-9A26-F79EE3BC3754}.Release|x64.Build.0 = Release|x64 + {B53A5535-EE9D-4C6F-9A26-F79EE3BC3754}.Release|x86.ActiveCfg = Release|Win32 + {B53A5535-EE9D-4C6F-9A26-F79EE3BC3754}.Release|x86.Build.0 = Release|Win32 + {7C87E378-DF58-482E-AA2F-1BC129BC19CE}.Debug|x64.ActiveCfg = Debug|x64 + {7C87E378-DF58-482E-AA2F-1BC129BC19CE}.Debug|x64.Build.0 = Debug|x64 + {7C87E378-DF58-482E-AA2F-1BC129BC19CE}.Debug|x86.ActiveCfg = Debug|Win32 + {7C87E378-DF58-482E-AA2F-1BC129BC19CE}.Debug|x86.Build.0 = Debug|Win32 + {7C87E378-DF58-482E-AA2F-1BC129BC19CE}.Release|x64.ActiveCfg = Release|x64 + {7C87E378-DF58-482E-AA2F-1BC129BC19CE}.Release|x64.Build.0 = Release|x64 + {7C87E378-DF58-482E-AA2F-1BC129BC19CE}.Release|x86.ActiveCfg = Release|Win32 + {7C87E378-DF58-482E-AA2F-1BC129BC19CE}.Release|x86.Build.0 = Release|Win32 + {6190199C-6CF4-4DAD-BFBD-93FA72A760C1}.Debug|x64.ActiveCfg = Debug|x64 + {6190199C-6CF4-4DAD-BFBD-93FA72A760C1}.Debug|x64.Build.0 = Debug|x64 + {6190199C-6CF4-4DAD-BFBD-93FA72A760C1}.Debug|x86.ActiveCfg = Debug|Win32 + {6190199C-6CF4-4DAD-BFBD-93FA72A760C1}.Debug|x86.Build.0 = Debug|Win32 + {6190199C-6CF4-4DAD-BFBD-93FA72A760C1}.Release|x64.ActiveCfg = Release|x64 + {6190199C-6CF4-4DAD-BFBD-93FA72A760C1}.Release|x64.Build.0 = Release|x64 + {6190199C-6CF4-4DAD-BFBD-93FA72A760C1}.Release|x86.ActiveCfg = Release|Win32 + {6190199C-6CF4-4DAD-BFBD-93FA72A760C1}.Release|x86.Build.0 = Release|Win32 + {460FEE33-1FE1-483F-B3BF-931FF8E969A5}.Debug|x64.ActiveCfg = Debug|x64 + {460FEE33-1FE1-483F-B3BF-931FF8E969A5}.Debug|x64.Build.0 = Debug|x64 + {460FEE33-1FE1-483F-B3BF-931FF8E969A5}.Debug|x86.ActiveCfg = Debug|Win32 + {460FEE33-1FE1-483F-B3BF-931FF8E969A5}.Debug|x86.Build.0 = Debug|Win32 + {460FEE33-1FE1-483F-B3BF-931FF8E969A5}.Release|x64.ActiveCfg = Release|x64 + {460FEE33-1FE1-483F-B3BF-931FF8E969A5}.Release|x64.Build.0 = Release|x64 + {460FEE33-1FE1-483F-B3BF-931FF8E969A5}.Release|x86.ActiveCfg = Release|Win32 + {460FEE33-1FE1-483F-B3BF-931FF8E969A5}.Release|x86.Build.0 = Release|Win32 + {5724BA7D-A09A-4BA8-800B-C4C1561B3D69}.Debug|x64.ActiveCfg = Debug|x64 + {5724BA7D-A09A-4BA8-800B-C4C1561B3D69}.Debug|x64.Build.0 = Debug|x64 + {5724BA7D-A09A-4BA8-800B-C4C1561B3D69}.Debug|x86.ActiveCfg = Debug|Win32 + {5724BA7D-A09A-4BA8-800B-C4C1561B3D69}.Debug|x86.Build.0 = Debug|Win32 + {5724BA7D-A09A-4BA8-800B-C4C1561B3D69}.Release|x64.ActiveCfg = Release|x64 + {5724BA7D-A09A-4BA8-800B-C4C1561B3D69}.Release|x64.Build.0 = Release|x64 + {5724BA7D-A09A-4BA8-800B-C4C1561B3D69}.Release|x86.ActiveCfg = Release|Win32 + {5724BA7D-A09A-4BA8-800B-C4C1561B3D69}.Release|x86.Build.0 = Release|Win32 + {93B86837-B543-48A5-A89B-7C87ABB77DF2}.Debug|x64.ActiveCfg = Debug|x64 + {93B86837-B543-48A5-A89B-7C87ABB77DF2}.Debug|x64.Build.0 = Debug|x64 + {93B86837-B543-48A5-A89B-7C87ABB77DF2}.Debug|x86.ActiveCfg = Debug|Win32 + {93B86837-B543-48A5-A89B-7C87ABB77DF2}.Debug|x86.Build.0 = Debug|Win32 + {93B86837-B543-48A5-A89B-7C87ABB77DF2}.Release|x64.ActiveCfg = Release|x64 + {93B86837-B543-48A5-A89B-7C87ABB77DF2}.Release|x64.Build.0 = Release|x64 + {93B86837-B543-48A5-A89B-7C87ABB77DF2}.Release|x86.ActiveCfg = Release|Win32 + {93B86837-B543-48A5-A89B-7C87ABB77DF2}.Release|x86.Build.0 = Release|Win32 + {792D487F-F14C-49FC-A9DE-3FC150F31C3F}.Debug|x64.ActiveCfg = Debug|x64 + {792D487F-F14C-49FC-A9DE-3FC150F31C3F}.Debug|x64.Build.0 = Debug|x64 + {792D487F-F14C-49FC-A9DE-3FC150F31C3F}.Debug|x86.ActiveCfg = Debug|Win32 + {792D487F-F14C-49FC-A9DE-3FC150F31C3F}.Debug|x86.Build.0 = Debug|Win32 + {792D487F-F14C-49FC-A9DE-3FC150F31C3F}.Release|x64.ActiveCfg = Release|x64 + {792D487F-F14C-49FC-A9DE-3FC150F31C3F}.Release|x64.Build.0 = Release|x64 + {792D487F-F14C-49FC-A9DE-3FC150F31C3F}.Release|x86.ActiveCfg = Release|Win32 + {792D487F-F14C-49FC-A9DE-3FC150F31C3F}.Release|x86.Build.0 = Release|Win32 + {A56B73DB-D46D-4882-8374-1FE3FFA08F07}.Debug|x64.ActiveCfg = Debug|x64 + {A56B73DB-D46D-4882-8374-1FE3FFA08F07}.Debug|x64.Build.0 = Debug|x64 + {A56B73DB-D46D-4882-8374-1FE3FFA08F07}.Debug|x86.ActiveCfg = Debug|Win32 + {A56B73DB-D46D-4882-8374-1FE3FFA08F07}.Debug|x86.Build.0 = Debug|Win32 + {A56B73DB-D46D-4882-8374-1FE3FFA08F07}.Release|x64.ActiveCfg = Release|x64 + {A56B73DB-D46D-4882-8374-1FE3FFA08F07}.Release|x64.Build.0 = Release|x64 + {A56B73DB-D46D-4882-8374-1FE3FFA08F07}.Release|x86.ActiveCfg = Release|Win32 + {A56B73DB-D46D-4882-8374-1FE3FFA08F07}.Release|x86.Build.0 = Release|Win32 + {0667528C-D734-4009-ADF9-C0D6C4A5A5A6}.Debug|x64.ActiveCfg = Debug|x64 + {0667528C-D734-4009-ADF9-C0D6C4A5A5A6}.Debug|x64.Build.0 = Debug|x64 + {0667528C-D734-4009-ADF9-C0D6C4A5A5A6}.Debug|x86.ActiveCfg = Debug|Win32 + {0667528C-D734-4009-ADF9-C0D6C4A5A5A6}.Debug|x86.Build.0 = Debug|Win32 + {0667528C-D734-4009-ADF9-C0D6C4A5A5A6}.Release|x64.ActiveCfg = Release|x64 + {0667528C-D734-4009-ADF9-C0D6C4A5A5A6}.Release|x64.Build.0 = Release|x64 + {0667528C-D734-4009-ADF9-C0D6C4A5A5A6}.Release|x86.ActiveCfg = Release|Win32 + {0667528C-D734-4009-ADF9-C0D6C4A5A5A6}.Release|x86.Build.0 = Release|Win32 + {0B2D7431-F876-4A58-87BF-F748338CD3BF}.Debug|x64.ActiveCfg = Debug|x64 + {0B2D7431-F876-4A58-87BF-F748338CD3BF}.Debug|x64.Build.0 = Debug|x64 + {0B2D7431-F876-4A58-87BF-F748338CD3BF}.Debug|x86.ActiveCfg = Debug|Win32 + {0B2D7431-F876-4A58-87BF-F748338CD3BF}.Debug|x86.Build.0 = Debug|Win32 + {0B2D7431-F876-4A58-87BF-F748338CD3BF}.Release|x64.ActiveCfg = Release|x64 + {0B2D7431-F876-4A58-87BF-F748338CD3BF}.Release|x64.Build.0 = Release|x64 + {0B2D7431-F876-4A58-87BF-F748338CD3BF}.Release|x86.ActiveCfg = Release|Win32 + {0B2D7431-F876-4A58-87BF-F748338CD3BF}.Release|x86.Build.0 = Release|Win32 + {1125654E-E1B2-4431-8B5C-62EA9A2FEECB}.Debug|x64.ActiveCfg = Debug|x64 + {1125654E-E1B2-4431-8B5C-62EA9A2FEECB}.Debug|x64.Build.0 = Debug|x64 + {1125654E-E1B2-4431-8B5C-62EA9A2FEECB}.Debug|x86.ActiveCfg = Debug|Win32 + {1125654E-E1B2-4431-8B5C-62EA9A2FEECB}.Debug|x86.Build.0 = Debug|Win32 + {1125654E-E1B2-4431-8B5C-62EA9A2FEECB}.Release|x64.ActiveCfg = Release|x64 + {1125654E-E1B2-4431-8B5C-62EA9A2FEECB}.Release|x64.Build.0 = Release|x64 + {1125654E-E1B2-4431-8B5C-62EA9A2FEECB}.Release|x86.ActiveCfg = Release|Win32 + {1125654E-E1B2-4431-8B5C-62EA9A2FEECB}.Release|x86.Build.0 = Release|Win32 + {D3022AF6-AD33-4CE3-B358-87CB6A1B29CF}.Debug|x64.ActiveCfg = Debug|x64 + {D3022AF6-AD33-4CE3-B358-87CB6A1B29CF}.Debug|x64.Build.0 = Debug|x64 + {D3022AF6-AD33-4CE3-B358-87CB6A1B29CF}.Debug|x86.ActiveCfg = Debug|Win32 + {D3022AF6-AD33-4CE3-B358-87CB6A1B29CF}.Debug|x86.Build.0 = Debug|Win32 + {D3022AF6-AD33-4CE3-B358-87CB6A1B29CF}.Release|x64.ActiveCfg = Release|x64 + {D3022AF6-AD33-4CE3-B358-87CB6A1B29CF}.Release|x64.Build.0 = Release|x64 + {D3022AF6-AD33-4CE3-B358-87CB6A1B29CF}.Release|x86.ActiveCfg = Release|Win32 + {D3022AF6-AD33-4CE3-B358-87CB6A1B29CF}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4ABD1207-9A90-4EC9-A8EB-203638A2605D} + SolutionGuid = {2FB733C9-24CB-4BA5-A26B-F43DAD7996B7} + SolutionGuid = {D0CAE2D0-8DB1-4A0B-80EE-800AA6C64323} + SolutionGuid = {DA7D16A6-E5F0-45B3-B194-C3FE64F1BFCD} + EndGlobalSection diff --git a/build_msvc/bitcoin_config.h b/build_msvc/bitcoin_config.h new file mode 100644 index 0000000000..4ac27dae3f --- /dev/null +++ b/build_msvc/bitcoin_config.h @@ -0,0 +1,424 @@ +#ifndef BITCOIN_BITCOIN_CONFIG_H +#define BITCOIN_BITCOIN_CONFIG_H + +/* Define if building universal (internal helper macro) */ +/* #undef AC_APPLE_UNIVERSAL_BUILD */ + +/* Version Build */ +#define CLIENT_VERSION_BUILD 0 + +/* Version is release */ +#define CLIENT_VERSION_IS_RELEASE false + +/* Major version */ +#define CLIENT_VERSION_MAJOR 1 + +/* Minor version */ +#define CLIENT_VERSION_MINOR 17 + +/* Build revision */ +#define CLIENT_VERSION_REVISION 99 + +/* Copyright holder(s) before %s replacement */ +#define COPYRIGHT_HOLDERS "The %s developers" + +/* Copyright holder(s) */ +#define COPYRIGHT_HOLDERS_FINAL "The Bitcoin Core developers" + +/* Replacement for %s in copyright holders string */ +#define COPYRIGHT_HOLDERS_SUBSTITUTION "Bitcoin Core" + +/* Copyright year */ +#define COPYRIGHT_YEAR 2018 + +/* Define to 1 to enable wallet functions */ +#define ENABLE_WALLET 1 + +/* Define to 1 to enable ZMQ functions */ +#define ENABLE_ZMQ 1 + +/* parameter and return value type for __fdelt_chk */ +/* #undef FDELT_TYPE */ + +/* define if the Boost library is available */ +#define HAVE_BOOST /**/ + +/* define if the Boost::Chrono library is available */ +#define HAVE_BOOST_CHRONO /**/ + +/* define if the Boost::Filesystem library is available */ +#define HAVE_BOOST_FILESYSTEM /**/ + +/* define if the Boost::PROGRAM_OPTIONS library is available */ +#define HAVE_BOOST_PROGRAM_OPTIONS /**/ + +/* define if the Boost::System library is available */ +#define HAVE_BOOST_SYSTEM /**/ + +/* define if the Boost::Thread library is available */ +#define HAVE_BOOST_THREAD /**/ + +/* define if the Boost::Unit_Test_Framework library is available */ +#define HAVE_BOOST_UNIT_TEST_FRAMEWORK /**/ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_BYTESWAP_H */ + +/* Define this symbol if the consensus lib has been built */ +#define HAVE_CONSENSUS_LIB 1 + +/* define if the compiler supports basic C++11 syntax */ +#define HAVE_CXX11 1 + +/* Define to 1 if you have the declaration of `be16toh', and to 0 if you + don't. */ +#define HAVE_DECL_BE16TOH 0 + +/* Define to 1 if you have the declaration of `be32toh', and to 0 if you + don't. */ +#define HAVE_DECL_BE32TOH 0 + +/* Define to 1 if you have the declaration of `be64toh', and to 0 if you + don't. */ +#define HAVE_DECL_BE64TOH 0 + +/* Define to 1 if you have the declaration of `bswap_16', and to 0 if you + don't. */ +#define HAVE_DECL_BSWAP_16 0 + +/* Define to 1 if you have the declaration of `bswap_32', and to 0 if you + don't. */ +#define HAVE_DECL_BSWAP_32 0 + +/* Define to 1 if you have the declaration of `bswap_64', and to 0 if you + don't. */ +#define HAVE_DECL_BSWAP_64 0 + +/* Define to 1 if you have the declaration of `daemon', and to 0 if you don't. + */ +#define HAVE_DECL_DAEMON 0 + +/* Define to 1 if you have the declaration of `EVP_MD_CTX_new', and to 0 if + you don't. */ +//#define HAVE_DECL_EVP_MD_CTX_NEW 1 + +/* Define to 1 if you have the declaration of `htobe16', and to 0 if you + don't. */ +#define HAVE_DECL_HTOBE16 0 + +/* Define to 1 if you have the declaration of `htobe32', and to 0 if you + don't. */ +#define HAVE_DECL_HTOBE32 0 + +/* Define to 1 if you have the declaration of `htobe64', and to 0 if you + don't. */ +#define HAVE_DECL_HTOBE64 0 + +/* Define to 1 if you have the declaration of `htole16', and to 0 if you + don't. */ +#define HAVE_DECL_HTOLE16 0 + +/* Define to 1 if you have the declaration of `htole32', and to 0 if you + don't. */ +#define HAVE_DECL_HTOLE32 0 + +/* Define to 1 if you have the declaration of `htole64', and to 0 if you + don't. */ +#define HAVE_DECL_HTOLE64 0 + +/* Define to 1 if you have the declaration of `le16toh', and to 0 if you + don't. */ +#define HAVE_DECL_LE16TOH 0 + +/* Define to 1 if you have the declaration of `le32toh', and to 0 if you + don't. */ +#define HAVE_DECL_LE32TOH 0 + +/* Define to 1 if you have the declaration of `le64toh', and to 0 if you + don't. */ +#define HAVE_DECL_LE64TOH 0 + +/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you + don't. */ +#define HAVE_DECL_STRERROR_R 0 + +/* Define to 1 if you have the declaration of `strnlen', and to 0 if you + don't. */ +#define HAVE_DECL_STRNLEN 1 + +/* Define to 1 if you have the declaration of `__builtin_clz', and to 0 if you + don't. */ +//#define HAVE_DECL___BUILTIN_CLZ 1 + +/* Define to 1 if you have the declaration of `__builtin_clzl', and to 0 if + you don't. */ +//#define HAVE_DECL___BUILTIN_CLZL 1 + +/* Define to 1 if you have the declaration of `__builtin_clzll', and to 0 if + you don't. */ +//#define HAVE_DECL___BUILTIN_CLZLL 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DLFCN_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_ENDIAN_H */ + +/* Define to 1 if the system has the `dllexport' function attribute */ +#define HAVE_FUNC_ATTRIBUTE_DLLEXPORT 1 + +/* Define to 1 if the system has the `dllimport' function attribute */ +#define HAVE_FUNC_ATTRIBUTE_DLLIMPORT 1 + +/* Define to 1 if the system has the `visibility' function attribute */ +#define HAVE_FUNC_ATTRIBUTE_VISIBILITY 1 + +/* Define this symbol if the BSD getentropy system call is available */ +/* #undef HAVE_GETENTROPY */ + +/* Define this symbol if the BSD getentropy system call is available with + sys/random.h */ +/* #undef HAVE_GETENTROPY_RAND */ + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `advapi32' library (-ladvapi32). */ +#define HAVE_LIBADVAPI32 1 + +/* Define to 1 if you have the `comctl32' library (-lcomctl32). */ +#define HAVE_LIBCOMCTL32 1 + +/* Define to 1 if you have the `comdlg32' library (-lcomdlg32). */ +#define HAVE_LIBCOMDLG32 1 + +/* Define to 1 if you have the `crypt32' library (-lcrypt32). */ +#define HAVE_LIBCRYPT32 1 + +/* Define to 1 if you have the `gdi32' library (-lgdi32). */ +#define HAVE_LIBGDI32 1 + +/* Define to 1 if you have the `imm32' library (-limm32). */ +#define HAVE_LIBIMM32 1 + +/* Define to 1 if you have the `iphlpapi' library (-liphlpapi). */ +#define HAVE_LIBIPHLPAPI 1 + +/* Define to 1 if you have the `kernel32' library (-lkernel32). */ +#define HAVE_LIBKERNEL32 1 + +/* Define to 1 if you have the `mingwthrd' library (-lmingwthrd). */ +#define HAVE_LIBMINGWTHRD 1 + +/* Define to 1 if you have the `mswsock' library (-lmswsock). */ +#define HAVE_LIBMSWSOCK 1 + +/* Define to 1 if you have the `ole32' library (-lole32). */ +#define HAVE_LIBOLE32 1 + +/* Define to 1 if you have the `oleaut32' library (-loleaut32). */ +#define HAVE_LIBOLEAUT32 1 + +/* Define to 1 if you have the `rpcrt4' library (-lrpcrt4). */ +#define HAVE_LIBRPCRT4 1 + +/* Define to 1 if you have the `rt' library (-lrt). */ +/* #undef HAVE_LIBRT */ + +/* Define to 1 if you have the `shell32' library (-lshell32). */ +#define HAVE_LIBSHELL32 1 + +/* Define to 1 if you have the `shlwapi' library (-lshlwapi). */ +#define HAVE_LIBSHLWAPI 1 + +/* Define to 1 if you have the `ssp' library (-lssp). */ +#define HAVE_LIBSSP 1 + +/* Define to 1 if you have the `user32' library (-luser32). */ +#define HAVE_LIBUSER32 1 + +/* Define to 1 if you have the `uuid' library (-luuid). */ +#define HAVE_LIBUUID 1 + +/* Define to 1 if you have the `winmm' library (-lwinmm). */ +#define HAVE_LIBWINMM 1 + +/* Define to 1 if you have the `winspool' library (-lwinspool). */ +#define HAVE_LIBWINSPOOL 1 + +/* Define to 1 if you have the `ws2_32' library (-lws2_32). */ +#define HAVE_LIBWS2_32 1 + +/* Define to 1 if you have the `z ' library (-lz ). */ +#define HAVE_LIBZ_ 1 + +/* Define this symbol if you have malloc_info */ +/* #undef HAVE_MALLOC_INFO */ + +/* Define this symbol if you have mallopt with M_ARENA_MAX */ +/* #undef HAVE_MALLOPT_ARENA_MAX */ + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MINIUPNPC_MINIUPNPC_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MINIUPNPC_MINIWGET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MINIUPNPC_UPNPCOMMANDS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MINIUPNPC_UPNPERRORS_H 1 + +/* Define this symbol if you have MSG_DONTWAIT */ +/* #undef HAVE_MSG_DONTWAIT */ + +/* Define this symbol if you have MSG_NOSIGNAL */ +/* #undef HAVE_MSG_NOSIGNAL */ + +/* Define if you have POSIX threads libraries and header files. */ +//#define HAVE_PTHREAD 1 + +/* Have PTHREAD_PRIO_INHERIT. */ +//#define HAVE_PTHREAD_PRIO_INHERIT 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDIO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strerror_r' function. */ +/* #undef HAVE_STRERROR_R */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define this symbol if the BSD sysctl(KERN_ARND) is available */ +/* #undef HAVE_SYSCTL_ARND */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_ENDIAN_H */ + +/* Define this symbol if the Linux getrandom system call is available */ +/* #undef HAVE_SYS_GETRANDOM */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_PRCTL_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SELECT_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +//#define HAVE_UNISTD_H 1 + +/* Define if the visibility attribute is supported. */ +#define HAVE_VISIBILITY_ATTRIBUTE 1 + +/* Define this symbol if boost sleep works */ +/* #undef HAVE_WORKING_BOOST_SLEEP */ + +/* Define this symbol if boost sleep_for works */ +#define HAVE_WORKING_BOOST_SLEEP_FOR 1 + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#define LT_OBJDIR ".libs/" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "https://github.com/bitcoin/bitcoin/issues" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "Bitcoin Core" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "Bitcoin Core 0.17.99" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "bitcoin" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "https://bitcoincore.org/" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "0.17.99" + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +/* #undef PTHREAD_CREATE_JOINABLE */ + +/* Define this symbol if the qt platform is cocoa */ +/* #undef QT_QPA_PLATFORM_COCOA */ + +/* Define this symbol if the minimal qt platform exists */ +#define QT_QPA_PLATFORM_MINIMAL 1 + +/* Define this symbol if the qt platform is windows */ +#define QT_QPA_PLATFORM_WINDOWS 1 + +/* Define this symbol if the qt platform is xcb */ +/* #undef QT_QPA_PLATFORM_XCB */ + +/* Define this symbol if qt plugins are static */ +#define QT_STATICPLUGIN 1 + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if strerror_r returns char *. */ +/* #undef STRERROR_R_CHAR_P */ + +/* Define this symbol to build in assembly routines */ +//#define USE_ASM 1 + +/* Define this symbol if coverage is enabled */ +/* #undef USE_COVERAGE */ + +/* Define if dbus support should be compiled in */ +/* #undef USE_DBUS */ + +/* Define if QR support should be compiled in */ +//#define USE_QRCODE 1 + +/* UPnP support not compiled if undefined, otherwise value (0 or 1) determines + default state */ +//#define USE_UPNP 0 + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +/* # undef WORDS_BIGENDIAN */ +# endif +#endif + +/* Enable large inode numbers on Mac OS X 10.5. */ +#ifndef _DARWIN_USE_64_BIT_INODE +# define _DARWIN_USE_64_BIT_INODE 1 +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +#define _FILE_OFFSET_BITS 64 + +/* Define for large files, on AIX-style hosts. */ +/* #undef _LARGE_FILES */ + +#endif //BITCOIN_BITCOIN_CONFIG_H diff --git a/build_msvc/bitcoind/bitcoind.vcxproj b/build_msvc/bitcoind/bitcoind.vcxproj new file mode 100644 index 0000000000..bb43d9821e --- /dev/null +++ b/build_msvc/bitcoind/bitcoind.vcxproj @@ -0,0 +1,185 @@ + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {D4513DDF-6013-44DC-ADCC-12EAF6D1F038} + Win32Proj + bitcoind + x86-windows-static + x64-windows-static + + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + NotUsing + Level3 + Disabled + WIN32;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreadedDebug + + + Console + true + crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + false + + + + + NotUsing + Level3 + Disabled + WIN32;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreadedDebug + + + Console + true + crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + false + + + + + NotUsing + Level3 + MaxSpeed + true + true + WIN32;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreaded + + + Console + true + true + true + + + crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + false + + + + + NotUsing + Level3 + MaxSpeed + true + true + WIN32;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreaded + + + Console + true + true + true + + + crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + false + + + + + + + + {2b384fa8-9ee1-4544-93cb-0d733c25e8ce} + + + {7c87e378-df58-482e-aa2f-1bc129bc19ce} + + + {6190199c-6cf4-4dad-bfbd-93fa72a760c1} + + + {460fee33-1fe1-483f-b3bf-931ff8e969a5} + + + {b53a5535-ee9d-4c6f-9a26-f79ee3bc3754} + + + {93b86837-b543-48a5-a89b-7c87abb77df2} + + + {792d487f-f14c-49fc-a9de-3fc150f31c3f} + + + {5724ba7d-a09a-4ba8-800b-c4c1561b3d69} + + + + diff --git a/build_msvc/common.init.vcxproj b/build_msvc/common.init.vcxproj new file mode 100644 index 0000000000..c3c0f665c2 --- /dev/null +++ b/build_msvc/common.init.vcxproj @@ -0,0 +1,14 @@ + + + + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0@ProductVersion) + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0@ProductVersion) + + $(WindowsTargetPlatformVersion_10).0 + + $(WindowsTargetPlatformVersion_10) + + + Win32 + + \ No newline at end of file diff --git a/build_msvc/common.vcxproj b/build_msvc/common.vcxproj new file mode 100644 index 0000000000..3a53f3bad3 --- /dev/null +++ b/build_msvc/common.vcxproj @@ -0,0 +1,15 @@ + + + + + + CopyConfig; + $(BuildDependsOn); + + + + + + \ No newline at end of file diff --git a/build_msvc/libbitcoin_cli/libbitcoin_cli.vcxproj b/build_msvc/libbitcoin_cli/libbitcoin_cli.vcxproj new file mode 100644 index 0000000000..623d24da10 --- /dev/null +++ b/build_msvc/libbitcoin_cli/libbitcoin_cli.vcxproj @@ -0,0 +1,162 @@ + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + 15.0 + {0667528C-D734-4009-ADF9-C0D6C4A5A5A6} + Win32Proj + libbitcoin_cli + x86-windows-static + x64-windows-static + + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + false + + + true + + + true + + + false + + + + NotUsing + Level3 + MaxSpeed + true + true + _SCL_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreaded + + + Console + true + true + true + + + + + NotUsing + Level3 + Disabled + _SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreadedDebug + + + Console + true + + + + + NotUsing + Level3 + Disabled + _SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreadedDebug + + + Console + true + + + + + NotUsing + Level3 + MaxSpeed + true + true + _SCL_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreaded + + + Console + true + true + true + + + + diff --git a/build_msvc/libbitcoin_common/libbitcoin_common.vcxproj b/build_msvc/libbitcoin_common/libbitcoin_common.vcxproj new file mode 100644 index 0000000000..e6d95ed5f3 --- /dev/null +++ b/build_msvc/libbitcoin_common/libbitcoin_common.vcxproj @@ -0,0 +1,210 @@ + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {7C87E378-DF58-482E-AA2F-1BC129BC19CE} + Win32Proj + libbitcoin_common + x86-windows-static + x64-windows-static + + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + NotUsing + Level3 + Disabled + WIN32;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + false + MultiThreadedDebug + + + Console + true + + + + + + + NotUsing + Level3 + Disabled + WIN32;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + false + MultiThreadedDebug + + + Console + true + + + + + + + NotUsing + Level3 + MaxSpeed + true + true + WIN32;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + false + MultiThreaded + + + Console + true + true + true + + + + + + + NotUsing + Level3 + MaxSpeed + true + true + WIN32;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + false + MultiThreaded + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build_msvc/libbitcoin_crypto/libbitcoin_crypto.vcxproj b/build_msvc/libbitcoin_crypto/libbitcoin_crypto.vcxproj new file mode 100644 index 0000000000..50519d045f --- /dev/null +++ b/build_msvc/libbitcoin_crypto/libbitcoin_crypto.vcxproj @@ -0,0 +1,175 @@ + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {6190199C-6CF4-4DAD-BFBD-93FA72A760C1} + Win32Proj + libbitcoin_crypto + + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + NotUsing + Level3 + Disabled + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src + MultiThreadedDebug + + + Console + true + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src + MultiThreadedDebug + + + Console + true + + + + + NotUsing + Level3 + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src + MultiThreaded + + + Console + true + true + true + + + + + NotUsing + Level3 + MaxSpeed + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src + MultiThreaded + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build_msvc/libbitcoin_qt/libbitcoin_qt.vcxproj b/build_msvc/libbitcoin_qt/libbitcoin_qt.vcxproj new file mode 100644 index 0000000000..2e8ecb2d2c --- /dev/null +++ b/build_msvc/libbitcoin_qt/libbitcoin_qt.vcxproj @@ -0,0 +1,955 @@ + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + x86-windows-static + x64-windows-static + {2B4ABFF8-D1FD-4845-88C9-1F3C0A6512BF} + + + + "$(QTDIR)\bincc.exe" -name bitcoin "%(Fullpath)" -o .\GeneratedFiles\qrc_bitcoin.cpp + Qt rcc generation for %(Identity) + .\GeneratedFiles\qrc_bitcoin.cpp + (QTDIR)\bincc.exe + + + "$(QTDIR)\bincc.exe" -name bitcoin_locale "%(Fullpath)" -o .\GeneratedFiles\qrc_bitcoin_locale.cpp + Qt rcc generation for %(Identity) + .\GeneratedFiles\qrc_bitcoin_locale.cpp + (QTDIR)\bincc.exe + + + + + + + + + + + + + + + + + + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + Document + F:\Dependencies\protobuf-cpp-3.4.1\protobuf-3.4.1\cmake\build\vs\Debug\protoc.exe --proto_path=%(RootDir)%(Directory) %(Fullpath) --cpp_out=.\GeneratedFiles + ProtoBuf source generation %(RootDir)%(Directory) %(Filename) + .\GeneratedFiles\%(Filename).pb.h;.\GeneratedFiles\(%Filename).pb.cc + F:\Dependencies\protobuf-cpp-3.4.1\protobuf-3.4.1\cmake\build\vs\Debug\protoc.exe + false + F:\deps\protobuf\protobuf-3.4.1\cmake\build\vs\Debug\protoc.exe --proto_path=%(RootDir)%(Directory) %(Fullpath) --cpp_out=.\GeneratedFiles + F:\deps\protobuf\protobuf-3.4.1\cmake\build\vs\Debug\protoc.exe + + + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + + + + + + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + + + + + "$(QTDIR)\bin\moc.exe" "%(Fullpath)" -o .\GeneratedFiles\%(Filename).moc $(MOC_DEF) + Qt moc generation for %(Identity) + .\GeneratedFiles\%(Filename).moc + (QTDIR)\bin\moc.exe + + + "$(QTDIR)\bin\moc.exe" "%(Fullpath)" -o .\GeneratedFiles\%(Filename).moc $(MOC_DEF) + Qt moc generation for %(Identity) + .\GeneratedFiles\%(Filename).moc + (QTDIR)\bin\moc.exe + + + "$(QTDIR)\bin\moc.exe" "%(Fullpath)" -o .\GeneratedFiles\%(Filename).moc $(MOC_DEF) + Qt moc generation for %(Identity) + .\GeneratedFiles\%(Filename).moc + (QTDIR)\bin\moc.exe + + + "$(QTDIR)\bin\moc.exe" "%(Fullpath)" -o .\GeneratedFiles\%(Filename).moc $(MOC_DEF) + Qt moc generation for %(Identity) + .\GeneratedFiles\%(Filename).moc + (QTDIR)\bin\moc.exe + + + "$(QTDIR)\bin\moc.exe" "%(Fullpath)" -o .\GeneratedFiles\%(Filename).moc $(MOC_DEF) + Qt moc generation for %(Identity) + .\GeneratedFiles\%(Filename).moc + (QTDIR)\bin\moc.exe + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + false + static + ClCompile + + + true + static + ClCompile + + + true + static + ClCompile + + + false + static + ClCompile + + + + NotUsing + Level3 + Disabled + true + false + _X86_;WIN32;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + .\GeneratedFiles;..\..\src;..\..\src\univalue\include;.\QtGenerated\mocheaders + MultiThreaded + + + Console + true + true + true + + + + + NotUsing + Level3 + Disabled + _X86_;WIN32;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + .\GeneratedFiles;..\..\src;..\..\src\univalue\include;.\QtGenerated\mocheaders + MultiThreadedDebug + + + Console + true + + + + + NotUsing + Level3 + Disabled + WIN32;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + .\GeneratedFiles;..\..\src;..\..\src\univalue\include;.\QtGenerated\mocheaders + MultiThreadedDebug + + + Console + true + + + + + NotUsing + Level3 + MaxSpeed + true + true + WIN32;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + .\GeneratedFiles;..\..\src;..\..\src\univalue\include;.\QtGenerated\mocheaders + MultiThreaded + + + Console + true + true + true + + + + + + There was an error executing the Qt headers moc code generation tasks. + + + + + + + + + There was an error executing the Qt forms code generation tasks. + + + + + + + + + There was an error executing the Qt local code generation tasks. + + + + + + + + + + + + + + + diff --git a/build_msvc/libbitcoin_server/libbitcoin_server.vcxproj b/build_msvc/libbitcoin_server/libbitcoin_server.vcxproj new file mode 100644 index 0000000000..9d4ac1a7f7 --- /dev/null +++ b/build_msvc/libbitcoin_server/libbitcoin_server.vcxproj @@ -0,0 +1,212 @@ + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {460FEE33-1FE1-483F-B3BF-931FF8E969A5} + Win32Proj + libbitcoin_server + x86-windows-static + x64-windows-static + + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + NotUsing + Level3 + Disabled + WIN32;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreadedDebug + + + Console + true + + + + + NotUsing + Level3 + Disabled + WIN32;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreadedDebug + false + + + Console + true + + + + + NotUsing + Level3 + MaxSpeed + true + true + WIN32;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreaded + + + Console + true + true + true + + + + + NotUsing + Level3 + MaxSpeed + true + true + WIN32;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreaded + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(IntDir)\netrpc.obj + $(IntDir)\netrpc.obj + $(IntDir)\netrpc.obj + $(IntDir)\netrpc.obj + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build_msvc/libbitcoin_util/libbitcoin_util.vcxproj b/build_msvc/libbitcoin_util/libbitcoin_util.vcxproj new file mode 100644 index 0000000000..9e960682e5 --- /dev/null +++ b/build_msvc/libbitcoin_util/libbitcoin_util.vcxproj @@ -0,0 +1,196 @@ + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {B53A5535-EE9D-4C6F-9A26-F79EE3BC3754} + Win32Proj + libbitcoin_util + libbitcoin_util + x86-windows-static + x64-windows-static + + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + NotUsing + Level3 + Disabled + HAVE_CONFIG_H;WIN32;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreadedDebug + + + Console + true + + + + + false + + + + + NotUsing + Level3 + Disabled + HAVE_CONFIG_H;WIN32;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreadedDebug + + + Console + true + + + + + false + + + + + NotUsing + Level3 + MaxSpeed + true + true + HAVE_CONFIG_H;WIN32;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreaded + + + Console + true + true + true + + + + + false + + + + + NotUsing + Level3 + MaxSpeed + true + true + HAVE_CONFIG_H;WIN32;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreaded + + + Console + true + true + true + + + + + false + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build_msvc/libbitcoin_wallet/libbitcoin_wallet.vcxproj b/build_msvc/libbitcoin_wallet/libbitcoin_wallet.vcxproj new file mode 100644 index 0000000000..64f3e16289 --- /dev/null +++ b/build_msvc/libbitcoin_wallet/libbitcoin_wallet.vcxproj @@ -0,0 +1,177 @@ + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + 15.0 + {93B86837-B543-48A5-A89B-7C87ABB77DF2} + Win32Proj + libbitcoin_wallet + x86-windows-static + x64-windows-static + + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + NotUsing + Level3 + Disabled + HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\wallet;..\..\src\univalue\include; + MultiThreadedDebug + /bigobj %(AdditionalOptions) + + + Console + true + + + + + NotUsing + Level3 + Disabled + HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\wallet;..\..\src\univalue\include; + MultiThreadedDebug + /bigobj %(AdditionalOptions) + + + Console + true + + + + + NotUsing + Level3 + MaxSpeed + true + true + HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\wallet;..\..\src\univalue\include; + MultiThreaded + /bigobj %(AdditionalOptions) + + + Console + true + true + true + + + + + NotUsing + Level3 + MaxSpeed + true + true + HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\wallet;..\..\src\univalue\include; + MultiThreaded + /bigobj %(AdditionalOptions) + + + Console + true + true + true + + + + diff --git a/build_msvc/libbitcoin_zmq/libbitcoin_zmq.vcxproj b/build_msvc/libbitcoin_zmq/libbitcoin_zmq.vcxproj new file mode 100644 index 0000000000..d7fbdd94b7 --- /dev/null +++ b/build_msvc/libbitcoin_zmq/libbitcoin_zmq.vcxproj @@ -0,0 +1,169 @@ + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + 15.0 + {792D487F-F14C-49FC-A9DE-3FC150F31C3F} + Win32Proj + libbitcoin_zmq + x86-windows-static + x64-windows-static + + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + NotUsing + Level3 + Disabled + NOMINMAX;ZMQ_STATIC;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreadedDebug + false + + + Console + true + + + + + NotUsing + Level3 + Disabled + NOMINMAX;ZMQ_STATIC;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreadedDebug + false + + + Console + true + + + + + NotUsing + Level3 + MaxSpeed + true + true + NOMINMAX;ZMQ_STATIC;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreaded + false + + + Console + true + true + true + + + + + NotUsing + Level3 + MaxSpeed + true + true + NOMINMAX;ZMQ_STATIC;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include; + MultiThreaded + false + + + Console + true + true + true + + + + diff --git a/build_msvc/libbitcoinconsensus/libbitcoinconsensus.vcxproj b/build_msvc/libbitcoinconsensus/libbitcoinconsensus.vcxproj new file mode 100644 index 0000000000..e6f4885e5e --- /dev/null +++ b/build_msvc/libbitcoinconsensus/libbitcoinconsensus.vcxproj @@ -0,0 +1,199 @@ + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 15.0 + {2B384FA8-9EE1-4544-93CB-0D733C25E8CE} + Win32Proj + bitcoind + libbitcoin_consensus + x86-windows-static + x64-windows-static + + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + + + true + + + + + true + + + + + true + + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + ..\..\src; + false + false + MultiThreadedDebug + + + Console + true + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + ..\..\src; + false + false + MultiThreadedDebug + + + Console + true + + + + + NotUsing + Level3 + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + ..\..\src; + false + false + MultiThreaded + + + Console + true + true + true + + + + + NotUsing + Level3 + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + ..\..\src; + false + false + MultiThreaded + + + Console + true + true + true + + + + \ No newline at end of file diff --git a/build_msvc/libunivalue/libunivalue.vcxproj b/build_msvc/libunivalue/libunivalue.vcxproj new file mode 100644 index 0000000000..57d469debf --- /dev/null +++ b/build_msvc/libunivalue/libunivalue.vcxproj @@ -0,0 +1,160 @@ + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + 15.0 + {5724BA7D-A09A-4BA8-800B-C4C1561B3D69} + Win32Proj + libunivalue + + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src\univalue\include; + MultiThreadedDebug + + + Console + true + + + + + NotUsing + Level3 + Disabled + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src\univalue\include; + MultiThreadedDebug + + + Console + true + + + + + NotUsing + Level3 + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src\univalue\include; + MultiThreaded + + + Console + true + true + true + + + + + NotUsing + Level3 + MaxSpeed + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src\univalue\include; + MultiThreaded + + + Console + true + true + true + + + + diff --git a/build_msvc/msbuild/tasks/hexdump.targets b/build_msvc/msbuild/tasks/hexdump.targets new file mode 100644 index 0000000000..12868a9874 --- /dev/null +++ b/build_msvc/msbuild/tasks/hexdump.targets @@ -0,0 +1,53 @@ + + + + + + + + + + + + + outFileInfo.LastWriteTime) + { + using (Stream inStm = File.OpenRead(RawFilePath)) + { + using (StreamWriter sw = new StreamWriter(HeaderFilePath)) + { + sw.WriteLine(SourceHeader); + int count = 0; + int rawChar = inStm.ReadByte(); + while(rawChar != -1) + { + sw.Write("0x{0:x2}, ", rawChar); + count++; + if(count % 8 == 0) + { + sw.WriteLine(); + } + rawChar = inStm.ReadByte(); + } + sw.WriteLine(SourceFooter); + } + } + } +} +]]> + + + + \ No newline at end of file diff --git a/build_msvc/test_bitcoin-qt/test_bitcoin-qt.vcxproj b/build_msvc/test_bitcoin-qt/test_bitcoin-qt.vcxproj new file mode 100644 index 0000000000..b2d4c118f3 --- /dev/null +++ b/build_msvc/test_bitcoin-qt/test_bitcoin-qt.vcxproj @@ -0,0 +1,146 @@ + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {51201D5E-D939-4854-AE9D-008F03FF518E} + Win32Proj + test_bitcoinqt + + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + false + + + true + + + true + + + false + + + + NotUsing + Level3 + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + NotUsing + Level3 + Disabled + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + NotUsing + Level3 + MaxSpeed + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + diff --git a/build_msvc/test_bitcoin/test_bitcoin.vcxproj b/build_msvc/test_bitcoin/test_bitcoin.vcxproj new file mode 100644 index 0000000000..0ab97643fb --- /dev/null +++ b/build_msvc/test_bitcoin/test_bitcoin.vcxproj @@ -0,0 +1,269 @@ + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {2b384fa8-9ee1-4544-93cb-0d733c25e8ce} + + + {0667528c-d734-4009-adf9-c0d6c4a5a5a6} + + + {7c87e378-df58-482e-aa2f-1bc129bc19ce} + + + {6190199c-6cf4-4dad-bfbd-93fa72a760c1} + + + {460fee33-1fe1-483f-b3bf-931ff8e969a5} + + + {b53a5535-ee9d-4c6f-9a26-f79ee3bc3754} + + + {93b86837-b543-48a5-a89b-7c87abb77df2} + + + {792d487f-f14c-49fc-a9de-3fc150f31c3f} + + + {5724ba7d-a09a-4ba8-800b-c4c1561b3d69} + + + + 15.0 + {A56B73DB-D46D-4882-8374-1FE3FFA08F07} + Win32Proj + test_bitcoin + x86-windows-static + x64-windows-static + + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + NotUsing + Level3 + Disabled + _CRT_SECURE_NO_WARNINGS;NOMINMAX;WIN32;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include;..\..\src\test; + MultiThreadedDebug + + + Console + true + false + boost_test_exec_monitor-vc140-mt-gd.lib;crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + NotUsing + Level3 + Disabled + _CRT_SECURE_NO_WARNINGS;NOMINMAX;WIN32;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include;..\..\src\test; + MultiThreadedDebug + + + Console + true + boost_test_exec_monitor-vc140-mt-gd.lib;crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + NotUsing + Level3 + MaxSpeed + true + true + _CRT_SECURE_NO_WARNINGS;NOMINMAX;WIN32;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include;..\..\src\test; + MultiThreaded + + + Console + true + true + true + boost_test_exec_monitor-vc140-mt.lib;crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + NotUsing + Level3 + MaxSpeed + true + true + _CRT_SECURE_NO_WARNINGS;NOMINMAX;WIN32;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src;..\..\src\univalue\include;..\..\src\test; + MultiThreaded + + + Console + true + true + true + boost_test_exec_monitor-vc140-mt.lib;crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + There was an error executing the JSON test header generation task. + + + + + + + + + \ No newline at end of file diff --git a/build_msvc/testconsensus/testconsensus.cpp b/build_msvc/testconsensus/testconsensus.cpp new file mode 100644 index 0000000000..0068f588cc --- /dev/null +++ b/build_msvc/testconsensus/testconsensus.cpp @@ -0,0 +1,50 @@ +#include + +// bitcoin includes. +#include <..\src\script\bitcoinconsensus.h> +#include <..\src\primitives\transaction.h> +#include <..\src\script\script.h> +#include <..\src\streams.h> +#include <..\src\version.h> + +CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CScriptWitness& scriptWitness, int nValue = 0) +{ + CMutableTransaction txSpend; + txSpend.nVersion = 1; + txSpend.nLockTime = 0; + txSpend.vin.resize(1); + txSpend.vout.resize(1); + txSpend.vin[0].scriptWitness = scriptWitness; + txSpend.vin[0].prevout.hash = uint256(); + txSpend.vin[0].prevout.n = 0; + txSpend.vin[0].scriptSig = scriptSig; + txSpend.vin[0].nSequence = CTxIn::SEQUENCE_FINAL; + txSpend.vout[0].scriptPubKey = CScript(); + txSpend.vout[0].nValue = nValue; + + return txSpend; +} + +int main() +{ + std::cout << "bitcoinconsensus version: " << bitcoinconsensus_version() << std::endl; + + CScript pubKeyScript; + pubKeyScript << OP_1 << OP_0 << OP_1; + + int amount = 0; // 600000000; + + CScript scriptSig; + CScriptWitness scriptWitness; + CTransaction vanillaSpendTx = BuildSpendingTransaction(scriptSig, scriptWitness, amount); + CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); + stream << vanillaSpendTx; + + bitcoinconsensus_error err; + auto op0Result = bitcoinconsensus_verify_script_with_amount(pubKeyScript.data(), pubKeyScript.size(), amount, (const unsigned char*)&stream[0], stream.size(), 0, bitcoinconsensus_SCRIPT_FLAGS_VERIFY_ALL, &err); + std::cout << "Op0 result: " << op0Result << ", error code " << err << std::endl; + + getchar(); + + return 0; +} diff --git a/build_msvc/testconsensus/testconsensus.vcxproj b/build_msvc/testconsensus/testconsensus.vcxproj new file mode 100644 index 0000000000..d73988df1c --- /dev/null +++ b/build_msvc/testconsensus/testconsensus.vcxproj @@ -0,0 +1,173 @@ + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {E78473E9-B850-456C-9120-276301E04C06} + Win32Proj + testconsensus + test_libbitcoinconsensus + x86-windows-static + x64-windows-static + + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + static + + + true + static + + + false + static + + + false + + + + NotUsing + Level3 + Disabled + HAVE_CONFIG_H;WIN32;_SCL_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src\; + MultiThreadedDebug + + + Console + true + + + + + NotUsing + Level3 + Disabled + HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src\; + MultiThreadedDebug + + + Console + true + true + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + NotUsing + Level3 + MaxSpeed + true + true + HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src\; + MultiThreaded + + + Console + true + true + true + + + + + NotUsing + Level3 + MaxSpeed + true + true + HAVE_CONFIG_H;WIN32;_CONSOLE;%(PreprocessorDefinitions) + true + ..\..\src\; + MultiThreaded + + + Console + true + true + true + + + + + + + + {2b384fa8-9ee1-4544-93cb-0d733c25e8ce} + + + {b53a5535-ee9d-4c6f-9a26-f79ee3bc3754} + + + + From a679109be40491222c458fdbef58f68509dae0bd Mon Sep 17 00:00:00 2001 From: "lucash.dev@gmail.com" Date: Sat, 12 May 2018 09:06:38 -0700 Subject: [PATCH 0042/1200] Speed up knapsack_solver_test by not recreating wallet 100 times. Moved the code for creating the wallet out of the 100-times repetition loop, for the most time-consuming tests. --- src/wallet/test/coinselector_tests.cpp | 61 +++++++++++++++----------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/src/wallet/test/coinselector_tests.cpp b/src/wallet/test/coinselector_tests.cpp index 0776ffda9c..c04a50c12b 100644 --- a/src/wallet/test/coinselector_tests.cpp +++ b/src/wallet/test/coinselector_tests.cpp @@ -452,14 +452,19 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test) BOOST_CHECK(testWallet.SelectCoinsMinConf(MIN_CHANGE * 9990 / 100, filter_confirmed, GroupCoins(vCoins), setCoinsRet, nValueRet, coin_selection_params, bnb_used)); BOOST_CHECK_EQUAL(nValueRet, 101 * MIN_CHANGE); BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); + } - // test with many inputs - for (CAmount amt=1500; amt < COIN; amt*=10) { - empty_wallet(); - // Create 676 inputs (= (old MAX_STANDARD_TX_SIZE == 100000) / 148 bytes per input) - for (uint16_t j = 0; j < 676; j++) - add_coin(amt); + // test with many inputs + for (CAmount amt=1500; amt < COIN; amt*=10) { + empty_wallet(); + // Create 676 inputs (= (old MAX_STANDARD_TX_SIZE == 100000) / 148 bytes per input) + for (uint16_t j = 0; j < 676; j++) + add_coin(amt); + + // We only create the wallet once to save time, but we still run the coin selection RUN_TESTS times. + for (int i = 0; i < RUN_TESTS; i++) { BOOST_CHECK(testWallet.SelectCoinsMinConf(2000, filter_confirmed, GroupCoins(vCoins), setCoinsRet, nValueRet, coin_selection_params, bnb_used)); + if (amt - 2000 < MIN_CHANGE) { // needs more than one input: uint16_t returnSize = std::ceil((2000.0 + MIN_CHANGE)/amt); @@ -471,14 +476,17 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test) BOOST_CHECK_EQUAL(nValueRet, amt); BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); } - } + } + } - // test randomness - { - empty_wallet(); - for (int i2 = 0; i2 < 100; i2++) - add_coin(COIN); + // test randomness + { + empty_wallet(); + for (int i2 = 0; i2 < 100; i2++) + add_coin(COIN); + // Again, we only create the wallet once to save time, but we still run the coin selection RUN_TESTS times. + for (int i = 0; i < RUN_TESTS; i++) { // picking 50 from 100 coins doesn't depend on the shuffle, // but does depend on randomness in the stochastic approximation code BOOST_CHECK(testWallet.SelectCoinsMinConf(50 * COIN, filter_standard, GroupCoins(vCoins), setCoinsRet , nValueRet, coin_selection_params, bnb_used)); @@ -496,17 +504,19 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test) fails++; } BOOST_CHECK_NE(fails, RANDOM_REPEATS); - - // add 75 cents in small change. not enough to make 90 cents, - // then try making 90 cents. there are multiple competing "smallest bigger" coins, - // one of which should be picked at random - add_coin(5 * CENT); - add_coin(10 * CENT); - add_coin(15 * CENT); - add_coin(20 * CENT); - add_coin(25 * CENT); - - fails = 0; + } + + // add 75 cents in small change. not enough to make 90 cents, + // then try making 90 cents. there are multiple competing "smallest bigger" coins, + // one of which should be picked at random + add_coin(5 * CENT); + add_coin(10 * CENT); + add_coin(15 * CENT); + add_coin(20 * CENT); + add_coin(25 * CENT); + + for (int i = 0; i < RUN_TESTS; i++) { + int fails = 0; for (int j = 0; j < RANDOM_REPEATS; j++) { // selecting 1 from 100 identical coins depends on the shuffle; this test will fail 1% of the time @@ -517,8 +527,9 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test) fails++; } BOOST_CHECK_NE(fails, RANDOM_REPEATS); - } - } + } + } + empty_wallet(); } From 2da54f5a66f91306c064d685bffcee2062b6ebd2 Mon Sep 17 00:00:00 2001 From: DesWurstes Date: Fri, 10 Aug 2018 18:04:42 +0300 Subject: [PATCH 0043/1200] Cleanup StartRest() --- src/httprpc.h | 2 +- src/init.cpp | 3 +-- src/rest.cpp | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/httprpc.h b/src/httprpc.h index 193f8d617a..2230a8ca4e 100644 --- a/src/httprpc.h +++ b/src/httprpc.h @@ -23,7 +23,7 @@ void StopHTTPRPC(); /** Start HTTP REST subsystem. * Precondition; HTTP and RPC has been started. */ -bool StartREST(); +void StartREST(); /** Interrupt RPC REST subsystem. */ void InterruptREST(); diff --git a/src/init.cpp b/src/init.cpp index 5c29736913..482107c06f 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -736,8 +736,7 @@ static bool AppInitServers() StartRPC(); if (!StartHTTPRPC()) return false; - if (gArgs.GetBoolArg("-rest", DEFAULT_REST_ENABLE) && !StartREST()) - return false; + if (gArgs.GetBoolArg("-rest", DEFAULT_REST_ENABLE)) StartREST(); StartHTTPServer(); return true; } diff --git a/src/rest.cpp b/src/rest.cpp index b81a6f9c5f..12358cf50d 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -591,11 +591,10 @@ static const struct { {"/rest/getutxos", rest_getutxos}, }; -bool StartREST() +void StartREST() { for (unsigned int i = 0; i < ARRAYLEN(uri_prefixes); i++) RegisterHTTPHandler(uri_prefixes[i].prefix, false, uri_prefixes[i].handler); - return true; } void InterruptREST() From fa6c3dea420b6c50c164ccc34f4e9e8a7d9a8022 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 12 Aug 2018 07:55:01 -0400 Subject: [PATCH 0044/1200] p2p: Clarify control flow in ProcessMessage() --- src/net_processing.cpp | 117 +++++++++++++++++------------------------ 1 file changed, 49 insertions(+), 68 deletions(-) diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 88999ba735..c31e1c0c60 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1618,8 +1618,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr return true; } - else if (strCommand == NetMsgType::VERSION) - { + if (strCommand == NetMsgType::VERSION) { // Each connection can only send one version message if (pfrom->nVersion != 0) { @@ -1796,9 +1795,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr return true; } - - else if (pfrom->nVersion == 0) - { + if (pfrom->nVersion == 0) { // Must have a version message before anything else LOCK(cs_main); Misbehaving(pfrom->GetId(), 1); @@ -1842,18 +1839,17 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion)); } pfrom->fSuccessfullyConnected = true; + return true; } - else if (!pfrom->fSuccessfullyConnected) - { + if (!pfrom->fSuccessfullyConnected) { // Must have a verack message before anything else LOCK(cs_main); Misbehaving(pfrom->GetId(), 1); return false; } - else if (strCommand == NetMsgType::ADDR) - { + if (strCommand == NetMsgType::ADDR) { std::vector vAddr; vRecv >> vAddr; @@ -1900,16 +1896,16 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr pfrom->fGetAddr = false; if (pfrom->fOneShot) pfrom->fDisconnect = true; + return true; } - else if (strCommand == NetMsgType::SENDHEADERS) - { + if (strCommand == NetMsgType::SENDHEADERS) { LOCK(cs_main); State(pfrom->GetId())->fPreferHeaders = true; + return true; } - else if (strCommand == NetMsgType::SENDCMPCT) - { + if (strCommand == NetMsgType::SENDCMPCT) { bool fAnnounceUsingCMPCTBLOCK = false; uint64_t nCMPCTBLOCKVersion = 0; vRecv >> fAnnounceUsingCMPCTBLOCK >> nCMPCTBLOCKVersion; @@ -1929,11 +1925,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr State(pfrom->GetId())->fSupportsDesiredCmpctVersion = (nCMPCTBLOCKVersion == 1); } } + return true; } - - else if (strCommand == NetMsgType::INV) - { + if (strCommand == NetMsgType::INV) { std::vector vInv; vRecv >> vInv; if (vInv.size() > MAX_INV_SZ) @@ -1987,11 +1982,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr } } } + return true; } - - else if (strCommand == NetMsgType::GETDATA) - { + if (strCommand == NetMsgType::GETDATA) { std::vector vInv; vRecv >> vInv; if (vInv.size() > MAX_INV_SZ) @@ -2009,11 +2003,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end()); ProcessGetData(pfrom, chainparams, connman, interruptMsgProc); + return true; } - - else if (strCommand == NetMsgType::GETBLOCKS) - { + if (strCommand == NetMsgType::GETBLOCKS) { CBlockLocator locator; uint256 hashStop; vRecv >> locator >> hashStop; @@ -2078,11 +2071,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr break; } } + return true; } - - else if (strCommand == NetMsgType::GETBLOCKTXN) - { + if (strCommand == NetMsgType::GETBLOCKTXN) { BlockTransactionsRequest req; vRecv >> req; @@ -2128,11 +2120,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr assert(ret); SendBlockTransactions(block, req, pfrom, connman); + return true; } - - else if (strCommand == NetMsgType::GETHEADERS) - { + if (strCommand == NetMsgType::GETHEADERS) { CBlockLocator locator; uint256 hashStop; vRecv >> locator >> hashStop; @@ -2196,11 +2187,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr // in the SendMessages logic. nodestate->pindexBestHeaderSent = pindex ? pindex : chainActive.Tip(); connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::HEADERS, vHeaders)); + return true; } - - else if (strCommand == NetMsgType::TX) - { + if (strCommand == NetMsgType::TX) { // Stop processing the transaction early if // We are in blocks only mode and peer is either not whitelisted or whitelistrelay is off if (!fRelayTxes && (!pfrom->fWhitelisted || !gArgs.GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY))) @@ -2384,10 +2374,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr Misbehaving(pfrom->GetId(), nDoS); } } + return true; } - - else if (strCommand == NetMsgType::CMPCTBLOCK && !fImporting && !fReindex) // Ignore blocks received while importing + if (strCommand == NetMsgType::CMPCTBLOCK && !fImporting && !fReindex) // Ignore blocks received while importing { CBlockHeaderAndShortTxIDs cmpctblock; vRecv >> cmpctblock; @@ -2605,10 +2595,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr MarkBlockAsReceived(pblock->GetHash()); } } - + return true; } - else if (strCommand == NetMsgType::BLOCKTXN && !fImporting && !fReindex) // Ignore blocks received while importing + if (strCommand == NetMsgType::BLOCKTXN && !fImporting && !fReindex) // Ignore blocks received while importing { BlockTransactions resp; vRecv >> resp; @@ -2680,10 +2670,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr mapBlockSource.erase(pblock->GetHash()); } } + return true; } - - else if (strCommand == NetMsgType::HEADERS && !fImporting && !fReindex) // Ignore headers received while importing + if (strCommand == NetMsgType::HEADERS && !fImporting && !fReindex) // Ignore headers received while importing { std::vector headers; @@ -2708,7 +2698,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr return ProcessHeadersMessage(pfrom, connman, headers, chainparams, should_punish); } - else if (strCommand == NetMsgType::BLOCK && !fImporting && !fReindex) // Ignore blocks received while importing + if (strCommand == NetMsgType::BLOCK && !fImporting && !fReindex) // Ignore blocks received while importing { std::shared_ptr pblock = std::make_shared(); vRecv >> *pblock; @@ -2734,11 +2724,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr LOCK(cs_main); mapBlockSource.erase(pblock->GetHash()); } + return true; } - - else if (strCommand == NetMsgType::GETADDR) - { + if (strCommand == NetMsgType::GETADDR) { // This asymmetric behavior for inbound and outbound connections was introduced // to prevent a fingerprinting attack: an attacker can send specific fake addresses // to users' AddrMan and later request them by sending getaddr messages. @@ -2762,11 +2751,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr FastRandomContext insecure_rand; for (const CAddress &addr : vAddr) pfrom->PushAddress(addr, insecure_rand); + return true; } - - else if (strCommand == NetMsgType::MEMPOOL) - { + if (strCommand == NetMsgType::MEMPOOL) { if (!(pfrom->GetLocalServices() & NODE_BLOOM) && !pfrom->fWhitelisted) { LogPrint(BCLog::NET, "mempool request with bloom filters disabled, disconnect peer=%d\n", pfrom->GetId()); @@ -2783,11 +2771,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr LOCK(pfrom->cs_inventory); pfrom->fSendMempool = true; + return true; } - - else if (strCommand == NetMsgType::PING) - { + if (strCommand == NetMsgType::PING) { if (pfrom->nVersion > BIP0031_VERSION) { uint64_t nonce = 0; @@ -2805,11 +2792,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr // return very quickly. connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::PONG, nonce)); } + return true; } - - else if (strCommand == NetMsgType::PONG) - { + if (strCommand == NetMsgType::PONG) { int64_t pingUsecEnd = nTimeReceived; uint64_t nonce = 0; size_t nAvail = vRecv.in_avail(); @@ -2862,11 +2848,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr if (bPingFinished) { pfrom->nPingNonceSent = 0; } + return true; } - - else if (strCommand == NetMsgType::FILTERLOAD) - { + if (strCommand == NetMsgType::FILTERLOAD) { CBloomFilter filter; vRecv >> filter; @@ -2883,11 +2868,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr pfrom->pfilter->UpdateEmptyFull(); pfrom->fRelayTxes = true; } + return true; } - - else if (strCommand == NetMsgType::FILTERADD) - { + if (strCommand == NetMsgType::FILTERADD) { std::vector vData; vRecv >> vData; @@ -2908,19 +2892,19 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr LOCK(cs_main); Misbehaving(pfrom->GetId(), 100); } + return true; } - - else if (strCommand == NetMsgType::FILTERCLEAR) - { + if (strCommand == NetMsgType::FILTERCLEAR) { LOCK(pfrom->cs_filter); if (pfrom->GetLocalServices() & NODE_BLOOM) { pfrom->pfilter.reset(new CBloomFilter()); } pfrom->fRelayTxes = true; + return true; } - else if (strCommand == NetMsgType::FEEFILTER) { + if (strCommand == NetMsgType::FEEFILTER) { CAmount newFeeFilter = 0; vRecv >> newFeeFilter; if (MoneyRange(newFeeFilter)) { @@ -2930,20 +2914,17 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr } LogPrint(BCLog::NET, "received: feefilter of %s from peer=%d\n", CFeeRate(newFeeFilter).ToString(), pfrom->GetId()); } + return true; } - else if (strCommand == NetMsgType::NOTFOUND) { + if (strCommand == NetMsgType::NOTFOUND) { // We do not care about the NOTFOUND message, but logging an Unknown Command // message would be undesirable as we transmit it ourselves. + return true; } - else { - // Ignore unknown commands for extensibility - LogPrint(BCLog::NET, "Unknown command \"%s\" from peer=%d\n", SanitizeString(strCommand), pfrom->GetId()); - } - - - + // Ignore unknown commands for extensibility + LogPrint(BCLog::NET, "Unknown command \"%s\" from peer=%d\n", SanitizeString(strCommand), pfrom->GetId()); return true; } From 265bd50884ac1984c08f0e5916256d5f12e655f5 Mon Sep 17 00:00:00 2001 From: 251 <13120787+251Labs@users.noreply.github.com> Date: Mon, 13 Aug 2018 00:37:15 +0200 Subject: [PATCH 0045/1200] Removes unsed `CBloomFilter` constructor. This commit removes the `CBloomFilter::CBloomFilter(const unsigned int, const double, const unsigned int)` constructor, which became obsolete with 086ee67. --- src/bloom.cpp | 11 ----------- src/bloom.h | 4 ---- 2 files changed, 15 deletions(-) diff --git a/src/bloom.cpp b/src/bloom.cpp index 24eebe2e3e..94aae742f1 100644 --- a/src/bloom.cpp +++ b/src/bloom.cpp @@ -38,17 +38,6 @@ CBloomFilter::CBloomFilter(const unsigned int nElements, const double nFPRate, c { } -// Private constructor used by CRollingBloomFilter -CBloomFilter::CBloomFilter(const unsigned int nElements, const double nFPRate, const unsigned int nTweakIn) : - vData((unsigned int)(-1 / LN2SQUARED * nElements * log(nFPRate)) / 8), - isFull(false), - isEmpty(true), - nHashFuncs((unsigned int)(vData.size() * 8 / nElements * LN2)), - nTweak(nTweakIn), - nFlags(BLOOM_UPDATE_NONE) -{ -} - inline unsigned int CBloomFilter::Hash(unsigned int nHashNum, const std::vector& vDataToHash) const { // 0xFBA4C795 chosen as it guarantees a reasonable bit difference between nHashNum values. diff --git a/src/bloom.h b/src/bloom.h index e136fcebfc..7d3aa878b0 100644 --- a/src/bloom.h +++ b/src/bloom.h @@ -53,10 +53,6 @@ class CBloomFilter unsigned int Hash(unsigned int nHashNum, const std::vector& vDataToHash) const; - // Private constructor for CRollingBloomFilter, no restrictions on size - CBloomFilter(const unsigned int nElements, const double nFPRate, const unsigned int nTweak); - friend class CRollingBloomFilter; - public: /** * Creates a new bloom filter which will provide the given fp rate when filled with the given number of elements From 49e56625aa2e102472f782e7421a332b4f438f54 Mon Sep 17 00:00:00 2001 From: Isidoro Ghezzi Date: Mon, 13 Aug 2018 14:04:44 +0200 Subject: [PATCH 0046/1200] fix deprecation in bitcoin-util-test.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To avoid: $ make check {…omissis…} Running test/util/bitcoin-util-test.py... /usr/local/bin/python3.7 ../test/util/bitcoin-util-test.py ../test/util/bitcoin-util-test.py:31: DeprecationWarning: This method will be removed in future versions. Use 'parser.read_file()' instead. config.readfp(open(os.path.join(os.path.dirname(__file__), "../config.ini"), encoding="utf8")) $ python3 --version Python 3.7.0 --- test/util/bitcoin-util-test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/util/bitcoin-util-test.py b/test/util/bitcoin-util-test.py index 16371a6234..92fef30e13 100755 --- a/test/util/bitcoin-util-test.py +++ b/test/util/bitcoin-util-test.py @@ -28,7 +28,7 @@ def main(): config = configparser.ConfigParser() config.optionxform = str - config.readfp(open(os.path.join(os.path.dirname(__file__), "../config.ini"), encoding="utf8")) + config.read_file(open(os.path.join(os.path.dirname(__file__), "../config.ini"), encoding="utf8")) env_conf = dict(config.items('environment')) parser = argparse.ArgumentParser(description=__doc__) From 58efc49b954f145ce39fc1047aca3534b7100a4f Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 13 Aug 2018 15:37:13 +0200 Subject: [PATCH 0047/1200] build: bump version to 0.17.99 Now that 0.17 branch has been split off, master is 0.17.99 (pre-0.18). Also clean out release notes. Tree-SHA512: bb20025d3ead3346afc7a6a51af715783e705e1de9d1b90ced6423d8969d64e42b72d06a1eb853083b11e9cfe674775266792ae2cd18ed6c858938e125edab03 --- configure.ac | 2 +- doc/release-notes.md | 203 +------------------------------------------ 2 files changed, 2 insertions(+), 203 deletions(-) diff --git a/configure.ac b/configure.ac index 5851413cf4..0bec81564b 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) -define(_CLIENT_VERSION_MINOR, 16) +define(_CLIENT_VERSION_MINOR, 17) define(_CLIENT_VERSION_REVISION, 99) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, false) diff --git a/doc/release-notes.md b/doc/release-notes.md index a24a13408b..d3ba067657 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -59,210 +59,9 @@ support versions of macOS older than 10.10. Notable changes =============== -Changed command-line options ----------------------------- - -- `-includeconf=` can be used to include additional configuration files. - Only works inside the `bitcoin.conf` file, not inside included files or from - command-line. Multiple files may be included. Can be disabled from command- - line via `-noincludeconf`. Note that multi-argument commands like - `-includeconf` will override preceding `-noincludeconf`, i.e. - - noincludeconf=1 - includeconf=relative.conf - - as bitcoin.conf will still include `relative.conf`. - -GUI changes ------------ - -- Block storage can be limited under Preferences, in the Main tab. Undoing this setting requires downloading the full blockchain again. This mode is incompatible with -txindex and -rescan. - -RPC changes +Example item ------------ -### Low-level changes - -- The `createrawtransaction` RPC will now accept an array or dictionary (kept for compatibility) for the `outputs` parameter. This means the order of transaction outputs can be specified by the client. -- The `fundrawtransaction` RPC will reject the previously deprecated `reserveChangeKey` option. -- `sendmany` now shuffles outputs to improve privacy, so any previously expected behavior with regards to output ordering can no longer be relied upon. -- The new RPC `testmempoolaccept` can be used to test acceptance of a transaction to the mempool without adding it. -- JSON transaction decomposition now includes a `weight` field which provides - the transaction's exact weight. This is included in REST /rest/tx/ and - /rest/block/ endpoints when in json mode. This is also included in `getblock` - (with verbosity=2), `listsinceblock`, `listtransactions`, and - `getrawtransaction` RPC commands. -- New `fees` field introduced in `getrawmempool`, `getmempoolancestors`, `getmempooldescendants` and - `getmempoolentry` when verbosity is set to `true` with sub-fields `ancestor`, `base`, `modified` - and `descendant` denominated in BTC. This new field deprecates previous fee fields, such as - `fee`, `modifiedfee`, `ancestorfee` and `descendantfee`. -- The new RPC `getzmqnotifications` returns information about active ZMQ - notifications. - -External wallet files ---------------------- - -The `-wallet=` option now accepts full paths instead of requiring wallets -to be located in the -walletdir directory. - -Newly created wallet format ---------------------------- - -If `-wallet=` is specified with a path that does not exist, it will now -create a wallet directory at the specified location (containing a wallet.dat -data file, a db.log file, and database/log.?????????? files) instead of just -creating a data file at the path and storing log files in the parent -directory. This should make backing up wallets more straightforward than -before because the specified wallet path can just be directly archived without -having to look in the parent directory for transaction log files. - -For backwards compatibility, wallet paths that are names of existing data files -in the `-walletdir` directory will continue to be accepted and interpreted the -same as before. - -Dynamic loading and creation of wallets ---------------------------------------- - -Previously, wallets could only be loaded or created at startup, by specifying `-wallet` parameters on the command line or in the bitcoin.conf file. It is now possible to load, create and unload wallets dynamically at runtime: - -- Existing wallets can be loaded by calling the `loadwallet` RPC. The wallet can be specified as file/directory basename (which must be located in the `walletdir` directory), or as an absolute path to a file/directory. -- New wallets can be created (and loaded) by calling the `createwallet` RPC. The provided name must not match a wallet file in the `walletdir` directory or the name of a wallet that is currently loaded. -- Loaded wallets can be unloaded by calling the `unloadwallet` RPC. - -This feature is currently only available through the RPC interface. - -Coin selection --------------- -- A new `-avoidpartialspends` flag has been added (default=false). If enabled, the wallet will try to spend UTXO's that point at the same destination - together. This is a privacy increase, as there will no longer be cases where a wallet will inadvertently spend only parts of the coins sent to - the same address (note that if someone were to send coins to that address after it was used, those coins will still be included in future - coin selections). - -Configuration sections for testnet and regtest ----------------------------------------------- - -It is now possible for a single configuration file to set different -options for different networks. This is done by using sections or by -prefixing the option with the network, such as: - - main.uacomment=bitcoin - test.uacomment=bitcoin-testnet - regtest.uacomment=regtest - [main] - mempoolsize=300 - [test] - mempoolsize=100 - [regtest] - mempoolsize=20 - -The `addnode=`, `connect=`, `port=`, `bind=`, `rpcport=`, `rpcbind=` -and `wallet=` options will only apply to mainnet when specified in the -configuration file, unless a network is specified. - -'label' and 'account' APIs for wallet -------------------------------------- - -A new 'label' API has been introduced for the wallet. This is intended as a -replacement for the deprecated 'account' API. The 'account' can continue to -be used in V0.17 by starting bitcoind with the '-deprecatedrpc=accounts' -argument, and will be fully removed in V0.18. - -The label RPC methods mirror the account functionality, with the following functional differences: - -- Labels can be set on any address, not just receiving addresses. This functionality was previously only available through the GUI. -- Labels can be deleted by reassigning all addresses using the `setlabel` RPC method. -- There isn't support for sending transactions _from_ a label, or for determining which label a transaction was sent from. -- Labels do not have a balance. - -Here are the changes to RPC methods: - -| Deprecated Method | New Method | Notes | -| :---------------------- | :-------------------- | :-----------| -| `getaccount` | `getaddressinfo` | `getaddressinfo` returns a json object with address information instead of just the name of the account as a string. | -| `getaccountaddress` | n/a | There is no replacement for `getaccountaddress` since labels do not have an associated receive address. | -| `getaddressesbyaccount` | `getaddressesbylabel` | `getaddressesbylabel` returns a json object with the addresses as keys, instead of a list of strings. | -| `getreceivedbyaccount` | `getreceivedbylabel` | _no change in behavior_ | -| `listaccounts` | `listlabels` | `listlabels` does not return a balance or accept `minconf` and `watchonly` arguments. | -| `listreceivedbyaccount` | `listreceivedbylabel` | Both methods return new `label` fields, along with `account` fields for backward compatibility. | -| `move` | n/a | _no replacement_ | -| `sendfrom` | n/a | _no replacement_ | -| `setaccount` | `setlabel` | Both methods now:
  • allow assigning labels to any address, instead of raising an error if the address is not receiving address.
  • delete the previous label associated with an address when the final address using that label is reassigned to a different label, instead of making an implicit `getaccountaddress` call to ensure the previous label still has a receiving address. | - -| Changed Method | Notes | -| :--------------------- | :------ | -| `addmultisigaddress` | Renamed `account` named parameter to `label`. Still accepts `account` for backward compatibility if running with '-deprecatedrpc=accounts'. | -| `getnewaddress` | Renamed `account` named parameter to `label`. Still accepts `account` for backward compatibility. if running with '-deprecatedrpc=accounts' | -| `listunspent` | Returns new `label` fields. `account` field will be returned for backward compatibility if running with '-deprecatedrpc=accounts' | -| `sendmany` | The `account` named parameter has been renamed to `dummy`. If provided, the `dummy` parameter must be set to the empty string, unless running with the `-deprecatedrpc=accounts` argument (in which case functionality is unchanged). | -| `listtransactions` | The `account` named parameter has been renamed to `dummy`. If provided, the `dummy` parameter must be set to the string `*`, unless running with the `-deprecatedrpc=accounts` argument (in which case functionality is unchanged). | -| `getbalance` | `account`, `minconf` and `include_watchonly` parameters are deprecated, and can only be used if running with '-deprecatedrpc=accounts' | - -Low-level RPC changes ---------------------- - -- When bitcoin is not started with any `-wallet=` options, the name of - the default wallet returned by `getwalletinfo` and `listwallets` RPCs is - now the empty string `""` instead of `"wallet.dat"`. If bitcoin is started - with any `-wallet=` options, there is no change in behavior, and the - name of any wallet is just its `` string. -- Passing an empty string (`""`) as the `address_type` parameter to - `getnewaddress`, `getrawchangeaddress`, `addmultisigaddress`, - `fundrawtransaction` RPCs is now an error. Previously, this would fall back - to using the default address type. It is still possible to pass null or leave - the parameter unset to use the default address type. - -- Bare multisig outputs to our keys are no longer automatically treated as - incoming payments. As this feature was only available for multisig outputs for - which you had all private keys in your wallet, there was generally no use for - them compared to single-key schemes. Furthermore, no address format for such - outputs is defined, and wallet software can't easily send to it. These outputs - will no longer show up in `listtransactions`, `listunspent`, or contribute to - your balance, unless they are explicitly watched (using `importaddress` or - `importmulti` with hex script argument). `signrawtransaction*` also still - works for them. - -- The `getwalletinfo` RPC method now returns an `hdseedid` value, which is always the same as the incorrectly-named `hdmasterkeyid` value. `hdmasterkeyid` will be removed in V0.18. -- The `getaddressinfo` RPC method now returns an `hdseedid` value, which is always the same as the incorrectly-named `hdmasterkeyid` value. `hdmasterkeyid` will be removed in V0.18. - -Other API changes ------------------ - -- The `inactivehdmaster` property in the `dumpwallet` output has been corrected to `inactivehdseed` - -### Logging - -- The log timestamp format is now ISO 8601 (e.g. "2018-02-28T12:34:56Z"). - -- When running bitcoind with `-debug` but without `-daemon`, logging to stdout - is now the default behavior. Setting `-printtoconsole=1` no longer implicitly - disables logging to debug.log. Instead, logging to file can be explicitly disabled - by setting `-debuglogfile=0`. - -Transaction index changes -------------------------- - -The transaction index is now built separately from the main node procedure, -meaning the `-txindex` flag can be toggled without a full reindex. If bitcoind -is run with `-txindex` on a node that is already partially or fully synced -without one, the transaction index will be built in the background and become -available once caught up. When switching from running `-txindex` to running -without the flag, the transaction index database will *not* be deleted -automatically, meaning it could be turned back on at a later time without a full -resync. - -Miner block size removed ------------------------- - -The `-blockmaxsize` option for miners to limit their blocks' sizes was -deprecated in V0.15.1, and has now been removed. Miners should use the -`-blockmaxweight` option if they want to limit the weight of their blocks' -weights. - -Python Support --------------- - -Support for Python 2 has been discontinued for all test files and tools. - Credits ======= From 263b3777e73525b172f0ad61ea84c95d417c67ae Mon Sep 17 00:00:00 2001 From: fanquake Date: Mon, 13 Aug 2018 21:44:22 +0800 Subject: [PATCH 0048/1200] gitian: bump descriptors for (0.)18 --- contrib/gitian-descriptors/gitian-linux.yml | 2 +- contrib/gitian-descriptors/gitian-osx.yml | 2 +- contrib/gitian-descriptors/gitian-win.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 4255fb0c9a..4e8904000b 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -1,5 +1,5 @@ --- -name: "bitcoin-linux-0.17" +name: "bitcoin-linux-0.18" enable_cache: true suites: - "bionic" diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index fb59cf671b..87d8007ccb 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -1,5 +1,5 @@ --- -name: "bitcoin-osx-0.17" +name: "bitcoin-osx-0.18" enable_cache: true suites: - "bionic" diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index 2d48170649..31b9c309c7 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -1,5 +1,5 @@ --- -name: "bitcoin-win-0.17" +name: "bitcoin-win-0.18" enable_cache: true suites: - "bionic" From c05712cb590c8c76729a71d75a290c67ae9e3c06 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 8 Aug 2018 14:27:20 -0700 Subject: [PATCH 0049/1200] Only wipe wrong UTXO type data if overwritten by wallet --- src/wallet/rpcwallet.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index a766874f12..4aed097364 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4504,10 +4504,11 @@ bool FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, const C // If we don't know about this input, skip it and let someone else deal with it const uint256& txhash = txin.prevout.hash; - const auto& it = pwallet->mapWallet.find(txhash); + const auto it = pwallet->mapWallet.find(txhash); if (it != pwallet->mapWallet.end()) { const CWalletTx& wtx = it->second; CTxOut utxo = wtx.tx->vout[txin.prevout.n]; + // Update both UTXOs from the wallet. input.non_witness_utxo = wtx.tx; input.witness_utxo = utxo; } @@ -4524,11 +4525,13 @@ bool FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, const C complete &= SignPSBTInput(PublicOnlySigningProvider(pwallet), *psbtx.tx, input, sigdata, i, sighash_type); } - // Drop the unnecessary UTXO - if (sigdata.witness) { - input.non_witness_utxo = nullptr; - } else { - input.witness_utxo.SetNull(); + if (it != pwallet->mapWallet.end()) { + // Drop the unnecessary UTXO if we added both from the wallet. + if (sigdata.witness) { + input.non_witness_utxo = nullptr; + } else { + input.witness_utxo.SetNull(); + } } // Get public key paths From 8254e9950f67d750c7f5905bfdef526d825965ed Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 8 Aug 2018 14:18:55 -0700 Subject: [PATCH 0050/1200] Additional sanity checks in SignPSBTInput --- src/script/sign.cpp | 16 ++++++++++++++++ src/script/sign.h | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/script/sign.cpp b/src/script/sign.cpp index e7bb90daa3..1982e8a832 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -244,17 +244,33 @@ bool SignPSBTInput(const SigningProvider& provider, const CMutableTransaction& t input.FillSignatureData(sigdata); // Get UTXO + bool require_witness_sig = false; CTxOut utxo; if (input.non_witness_utxo) { + // If we're taking our information from a non-witness UTXO, verify that it matches the prevout. + if (input.non_witness_utxo->GetHash() != tx.vin[index].prevout.hash) return false; + // If both witness and non-witness UTXO are provided, verify that they match. This check shouldn't + // matter, as the PSBT deserializer enforces only one of both is provided, and the only way both + // can be present is when they're added simultaneously by FillPSBT (in which case they always match). + // Still, check in order to not rely on callers to enforce this. + if (!input.witness_utxo.IsNull() && input.non_witness_utxo->vout[tx.vin[index].prevout.n] != input.witness_utxo) return false; utxo = input.non_witness_utxo->vout[tx.vin[index].prevout.n]; } else if (!input.witness_utxo.IsNull()) { utxo = input.witness_utxo; + // When we're taking our information from a witness UTXO, we can't verify it is actually data from + // the output being spent. This is safe in case a witness signature is produced (which includes this + // information directly in the hash), but not for non-witness signatures. Remember that we require + // a witness signature in this situation. + require_witness_sig = true; } else { return false; } MutableTransactionSignatureCreator creator(&tx, index, utxo.nValue, sighash); + sigdata.witness = false; bool sig_complete = ProduceSignature(provider, creator, utxo.scriptPubKey, sigdata); + // Verify that a witness signature was produced in case one was required. + if (require_witness_sig && !sigdata.witness) return false; input.FromSignatureData(sigdata); return sig_complete; } diff --git a/src/script/sign.h b/src/script/sign.h index 24cddda51b..d2033af731 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -678,7 +678,7 @@ bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreato bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType); bool SignSignature(const SigningProvider &provider, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType); -/** Signs a PSBTInput */ +/** Signs a PSBTInput, verifying that all provided data matches what is being signed. */ bool SignPSBTInput(const SigningProvider& provider, const CMutableTransaction& tx, PSBTInput& input, SignatureData& sigdata, int index, int sighash = 1); /** Extract signature data from a transaction input, and insert it. */ From 7c8bffdc24e005c3044a9a80bbc227b2a39b8605 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Wed, 8 Aug 2018 14:14:12 -0700 Subject: [PATCH 0051/1200] Test that a non-witness script as witness utxo is not signed --- test/functional/data/rpc_psbt.json | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/test/functional/data/rpc_psbt.json b/test/functional/data/rpc_psbt.json index d800fa97a5..777d53d330 100644 --- a/test/functional/data/rpc_psbt.json +++ b/test/functional/data/rpc_psbt.json @@ -57,15 +57,38 @@ ], "psbt" : "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAABBEdSIQKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfyEC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtdSriIGApWDvzmuCmCXR60Zmt3WNPphCFWdbFzTm0whg/GrluB/ENkMak8AAACAAAAAgAAAAIAiBgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU21xDZDGpPAAAAgAAAAIABAACAAQMEAQAAAAABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohwEEIgAgjCNTFzdDtZXftKB7crqOQuN5fadOh/59nXSX47ICiQMBBUdSIQMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3CECOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnNSriIGAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zENkMak8AAACAAAAAgAMAAIAiBgMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3BDZDGpPAAAAgAAAAIACAACAAQMEAQAAAAAiAgOppMN/WZbTqiXbrGtXCvBlA5RJKUJGCzVHU+2e7KWHcRDZDGpPAAAAgAAAAIAEAACAACICAn9jmXV9Lv9VoTatAsaEsYOLZVbl8bazQoKpS2tQBRCWENkMak8AAACAAAAAgAUAAIAA", "result" : "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgf0cwRAIgdAGK1BgAl7hzMjwAFXILNoTMgSOJEEjn282bVa1nnJkCIHPTabdA4+tT3O+jOCPIBwUUylWn3ZVE8VfBZ5EyYRGMAQEDBAEAAAABBEdSIQKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfyEC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtdSriIGApWDvzmuCmCXR60Zmt3WNPphCFWdbFzTm0whg/GrluB/ENkMak8AAACAAAAAgAAAAIAiBgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU21xDZDGpPAAAAgAAAAIABAACAAAEBIADC6wsAAAAAF6kUt/X69A49QKWkWbHbNTXyty+pIeiHIgIDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtxHMEQCIGLrelVhB6fHP0WsSrWh3d9vcHX7EnWWmn84Pv/3hLyyAiAMBdu3Rw2/LwhVfdNWxzJcHtMJE+mWzThAlF2xIijaXwEBAwQBAAAAAQQiACCMI1MXN0O1ld+0oHtyuo5C43l9p06H/n2ddJfjsgKJAwEFR1IhAwidwQx6xttU+RMpr2FzM9s4jOrQwjH3IzedG5kDCwLcIQI63ZBPPW3PWd25BrDe4jUpt/+57VDl6GFRkmhgIh8Oc1KuIgYCOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnMQ2QxqTwAAAIAAAACAAwAAgCIGAwidwQx6xttU+RMpr2FzM9s4jOrQwjH3IzedG5kDCwLcENkMak8AAACAAAAAgAIAAIAAIgIDqaTDf1mW06ol26xrVwrwZQOUSSlCRgs1R1Ptnuylh3EQ2QxqTwAAAIAAAACABAAAgAAiAgJ/Y5l1fS7/VaE2rQLGhLGDi2VW5fG2s0KCqUtrUAUQlhDZDGpPAAAAgAAAAIAFAACAAA==" + }, + { + "privkeys" : [ + "cT7J9YpCwY3AVRFSjN6ukeEeWY6mhpbJPxRaDaP5QTdygQRxP9Au", + "cNBc3SWUip9PPm1GjRoLEJT6T41iNzCYtD7qro84FMnM5zEqeJsE" + ], + "psbt" : "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAABBEdSIQKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfyEC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtdSriIGApWDvzmuCmCXR60Zmt3WNPphCFWdbFzTm0whg/GrluB/ENkMak8AAACAAAAAgAAAAIAiBgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU21xDZDGpPAAAAgAAAAIABAACAAQMEAQAAAAABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohwEEIgAgjCNTFzdDtZXftKB7crqOQuN5fadOh/59nXSX47ICiQMBBUdSIQMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3CECOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnNSriIGAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zENkMak8AAACAAAAAgAMAAIAiBgMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3BDZDGpPAAAAgAAAAIACAACAAQMEAQAAAAAiAgOppMN/WZbTqiXbrGtXCvBlA5RJKUJGCzVHU+2e7KWHcRDZDGpPAAAAgAAAAIAEAACAACICAn9jmXV9Lv9VoTatAsaEsYOLZVbl8bazQoKpS2tQBRCWENkMak8AAACAAAAAgAUAAIAA", + "result" : "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU210cwRAIgYxqYn+c4qSrQGYYCMxLBkhT+KAKznly8GsNniAbGksMCIDnbbDh70mdxbf2z1NjaULjoXSEzJrp8faqkwM5B65IjAQEDBAEAAAABBEdSIQKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfyEC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtdSriIGApWDvzmuCmCXR60Zmt3WNPphCFWdbFzTm0whg/GrluB/ENkMak8AAACAAAAAgAAAAIAiBgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU21xDZDGpPAAAAgAAAAIABAACAAAEBIADC6wsAAAAAF6kUt/X69A49QKWkWbHbNTXyty+pIeiHIgICOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnNHMEQCIGX0W6WZi1mif/4ae+0BavHx+Q1Us6qPdFCqX1aiUQO9AiB/ckcDrR7blmgLKEtW1P/LiPf7dZ6rvgiqMPKbhROD0gEBAwQBAAAAAQQiACCMI1MXN0O1ld+0oHtyuo5C43l9p06H/n2ddJfjsgKJAwEFR1IhAwidwQx6xttU+RMpr2FzM9s4jOrQwjH3IzedG5kDCwLcIQI63ZBPPW3PWd25BrDe4jUpt/+57VDl6GFRkmhgIh8Oc1KuIgYCOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnMQ2QxqTwAAAIAAAACAAwAAgCIGAwidwQx6xttU+RMpr2FzM9s4jOrQwjH3IzedG5kDCwLcENkMak8AAACAAAAAgAIAAIAAIgIDqaTDf1mW06ol26xrVwrwZQOUSSlCRgs1R1Ptnuylh3EQ2QxqTwAAAIAAAACABAAAgAAiAgJ/Y5l1fS7/VaE2rQLGhLGDi2VW5fG2s0KCqUtrUAUQlhDZDGpPAAAAgAAAAIAFAACAAA==" + }, + { + "privkeys" : [ + "cT7J9YpCwY3AVRFSjN6ukeEeWY6mhpbJPxRaDaP5QTdygQRxP9Au", + "cNBc3SWUip9PPm1GjRoLEJT6T41iNzCYtD7qro84FMnM5zEqeJsE" + ], + "psbt" : "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAABBEdSIQKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfyEC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtdSriIGApWDvzmuCmCXR60Zmt3WNPphCFWdbFzTm0whg/GrluB/ENkMak8AAACAAAAAgAAAAIAiBgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU21xDZDGpPAAAAgAAAAIABAACAAQMEAQAAAAABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohwEEIgAgjCNTFzdDtZXftKB7crqOQuN5fadOh/59nXSX47ICiQMBBUdSIQMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3CECOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnNSriIGAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zENkMak8AAACAAAAAgAMAAIAiBgMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3BDZDGpPAAAAgAAAAIACAACAAQMEAQAAAAAiAgOppMN/WZbTqiXbrGtXCvBlA5RJKUJGCzVHU+2e7KWHcRDZDGpPAAAAgAAAAIAEAACAACICAn9jmXV9Lv9VoTatAsaEsYOLZVbl8bazQoKpS2tQBRCWENkMak8AAACAAAAAgAUAAIAA", + "result" : "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU210cwRAIgYxqYn+c4qSrQGYYCMxLBkhT+KAKznly8GsNniAbGksMCIDnbbDh70mdxbf2z1NjaULjoXSEzJrp8faqkwM5B65IjAQEDBAEAAAABBEdSIQKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfyEC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtdSriIGApWDvzmuCmCXR60Zmt3WNPphCFWdbFzTm0whg/GrluB/ENkMak8AAACAAAAAgAAAAIAiBgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU21xDZDGpPAAAAgAAAAIABAACAAAEBIADC6wsAAAAAF6kUt/X69A49QKWkWbHbNTXyty+pIeiHIgICOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnNHMEQCIGX0W6WZi1mif/4ae+0BavHx+Q1Us6qPdFCqX1aiUQO9AiB/ckcDrR7blmgLKEtW1P/LiPf7dZ6rvgiqMPKbhROD0gEBAwQBAAAAAQQiACCMI1MXN0O1ld+0oHtyuo5C43l9p06H/n2ddJfjsgKJAwEFR1IhAwidwQx6xttU+RMpr2FzM9s4jOrQwjH3IzedG5kDCwLcIQI63ZBPPW3PWd25BrDe4jUpt/+57VDl6GFRkmhgIh8Oc1KuIgYCOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnMQ2QxqTwAAAIAAAACAAwAAgCIGAwidwQx6xttU+RMpr2FzM9s4jOrQwjH3IzedG5kDCwLcENkMak8AAACAAAAAgAIAAIAAIgIDqaTDf1mW06ol26xrVwrwZQOUSSlCRgs1R1Ptnuylh3EQ2QxqTwAAAIAAAACABAAAgAAiAgJ/Y5l1fS7/VaE2rQLGhLGDi2VW5fG2s0KCqUtrUAUQlhDZDGpPAAAAgAAAAIAFAACAAA==" + }, + { + "privkeys" : [ + "cNBc3SWUip9PPm1GjRoLEJT6T41iNzCYtD7qro84FMnM5zEqeJsE" + ], + "psbt" : "cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEBItPf9QUAAAAAGXapFNSO0xELlAFMsRS9Mtb00GbcdCVriKwAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIACICAurVlmh8qAYEPtw94RbN8p1eklfBls0FXPaYyNAr8k6ZELSmumcAAACAAAAAgAIAAIAAIgIDlPYr6d8ZlSxVh3aK63aYBhrSxKJciU9H2MFitNchPQUQtKa6ZwAAAIABAACAAgAAgAA=", + "result" : "cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEBItPf9QUAAAAAGXapFNSO0xELlAFMsRS9Mtb00GbcdCVriKwAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIACICAurVlmh8qAYEPtw94RbN8p1eklfBls0FXPaYyNAr8k6ZELSmumcAAACAAAAAgAIAAIAAIgIDlPYr6d8ZlSxVh3aK63aYBhrSxKJciU9H2MFitNchPQUQtKa6ZwAAAIABAACAAgAAgAA=" } ], "combiner" : [ { "combine" : [ "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgf0cwRAIgdAGK1BgAl7hzMjwAFXILNoTMgSOJEEjn282bVa1nnJkCIHPTabdA4+tT3O+jOCPIBwUUylWn3ZVE8VfBZ5EyYRGMAQEDBAEAAAABBEdSIQKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfyEC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtdSriIGApWDvzmuCmCXR60Zmt3WNPphCFWdbFzTm0whg/GrluB/ENkMak8AAACAAAAAgAAAAIAiBgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU21xDZDGpPAAAAgAAAAIABAACAAAEBIADC6wsAAAAAF6kUt/X69A49QKWkWbHbNTXyty+pIeiHIgIDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtxHMEQCIGLrelVhB6fHP0WsSrWh3d9vcHX7EnWWmn84Pv/3hLyyAiAMBdu3Rw2/LwhVfdNWxzJcHtMJE+mWzThAlF2xIijaXwEBAwQBAAAAAQQiACCMI1MXN0O1ld+0oHtyuo5C43l9p06H/n2ddJfjsgKJAwEFR1IhAwidwQx6xttU+RMpr2FzM9s4jOrQwjH3IzedG5kDCwLcIQI63ZBPPW3PWd25BrDe4jUpt/+57VDl6GFRkmhgIh8Oc1KuIgYCOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnMQ2QxqTwAAAIAAAACAAwAAgCIGAwidwQx6xttU+RMpr2FzM9s4jOrQwjH3IzedG5kDCwLcENkMak8AAACAAAAAgAIAAIAAIgIDqaTDf1mW06ol26xrVwrwZQOUSSlCRgs1R1Ptnuylh3EQ2QxqTwAAAIAAAACABAAAgAAiAgJ/Y5l1fS7/VaE2rQLGhLGDi2VW5fG2s0KCqUtrUAUQlhDZDGpPAAAAgAAAAIAFAACAAA==", - "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU210gwRQIhAPYQOLMI3B2oZaNIUnRvAVdyk0IIxtJEVDk82ZvfIhd3AiAFbmdaZ1ptCgK4WxTl4pB02KJam1dgvqKBb2YZEKAG6gEBAwQBAAAAAQRHUiEClYO/Oa4KYJdHrRma3dY0+mEIVZ1sXNObTCGD8auW4H8hAtq2H/SaFNtqfQKwzR+7ePxLGDErW05U2uTbovv+9TbXUq4iBgKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfxDZDGpPAAAAgAAAAIAAAACAIgYC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtcQ2QxqTwAAAIAAAACAAQAAgAABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohyICAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zRzBEAiBl9FulmYtZon/+GnvtAWrx8fkNVLOqj3RQql9WolEDvQIgf3JHA60e25ZoCyhLVtT/y4j3+3Weq74IqjDym4UTg9IBAQMEAQAAAAEEIgAgjCNTFzdDtZXftKB7crqOQuN5fadOh/59nXSX47ICiQMBBUdSIQMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3CECOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnNSriIGAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zENkMak8AAACAAAAAgAMAAIAiBgMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3BDZDGpPAAAAgAAAAIACAACAACICA6mkw39ZltOqJdusa1cK8GUDlEkpQkYLNUdT7Z7spYdxENkMak8AAACAAAAAgAQAAIAAIgICf2OZdX0u/1WhNq0CxoSxg4tlVuXxtrNCgqlLa1AFEJYQ2QxqTwAAAIAAAACABQAAgAA=" + "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU210cwRAIgYxqYn+c4qSrQGYYCMxLBkhT+KAKznly8GsNniAbGksMCIDnbbDh70mdxbf2z1NjaULjoXSEzJrp8faqkwM5B65IjAQEDBAEAAAABBEdSIQKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfyEC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtdSriIGApWDvzmuCmCXR60Zmt3WNPphCFWdbFzTm0whg/GrluB/ENkMak8AAACAAAAAgAAAAIAiBgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU21xDZDGpPAAAAgAAAAIABAACAAAEBIADC6wsAAAAAF6kUt/X69A49QKWkWbHbNTXyty+pIeiHIgICOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnNHMEQCIGX0W6WZi1mif/4ae+0BavHx+Q1Us6qPdFCqX1aiUQO9AiB/ckcDrR7blmgLKEtW1P/LiPf7dZ6rvgiqMPKbhROD0gEBAwQBAAAAAQQiACCMI1MXN0O1ld+0oHtyuo5C43l9p06H/n2ddJfjsgKJAwEFR1IhAwidwQx6xttU+RMpr2FzM9s4jOrQwjH3IzedG5kDCwLcIQI63ZBPPW3PWd25BrDe4jUpt/+57VDl6GFRkmhgIh8Oc1KuIgYCOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnMQ2QxqTwAAAIAAAACAAwAAgCIGAwidwQx6xttU+RMpr2FzM9s4jOrQwjH3IzedG5kDCwLcENkMak8AAACAAAAAgAIAAIAAIgIDqaTDf1mW06ol26xrVwrwZQOUSSlCRgs1R1Ptnuylh3EQ2QxqTwAAAIAAAACABAAAgAAiAgJ/Y5l1fS7/VaE2rQLGhLGDi2VW5fG2s0KCqUtrUAUQlhDZDGpPAAAAgAAAAIAFAACAAA==" ], - "result" : "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgf0cwRAIgdAGK1BgAl7hzMjwAFXILNoTMgSOJEEjn282bVa1nnJkCIHPTabdA4+tT3O+jOCPIBwUUylWn3ZVE8VfBZ5EyYRGMASICAtq2H/SaFNtqfQKwzR+7ePxLGDErW05U2uTbovv+9TbXSDBFAiEA9hA4swjcHahlo0hSdG8BV3KTQgjG0kRUOTzZm98iF3cCIAVuZ1pnWm0KArhbFOXikHTYolqbV2C+ooFvZhkQoAbqAQEDBAEAAAABBEdSIQKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfyEC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtdSriIGApWDvzmuCmCXR60Zmt3WNPphCFWdbFzTm0whg/GrluB/ENkMak8AAACAAAAAgAAAAIAiBgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU21xDZDGpPAAAAgAAAAIABAACAAAEBIADC6wsAAAAAF6kUt/X69A49QKWkWbHbNTXyty+pIeiHIgIDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtxHMEQCIGLrelVhB6fHP0WsSrWh3d9vcHX7EnWWmn84Pv/3hLyyAiAMBdu3Rw2/LwhVfdNWxzJcHtMJE+mWzThAlF2xIijaXwEiAgI63ZBPPW3PWd25BrDe4jUpt/+57VDl6GFRkmhgIh8Oc0cwRAIgZfRbpZmLWaJ//hp77QFq8fH5DVSzqo90UKpfVqJRA70CIH9yRwOtHtuWaAsoS1bU/8uI9/t1nqu+CKow8puFE4PSAQEDBAEAAAABBCIAIIwjUxc3Q7WV37Sge3K6jkLjeX2nTof+fZ10l+OyAokDAQVHUiEDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtwhAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zUq4iBgI63ZBPPW3PWd25BrDe4jUpt/+57VDl6GFRkmhgIh8OcxDZDGpPAAAAgAAAAIADAACAIgYDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtwQ2QxqTwAAAIAAAACAAgAAgAAiAgOppMN/WZbTqiXbrGtXCvBlA5RJKUJGCzVHU+2e7KWHcRDZDGpPAAAAgAAAAIAEAACAACICAn9jmXV9Lv9VoTatAsaEsYOLZVbl8bazQoKpS2tQBRCWENkMak8AAACAAAAAgAUAAIAA" + "result" : "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgf0cwRAIgdAGK1BgAl7hzMjwAFXILNoTMgSOJEEjn282bVa1nnJkCIHPTabdA4+tT3O+jOCPIBwUUylWn3ZVE8VfBZ5EyYRGMASICAtq2H/SaFNtqfQKwzR+7ePxLGDErW05U2uTbovv+9TbXRzBEAiBjGpif5zipKtAZhgIzEsGSFP4oArOeXLwaw2eIBsaSwwIgOdtsOHvSZ3Ft/bPU2NpQuOhdITMmunx9qqTAzkHrkiMBAQMEAQAAAAEER1IhApWDvzmuCmCXR60Zmt3WNPphCFWdbFzTm0whg/GrluB/IQLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU211KuIgYClYO/Oa4KYJdHrRma3dY0+mEIVZ1sXNObTCGD8auW4H8Q2QxqTwAAAIAAAACAAAAAgCIGAtq2H/SaFNtqfQKwzR+7ePxLGDErW05U2uTbovv+9TbXENkMak8AAACAAAAAgAEAAIAAAQEgAMLrCwAAAAAXqRS39fr0Dj1ApaRZsds1NfK3L6kh6IciAgMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3EcwRAIgYut6VWEHp8c/RaxKtaHd329wdfsSdZaafzg+//eEvLICIAwF27dHDb8vCFV901bHMlwe0wkT6ZbNOECUXbEiKNpfASICAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zRzBEAiBl9FulmYtZon/+GnvtAWrx8fkNVLOqj3RQql9WolEDvQIgf3JHA60e25ZoCyhLVtT/y4j3+3Weq74IqjDym4UTg9IBAQMEAQAAAAEEIgAgjCNTFzdDtZXftKB7crqOQuN5fadOh/59nXSX47ICiQMBBUdSIQMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3CECOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnNSriIGAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zENkMak8AAACAAAAAgAMAAIAiBgMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3BDZDGpPAAAAgAAAAIACAACAACICA6mkw39ZltOqJdusa1cK8GUDlEkpQkYLNUdT7Z7spYdxENkMak8AAACAAAAAgAQAAIAAIgICf2OZdX0u/1WhNq0CxoSxg4tlVuXxtrNCgqlLa1AFEJYQ2QxqTwAAAIAAAACABQAAgAA=" }, { "combine" : [ From 5df6f089b53c5b5859e5a3454c026447e4752f82 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Wed, 8 Aug 2018 16:14:01 -0700 Subject: [PATCH 0052/1200] More tests of signer checks --- test/functional/data/rpc_psbt.json | 24 ++++++++++++++++++++++++ test/functional/rpc_psbt.py | 6 ++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/test/functional/data/rpc_psbt.json b/test/functional/data/rpc_psbt.json index 777d53d330..70388841d1 100644 --- a/test/functional/data/rpc_psbt.json +++ b/test/functional/data/rpc_psbt.json @@ -80,6 +80,30 @@ ], "psbt" : "cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEBItPf9QUAAAAAGXapFNSO0xELlAFMsRS9Mtb00GbcdCVriKwAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIACICAurVlmh8qAYEPtw94RbN8p1eklfBls0FXPaYyNAr8k6ZELSmumcAAACAAAAAgAIAAIAAIgIDlPYr6d8ZlSxVh3aK63aYBhrSxKJciU9H2MFitNchPQUQtKa6ZwAAAIABAACAAgAAgAA=", "result" : "cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEBItPf9QUAAAAAGXapFNSO0xELlAFMsRS9Mtb00GbcdCVriKwAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIACICAurVlmh8qAYEPtw94RbN8p1eklfBls0FXPaYyNAr8k6ZELSmumcAAACAAAAAgAIAAIAAIgIDlPYr6d8ZlSxVh3aK63aYBhrSxKJciU9H2MFitNchPQUQtKa6ZwAAAIABAACAAgAAgAA=" + }, + { + "privkeys" : [ + "cT7J9YpCwY3AVRFSjN6ukeEeWY6mhpbJPxRaDaP5QTdygQRxP9Au", + "cNBc3SWUip9PPm1GjRoLEJT6T41iNzCYtD7qro84FMnM5zEqeJsE" + ], + "psbt" : "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU210gwRQIhAPYQOLMI3B2oZaNIUnRvAVdyk0IIxtJEVDk82ZvfIhd3AiAFbmdaZ1ptCgK4WxTl4pB02KJam1dgvqKBb2YZEKAG6gEBAwQBAAAAAQRHUiEClYO/Oa4KYJdHrRma3dY0+mEIVZ1sXNObTCGD8auW4H8hAtq2H/SaFNtqfQKwzR+7ePxLGDErW05U2uTbovv+9TbXUq8iBgKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfxDZDGpPAAAAgAAAAIAAAACAIgYC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtcQ2QxqTwAAAIAAAACAAQAAgAABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohyICAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zRzBEAiBl9FulmYtZon/+GnvtAWrx8fkNVLOqj3RQql9WolEDvQIgf3JHA60e25ZoCyhLVtT/y4j3+3Weq74IqjDym4UTg9IBAQMEAQAAAAEEIgAgjCNTFzdDtZXftKB7crqOQuN5fadOh/59nXSX47ICiQMBBUdSIQMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3CECOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnNSriIGAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zENkMak8AAACAAAAAgAMAAIAiBgMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3BDZDGpPAAAAgAAAAIACAACAACICA6mkw39ZltOqJdusa1cK8GUDlEkpQkYLNUdT7Z7spYdxENkMak8AAACAAAAAgAQAAIAAIgICf2OZdX0u/1WhNq0CxoSxg4tlVuXxtrNCgqlLa1AFEJYQ2QxqTwAAAIAAAACABQAAgAA=", + "result" : "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU210gwRQIhAPYQOLMI3B2oZaNIUnRvAVdyk0IIxtJEVDk82ZvfIhd3AiAFbmdaZ1ptCgK4WxTl4pB02KJam1dgvqKBb2YZEKAG6gEBAwQBAAAAAQRHUiEClYO/Oa4KYJdHrRma3dY0+mEIVZ1sXNObTCGD8auW4H8hAtq2H/SaFNtqfQKwzR+7ePxLGDErW05U2uTbovv+9TbXUq8iBgKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfxDZDGpPAAAAgAAAAIAAAACAIgYC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtcQ2QxqTwAAAIAAAACAAQAAgAABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohyICAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zRzBEAiBl9FulmYtZon/+GnvtAWrx8fkNVLOqj3RQql9WolEDvQIgf3JHA60e25ZoCyhLVtT/y4j3+3Weq74IqjDym4UTg9IBAQMEAQAAAAEEIgAgjCNTFzdDtZXftKB7crqOQuN5fadOh/59nXSX47ICiQMBBUdSIQMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3CECOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnNSriIGAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zENkMak8AAACAAAAAgAMAAIAiBgMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3BDZDGpPAAAAgAAAAIACAACAACICA6mkw39ZltOqJdusa1cK8GUDlEkpQkYLNUdT7Z7spYdxENkMak8AAACAAAAAgAQAAIAAIgICf2OZdX0u/1WhNq0CxoSxg4tlVuXxtrNCgqlLa1AFEJYQ2QxqTwAAAIAAAACABQAAgAA=" + }, + { + "privkeys" : [ + "cT7J9YpCwY3AVRFSjN6ukeEeWY6mhpbJPxRaDaP5QTdygQRxP9Au", + "cNBc3SWUip9PPm1GjRoLEJT6T41iNzCYtD7qro84FMnM5zEqeJsE" + ], + "psbt" : "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU210gwRQIhAPYQOLMI3B2oZaNIUnRvAVdyk0IIxtJEVDk82ZvfIhd3AiAFbmdaZ1ptCgK4WxTl4pB02KJam1dgvqKBb2YZEKAG6gEBAwQBAAAAAQRHUiEClYO/Oa4KYJdHrRma3dY0+mEIVZ1sXNObTCGD8auW4H8hAtq2H/SaFNtqfQKwzR+7ePxLGDErW05U2uTbovv+9TbXUq4iBgKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfxDZDGpPAAAAgAAAAIAAAACAIgYC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtcQ2QxqTwAAAIAAAACAAQAAgAABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohyICAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zRzBEAiBl9FulmYtZon/+GnvtAWrx8fkNVLOqj3RQql9WolEDvQIgf3JHA60e25ZoCyhLVtT/y4j3+3Weq74IqjDym4UTg9IBAQMEAQAAAAEEIgAgjCNTFzdDtZXftKB7crqOQuN5fadOh/59nXSX47ICiQABBUdSIQMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3CECOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnNSriIGAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zENkMak8AAACAAAAAgAMAAIAiBgMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3BDZDGpPAAAAgAAAAIACAACAACICA6mkw39ZltOqJdusa1cK8GUDlEkpQkYLNUdT7Z7spYdxENkMak8AAACAAAAAgAQAAIAAIgICf2OZdX0u/1WhNq0CxoSxg4tlVuXxtrNCgqlLa1AFEJYQ2QxqTwAAAIAAAACABQAAgAA=", + "result" : "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU210gwRQIhAPYQOLMI3B2oZaNIUnRvAVdyk0IIxtJEVDk82ZvfIhd3AiAFbmdaZ1ptCgK4WxTl4pB02KJam1dgvqKBb2YZEKAG6gEBAwQBAAAAAQRHUiEClYO/Oa4KYJdHrRma3dY0+mEIVZ1sXNObTCGD8auW4H8hAtq2H/SaFNtqfQKwzR+7ePxLGDErW05U2uTbovv+9TbXUq4iBgKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfxDZDGpPAAAAgAAAAIAAAACAIgYC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtcQ2QxqTwAAAIAAAACAAQAAgAABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohyICAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zRzBEAiBl9FulmYtZon/+GnvtAWrx8fkNVLOqj3RQql9WolEDvQIgf3JHA60e25ZoCyhLVtT/y4j3+3Weq74IqjDym4UTg9IBAQMEAQAAAAEEIgAgjCNTFzdDtZXftKB7crqOQuN5fadOh/59nXSX47ICiQABBUdSIQMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3CECOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnNSriIGAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zENkMak8AAACAAAAAgAMAAIAiBgMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3BDZDGpPAAAAgAAAAIACAACAACICA6mkw39ZltOqJdusa1cK8GUDlEkpQkYLNUdT7Z7spYdxENkMak8AAACAAAAAgAQAAIAAIgICf2OZdX0u/1WhNq0CxoSxg4tlVuXxtrNCgqlLa1AFEJYQ2QxqTwAAAIAAAACABQAAgAA=" + }, + { + "privkeys" : [ + "cT7J9YpCwY3AVRFSjN6ukeEeWY6mhpbJPxRaDaP5QTdygQRxP9Au", + "cNBc3SWUip9PPm1GjRoLEJT6T41iNzCYtD7qro84FMnM5zEqeJsE" + ], + "psbt" : "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU210gwRQIhAPYQOLMI3B2oZaNIUnRvAVdyk0IIxtJEVDk82ZvfIhd3AiAFbmdaZ1ptCgK4WxTl4pB02KJam1dgvqKBb2YZEKAG6gEBAwQBAAAAAQRHUiEClYO/Oa4KYJdHrRma3dY0+mEIVZ1sXNObTCGD8auW4H8hAtq2H/SaFNtqfQKwzR+7ePxLGDErW05U2uTbovv+9TbXUq4iBgKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfxDZDGpPAAAAgAAAAIAAAACAIgYC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtcQ2QxqTwAAAIAAAACAAQAAgAABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohyICAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zRzBEAiBl9FulmYtZon/+GnvtAWrx8fkNVLOqj3RQql9WolEDvQIgf3JHA60e25ZoCyhLVtT/y4j3+3Weq74IqjDym4UTg9IBAQMEAQAAAAEEIgAgjCNTFzdDtZXftKB7crqOQuN5fadOh/59nXSX47ICiQMBBUdSIQMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3CECOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnNSrSIGAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zENkMak8AAACAAAAAgAMAAIAiBgMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3BDZDGpPAAAAgAAAAIACAACAACICA6mkw39ZltOqJdusa1cK8GUDlEkpQkYLNUdT7Z7spYdxENkMak8AAACAAAAAgAQAAIAAIgICf2OZdX0u/1WhNq0CxoSxg4tlVuXxtrNCgqlLa1AFEJYQ2QxqTwAAAIAAAACABQAAgAA=", + "result" : "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU210gwRQIhAPYQOLMI3B2oZaNIUnRvAVdyk0IIxtJEVDk82ZvfIhd3AiAFbmdaZ1ptCgK4WxTl4pB02KJam1dgvqKBb2YZEKAG6gEBAwQBAAAAAQRHUiEClYO/Oa4KYJdHrRma3dY0+mEIVZ1sXNObTCGD8auW4H8hAtq2H/SaFNtqfQKwzR+7ePxLGDErW05U2uTbovv+9TbXUq4iBgKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfxDZDGpPAAAAgAAAAIAAAACAIgYC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtcQ2QxqTwAAAIAAAACAAQAAgAABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohyICAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zRzBEAiBl9FulmYtZon/+GnvtAWrx8fkNVLOqj3RQql9WolEDvQIgf3JHA60e25ZoCyhLVtT/y4j3+3Weq74IqjDym4UTg9IBAQMEAQAAAAEEIgAgjCNTFzdDtZXftKB7crqOQuN5fadOh/59nXSX47ICiQMBBUdSIQMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3CECOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnNSrSIGAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zENkMak8AAACAAAAAgAMAAIAiBgMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3BDZDGpPAAAAgAAAAIACAACAACICA6mkw39ZltOqJdusa1cK8GUDlEkpQkYLNUdT7Z7spYdxENkMak8AAACAAAAAgAQAAIAAIgICf2OZdX0u/1WhNq0CxoSxg4tlVuXxtrNCgqlLa1AFEJYQ2QxqTwAAAIAAAACABQAAgAA=" } ], "combiner" : [ diff --git a/test/functional/rpc_psbt.py b/test/functional/rpc_psbt.py index 26eca031c0..99c4131d61 100755 --- a/test/functional/rpc_psbt.py +++ b/test/functional/rpc_psbt.py @@ -168,9 +168,11 @@ def run_test(self): # Signer tests for i, signer in enumerate(signers): + self.nodes[2].createwallet("wallet{}".format(i)) + wrpc = self.nodes[2].get_wallet_rpc("wallet{}".format(i)) for key in signer['privkeys']: - self.nodes[i].importprivkey(key) - signed_tx = self.nodes[i].walletprocesspsbt(signer['psbt'])['psbt'] + wrpc.importprivkey(key) + signed_tx = wrpc.walletprocesspsbt(signer['psbt'])['psbt'] assert_equal(signed_tx, signer['result']) # Combiner test From 611ab307fbd8b6f8f7ffc1d569bb86d1f9cb4e92 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 19 Jul 2018 23:15:53 -0700 Subject: [PATCH 0053/1200] Introduce KeyOriginInfo for fingerprint + path --- src/rpc/rawtransaction.cpp | 15 ++++----------- src/script/sign.h | 32 ++++++++++++++++++++++---------- src/wallet/rpcwallet.cpp | 15 ++++++++------- 3 files changed, 34 insertions(+), 28 deletions(-) diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 608a1b5da2..8d96add13b 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -1460,11 +1460,8 @@ UniValue decodepsbt(const JSONRPCRequest& request) UniValue keypath(UniValue::VOBJ); keypath.pushKV("pubkey", HexStr(entry.first)); - uint32_t fingerprint = entry.second.at(0); - keypath.pushKV("master_fingerprint", strprintf("%08x", bswap_32(fingerprint))); - - entry.second.erase(entry.second.begin()); - keypath.pushKV("path", WriteHDKeypath(entry.second)); + keypath.pushKV("master_fingerprint", strprintf("%08x", ReadBE32(entry.second.fingerprint))); + keypath.pushKV("path", WriteHDKeypath(entry.second.path)); keypaths.push_back(keypath); } in.pushKV("bip32_derivs", keypaths); @@ -1522,12 +1519,8 @@ UniValue decodepsbt(const JSONRPCRequest& request) for (auto entry : output.hd_keypaths) { UniValue keypath(UniValue::VOBJ); keypath.pushKV("pubkey", HexStr(entry.first)); - - uint32_t fingerprint = entry.second.at(0); - keypath.pushKV("master_fingerprint", strprintf("%08x", bswap_32(fingerprint))); - - entry.second.erase(entry.second.begin()); - keypath.pushKV("path", WriteHDKeypath(entry.second)); + keypath.pushKV("master_fingerprint", strprintf("%08x", ReadBE32(entry.second.fingerprint))); + keypath.pushKV("path", WriteHDKeypath(entry.second.path)); keypaths.push_back(keypath); } out.pushKV("bip32_derivs", keypaths); diff --git a/src/script/sign.h b/src/script/sign.h index d2033af731..e0668f8c58 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -20,6 +20,12 @@ class CTransaction; struct CMutableTransaction; +struct KeyOriginInfo +{ + unsigned char fingerprint[4]; + std::vector path; +}; + /** An interface to be implemented by keystores that support signing. */ class SigningProvider { @@ -155,7 +161,7 @@ void UnserializeFromVector(Stream& s, X&... args) // Deserialize HD keypaths into a map template -void DeserializeHDKeypaths(Stream& s, const std::vector& key, std::map>& hd_keypaths) +void DeserializeHDKeypaths(Stream& s, const std::vector& key, std::map& hd_keypaths) { // Make sure that the key is the size of pubkey + 1 if (key.size() != CPubKey::PUBLIC_KEY_SIZE + 1 && key.size() != CPubKey::COMPRESSED_PUBLIC_KEY_SIZE + 1) { @@ -172,25 +178,31 @@ void DeserializeHDKeypaths(Stream& s, const std::vector& key, std // Read in key path uint64_t value_len = ReadCompactSize(s); - std::vector keypath; - for (unsigned int i = 0; i < value_len; i += sizeof(uint32_t)) { + if (value_len % 4 || value_len == 0) { + throw std::ios_base::failure("Invalid length for HD key path"); + } + + KeyOriginInfo keypath; + s >> keypath.fingerprint; + for (unsigned int i = 4; i < value_len; i += sizeof(uint32_t)) { uint32_t index; s >> index; - keypath.push_back(index); + keypath.path.push_back(index); } // Add to map - hd_keypaths.emplace(pubkey, keypath); + hd_keypaths.emplace(pubkey, std::move(keypath)); } // Serialize HD keypaths to a stream from a map template -void SerializeHDKeypaths(Stream& s, const std::map>& hd_keypaths, uint8_t type) +void SerializeHDKeypaths(Stream& s, const std::map& hd_keypaths, uint8_t type) { for (auto keypath_pair : hd_keypaths) { SerializeToVector(s, type, MakeSpan(keypath_pair.first)); - WriteCompactSize(s, keypath_pair.second.size() * sizeof(uint32_t)); - for (auto& path : keypath_pair.second) { + WriteCompactSize(s, (keypath_pair.second.path.size() + 1) * sizeof(uint32_t)); + s << keypath_pair.second.fingerprint; + for (const auto& path : keypath_pair.second.path) { s << path; } } @@ -205,7 +217,7 @@ struct PSBTInput CScript witness_script; CScript final_script_sig; CScriptWitness final_script_witness; - std::map> hd_keypaths; + std::map hd_keypaths; std::map partial_sigs; std::map, std::vector> unknown; int sighash_type = 0; @@ -413,7 +425,7 @@ struct PSBTOutput { CScript redeem_script; CScript witness_script; - std::map> hd_keypaths; + std::map hd_keypaths; std::map, std::vector> unknown; bool IsNull() const; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 4aed097364..fd3b82d9ab 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4464,7 +4464,7 @@ bool ParseHDKeypath(std::string keypath_str, std::vector& keypath) return true; } -void AddKeypathToMap(const CWallet* pwallet, const CKeyID& keyID, std::map>& hd_keypaths) +void AddKeypathToMap(const CWallet* pwallet, const CKeyID& keyID, std::map& hd_keypaths) { CPubKey vchPubKey; if (!pwallet->GetPubKey(keyID, vchPubKey)) { @@ -4475,9 +4475,9 @@ void AddKeypathToMap(const CWallet* pwallet, const CKeyID& keyID, std::mapmapKeyMetadata.end()) { meta = it->second; } - std::vector keypath; + KeyOriginInfo info; if (!meta.hdKeypath.empty()) { - if (!ParseHDKeypath(meta.hdKeypath, keypath)) { + if (!ParseHDKeypath(meta.hdKeypath, info.path)) { throw JSONRPCError(RPC_INTERNAL_ERROR, "Internal keypath is broken"); } // Get the proper master key id @@ -4485,12 +4485,13 @@ void AddKeypathToMap(const CWallet* pwallet, const CKeyID& keyID, std::mapGetKey(meta.hd_seed_id, key); CExtKey masterKey; masterKey.SetSeed(key.begin(), key.size()); - // Add to map - keypath.insert(keypath.begin(), ReadLE32(masterKey.key.GetPubKey().GetID().begin())); + // Compute identifier + CKeyID masterid = masterKey.key.GetPubKey().GetID(); + std::copy(masterid.begin(), masterid.begin() + 4, info.fingerprint); } else { // Single pubkeys get the master fingerprint of themselves - keypath.insert(keypath.begin(), ReadLE32(vchPubKey.GetID().begin())); + std::copy(keyID.begin(), keyID.begin() + 4, info.fingerprint); } - hd_keypaths.emplace(vchPubKey, keypath); + hd_keypaths.emplace(vchPubKey, std::move(info)); } bool FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, const CTransaction* txConst, int sighash_type, bool sign, bool bip32derivs) From 84f1f1bfdf900cd28099e428441aa42f9d11a0ed Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 19 Jul 2018 17:25:21 -0700 Subject: [PATCH 0054/1200] Make SigningProvider expose key origin information --- src/script/sign.cpp | 9 +++++++-- src/script/sign.h | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 1982e8a832..47931e21d9 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -645,9 +645,14 @@ bool PublicOnlySigningProvider::GetCScript(const CScriptID &scriptid, CScript& s return m_provider->GetCScript(scriptid, script); } -bool PublicOnlySigningProvider::GetPubKey(const CKeyID &address, CPubKey& pubkey) const +bool PublicOnlySigningProvider::GetPubKey(const CKeyID& keyid, CPubKey& pubkey) const { - return m_provider->GetPubKey(address, pubkey); + return m_provider->GetPubKey(keyid, pubkey); +} + +bool PublicOnlySigningProvider::GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const +{ + return m_provider->GetKeyOrigin(keyid, info); } bool FlatSigningProvider::GetCScript(const CScriptID& scriptid, CScript& script) const { return LookupHelper(scripts, scriptid, script); } diff --git a/src/script/sign.h b/src/script/sign.h index e0668f8c58..323fe70f34 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -34,6 +34,7 @@ class SigningProvider virtual bool GetCScript(const CScriptID &scriptid, CScript& script) const { return false; } virtual bool GetPubKey(const CKeyID &address, CPubKey& pubkey) const { return false; } virtual bool GetKey(const CKeyID &address, CKey& key) const { return false; } + virtual bool GetKeyOrigin(const CKeyID& id, KeyOriginInfo& info) const { return false; } }; extern const SigningProvider& DUMMY_SIGNING_PROVIDER; @@ -47,6 +48,7 @@ class PublicOnlySigningProvider : public SigningProvider PublicOnlySigningProvider(const SigningProvider* provider) : m_provider(provider) {} bool GetCScript(const CScriptID &scriptid, CScript& script) const; bool GetPubKey(const CKeyID &address, CPubKey& pubkey) const; + bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const; }; struct FlatSigningProvider final : public SigningProvider From 81e1dd5ce1a32114a38691ec6b55e72ab04dbbb1 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 20 Jul 2018 00:04:02 -0700 Subject: [PATCH 0055/1200] Generalize PublicOnlySigningProvider into HidingSigningProvider --- src/script/sign.cpp | 13 ++++++++++--- src/script/sign.h | 13 ++++++++----- src/wallet/rpcwallet.cpp | 6 +----- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 47931e21d9..ae29f72b05 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -640,18 +640,25 @@ void PSBTOutput::Merge(const PSBTOutput& output) if (witness_script.empty() && !output.witness_script.empty()) witness_script = output.witness_script; } -bool PublicOnlySigningProvider::GetCScript(const CScriptID &scriptid, CScript& script) const +bool HidingSigningProvider::GetCScript(const CScriptID& scriptid, CScript& script) const { return m_provider->GetCScript(scriptid, script); } -bool PublicOnlySigningProvider::GetPubKey(const CKeyID& keyid, CPubKey& pubkey) const +bool HidingSigningProvider::GetPubKey(const CKeyID& keyid, CPubKey& pubkey) const { return m_provider->GetPubKey(keyid, pubkey); } -bool PublicOnlySigningProvider::GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const +bool HidingSigningProvider::GetKey(const CKeyID& keyid, CKey& key) const { + if (m_hide_secret) return false; + return m_provider->GetKey(keyid, key); +} + +bool HidingSigningProvider::GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const +{ + if (m_hide_origin) return false; return m_provider->GetKeyOrigin(keyid, info); } diff --git a/src/script/sign.h b/src/script/sign.h index 323fe70f34..d8334f2ea2 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -39,16 +39,19 @@ class SigningProvider extern const SigningProvider& DUMMY_SIGNING_PROVIDER; -class PublicOnlySigningProvider : public SigningProvider +class HidingSigningProvider : public SigningProvider { private: + const bool m_hide_secret; + const bool m_hide_origin; const SigningProvider* m_provider; public: - PublicOnlySigningProvider(const SigningProvider* provider) : m_provider(provider) {} - bool GetCScript(const CScriptID &scriptid, CScript& script) const; - bool GetPubKey(const CKeyID &address, CPubKey& pubkey) const; - bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const; + HidingSigningProvider(const SigningProvider* provider, bool hide_secret, bool hide_origin) : m_hide_secret(hide_secret), m_hide_origin(hide_origin), m_provider(provider) {} + bool GetCScript(const CScriptID& scriptid, CScript& script) const override; + bool GetPubKey(const CKeyID& keyid, CPubKey& pubkey) const override; + bool GetKey(const CKeyID& keyid, CKey& key) const override; + bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const override; }; struct FlatSigningProvider final : public SigningProvider diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index fd3b82d9ab..a719e883c7 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4520,11 +4520,7 @@ bool FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, const C } SignatureData sigdata; - if (sign) { - complete &= SignPSBTInput(*pwallet, *psbtx.tx, input, sigdata, i, sighash_type); - } else { - complete &= SignPSBTInput(PublicOnlySigningProvider(pwallet), *psbtx.tx, input, sigdata, i, sighash_type); - } + complete &= SignPSBTInput(HidingSigningProvider(pwallet, !sign, false), *psbtx.tx, input, sigdata, i, sighash_type); if (it != pwallet->mapWallet.end()) { // Drop the unnecessary UTXO if we added both from the wallet. From 3b01efa0d1bf3d23d1b7b7e518849f1fc26314f9 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 19 Jul 2018 17:37:19 -0700 Subject: [PATCH 0056/1200] [MOVEONLY] Move ParseHDKeypath to utilstrencodings --- src/utilstrencodings.cpp | 40 ++++++++++++++++++++++++++ src/utilstrencodings.h | 3 ++ src/wallet/rpcwallet.cpp | 41 --------------------------- src/wallet/test/psbt_wallet_tests.cpp | 2 -- 4 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index a06d88cb19..e66e2c238c 100644 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -544,3 +544,43 @@ bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out) return true; } +bool ParseHDKeypath(const std::string& keypath_str, std::vector& keypath) +{ + std::stringstream ss(keypath_str); + std::string item; + bool first = true; + while (std::getline(ss, item, '/')) { + if (item.compare("m") == 0) { + if (first) { + first = false; + continue; + } + return false; + } + // Finds whether it is hardened + uint32_t path = 0; + size_t pos = item.find("'"); + if (pos != std::string::npos) { + // The hardened tick can only be in the last index of the string + if (pos != item.size() - 1) { + return false; + } + path |= 0x80000000; + item = item.substr(0, item.size() - 1); // Drop the last character which is the hardened tick + } + + // Ensure this is only numbers + if (item.find_first_not_of( "0123456789" ) != std::string::npos) { + return false; + } + uint32_t number; + if (!ParseUInt32(item, &number)) { + return false; + } + path |= number; + + keypath.push_back(path); + first = false; + } + return true; +} diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h index 5f2211b5dc..8f29f8f322 100644 --- a/src/utilstrencodings.h +++ b/src/utilstrencodings.h @@ -183,4 +183,7 @@ bool ConvertBits(const O& outfn, I it, I end) { return true; } +/** Parse an HD keypaths like "m/7/0'/2000". */ +bool ParseHDKeypath(const std::string& keypath_str, std::vector& keypath); + #endif // BITCOIN_UTILSTRENCODINGS_H diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index a719e883c7..aa7f5312b4 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4423,47 +4423,6 @@ UniValue sethdseed(const JSONRPCRequest& request) return NullUniValue; } -bool ParseHDKeypath(std::string keypath_str, std::vector& keypath) -{ - std::stringstream ss(keypath_str); - std::string item; - bool first = true; - while (std::getline(ss, item, '/')) { - if (item.compare("m") == 0) { - if (first) { - first = false; - continue; - } - return false; - } - // Finds whether it is hardened - uint32_t path = 0; - size_t pos = item.find("'"); - if (pos != std::string::npos) { - // The hardened tick can only be in the last index of the string - if (pos != item.size() - 1) { - return false; - } - path |= 0x80000000; - item = item.substr(0, item.size() - 1); // Drop the last character which is the hardened tick - } - - // Ensure this is only numbers - if (item.find_first_not_of( "0123456789" ) != std::string::npos) { - return false; - } - uint32_t number; - if (!ParseUInt32(item, &number)) { - return false; - } - path |= number; - - keypath.push_back(path); - first = false; - } - return true; -} - void AddKeypathToMap(const CWallet* pwallet, const CKeyID& keyID, std::map& hd_keypaths) { CPubKey vchPubKey; diff --git a/src/wallet/test/psbt_wallet_tests.cpp b/src/wallet/test/psbt_wallet_tests.cpp index 61c3fa94a6..526f2d983f 100644 --- a/src/wallet/test/psbt_wallet_tests.cpp +++ b/src/wallet/test/psbt_wallet_tests.cpp @@ -13,8 +13,6 @@ #include #include -extern bool ParseHDKeypath(std::string keypath_str, std::vector& keypath); - BOOST_FIXTURE_TEST_SUITE(psbt_wallet_tests, WalletTestingSetup) BOOST_AUTO_TEST_CASE(psbt_updater_test) From 03a99586a398ee38f40c3b72d24c6a2ba4b88579 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 19 Jul 2018 17:56:52 -0700 Subject: [PATCH 0057/1200] Implement key origin lookup in CWallet --- src/wallet/rpcwallet.cpp | 21 ++------------------- src/wallet/wallet.cpp | 26 ++++++++++++++++++++++++++ src/wallet/wallet.h | 2 ++ 3 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index aa7f5312b4..0fcdd780a7 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4429,26 +4429,9 @@ void AddKeypathToMap(const CWallet* pwallet, const CKeyID& keyID, std::mapGetPubKey(keyID, vchPubKey)) { return; } - CKeyMetadata meta; - auto it = pwallet->mapKeyMetadata.find(keyID); - if (it != pwallet->mapKeyMetadata.end()) { - meta = it->second; - } KeyOriginInfo info; - if (!meta.hdKeypath.empty()) { - if (!ParseHDKeypath(meta.hdKeypath, info.path)) { - throw JSONRPCError(RPC_INTERNAL_ERROR, "Internal keypath is broken"); - } - // Get the proper master key id - CKey key; - pwallet->GetKey(meta.hd_seed_id, key); - CExtKey masterKey; - masterKey.SetSeed(key.begin(), key.size()); - // Compute identifier - CKeyID masterid = masterKey.key.GetPubKey().GetID(); - std::copy(masterid.begin(), masterid.begin() + 4, info.fingerprint); - } else { // Single pubkeys get the master fingerprint of themselves - std::copy(keyID.begin(), keyID.begin() + 4, info.fingerprint); + if (!pwallet->GetKeyOrigin(keyID, info)) { + throw JSONRPCError(RPC_INTERNAL_ERROR, "Internal keypath is broken"); } hd_keypaths.emplace(vchPubKey, std::move(info)); } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 5a7fdf9a85..92ffc3c108 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4466,3 +4466,29 @@ std::vector CWallet::GroupOutputs(const std::vector& outpu } return groups; } + +bool CWallet::GetKeyOrigin(const CKeyID& keyID, KeyOriginInfo& info) const +{ + CKeyMetadata meta; + { + LOCK(cs_wallet); + auto it = mapKeyMetadata.find(keyID); + if (it != mapKeyMetadata.end()) { + meta = it->second; + } + } + if (!meta.hdKeypath.empty()) { + if (!ParseHDKeypath(meta.hdKeypath, info.path)) return false; + // Get the proper master key id + CKey key; + GetKey(meta.hd_seed_id, key); + CExtKey masterKey; + masterKey.SetSeed(key.begin(), key.size()); + // Compute identifier + CKeyID masterid = masterKey.key.GetPubKey().GetID(); + std::copy(masterid.begin(), masterid.begin() + 4, info.fingerprint); + } else { // Single pubkeys get the master fingerprint of themselves + std::copy(keyID.begin(), keyID.begin() + 4, info.fingerprint); + } + return true; +} diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 57b22c0e49..e9f6a45243 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1211,6 +1211,8 @@ class CWallet final : public CCryptoKeyStore, public CValidationInterface LogPrintf(("%s " + fmt).c_str(), GetDisplayName(), parameters...); }; + /** Implement lookup of key origin information through wallet key metadata. */ + bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const override; }; /** A key allocated from the key pool. */ From cad5dd2368109ec398a3b79c8b9e94dfd23f0845 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 19 Jul 2018 18:47:24 -0700 Subject: [PATCH 0058/1200] Pass HD path data through SignatureData --- src/script/sign.cpp | 24 +++++++++++++++++------- src/script/sign.h | 2 +- src/wallet/rpcwallet.cpp | 18 ++---------------- 3 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/script/sign.cpp b/src/script/sign.cpp index ae29f72b05..4060111ff2 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -50,10 +50,6 @@ static bool GetCScript(const SigningProvider& provider, const SignatureData& sig static bool GetPubKey(const SigningProvider& provider, SignatureData& sigdata, const CKeyID& address, CPubKey& pubkey) { - if (provider.GetPubKey(address, pubkey)) { - sigdata.misc_pubkeys.emplace(pubkey.GetID(), pubkey); - return true; - } // Look for pubkey in all partial sigs const auto it = sigdata.signatures.find(address); if (it != sigdata.signatures.end()) { @@ -63,7 +59,15 @@ static bool GetPubKey(const SigningProvider& provider, SignatureData& sigdata, c // Look for pubkey in pubkey list const auto& pk_it = sigdata.misc_pubkeys.find(address); if (pk_it != sigdata.misc_pubkeys.end()) { - pubkey = pk_it->second; + pubkey = pk_it->second.first; + return true; + } + // Query the underlying provider + if (provider.GetPubKey(address, pubkey)) { + KeyOriginInfo info; + if (provider.GetKeyOrigin(address, info)) { + sigdata.misc_pubkeys.emplace(address, std::make_pair(pubkey, std::move(info))); + } return true; } return false; @@ -543,7 +547,7 @@ void PSBTInput::FillSignatureData(SignatureData& sigdata) const sigdata.witness_script = witness_script; } for (const auto& key_pair : hd_keypaths) { - sigdata.misc_pubkeys.emplace(key_pair.first.GetID(), key_pair.first); + sigdata.misc_pubkeys.emplace(key_pair.first.GetID(), key_pair); } } @@ -571,6 +575,9 @@ void PSBTInput::FromSignatureData(const SignatureData& sigdata) if (witness_script.empty() && !sigdata.witness_script.empty()) { witness_script = sigdata.witness_script; } + for (const auto& entry : sigdata.misc_pubkeys) { + hd_keypaths.emplace(entry.second); + } } void PSBTInput::Merge(const PSBTInput& input) @@ -612,7 +619,7 @@ void PSBTOutput::FillSignatureData(SignatureData& sigdata) const sigdata.witness_script = witness_script; } for (const auto& key_pair : hd_keypaths) { - sigdata.misc_pubkeys.emplace(key_pair.first.GetID(), key_pair.first); + sigdata.misc_pubkeys.emplace(key_pair.first.GetID(), key_pair); } } @@ -624,6 +631,9 @@ void PSBTOutput::FromSignatureData(const SignatureData& sigdata) if (witness_script.empty() && !sigdata.witness_script.empty()) { witness_script = sigdata.witness_script; } + for (const auto& entry : sigdata.misc_pubkeys) { + hd_keypaths.emplace(entry.second); + } } bool PSBTOutput::IsNull() const diff --git a/src/script/sign.h b/src/script/sign.h index d8334f2ea2..a4e1eac403 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -109,7 +109,7 @@ struct SignatureData { CScript witness_script; ///< The witnessScript (if any) for the input. witnessScripts are used in P2WSH outputs. CScriptWitness scriptWitness; ///< The scriptWitness of an input. Contains complete signatures or the traditional partial signatures format. scriptWitness is part of a transaction input per BIP 144. std::map signatures; ///< BIP 174 style partial signatures for the input. May contain all signatures necessary for producing a final scriptSig or scriptWitness. - std::map misc_pubkeys; + std::map> misc_pubkeys; SignatureData() {} explicit SignatureData(const CScript& script) : scriptSig(script) {} diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 0fcdd780a7..c2cd4ea2a0 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4462,7 +4462,7 @@ bool FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, const C } SignatureData sigdata; - complete &= SignPSBTInput(HidingSigningProvider(pwallet, !sign, false), *psbtx.tx, input, sigdata, i, sighash_type); + complete &= SignPSBTInput(HidingSigningProvider(pwallet, !sign, !bip32derivs), *psbtx.tx, input, sigdata, i, sighash_type); if (it != pwallet->mapWallet.end()) { // Drop the unnecessary UTXO if we added both from the wallet. @@ -4472,13 +4472,6 @@ bool FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, const C input.witness_utxo.SetNull(); } } - - // Get public key paths - if (bip32derivs) { - for (const auto& pubkey_it : sigdata.misc_pubkeys) { - AddKeypathToMap(pwallet, pubkey_it.first, input.hd_keypaths); - } - } } // Fill in the bip32 keypaths and redeemscripts for the outputs so that hardware wallets can identify change @@ -4496,15 +4489,8 @@ bool FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, const C psbt_out.FillSignatureData(sigdata); MutableTransactionSignatureCreator creator(psbtx.tx.get_ptr(), 0, out.nValue, 1); - ProduceSignature(*pwallet, creator, out.scriptPubKey, sigdata); + ProduceSignature(HidingSigningProvider(pwallet, true, !bip32derivs), creator, out.scriptPubKey, sigdata); psbt_out.FromSignatureData(sigdata); - - // Get public key paths - if (bip32derivs) { - for (const auto& pubkey_it : sigdata.misc_pubkeys) { - AddKeypathToMap(pwallet, pubkey_it.first, psbt_out.hd_keypaths); - } - } } return complete; } From 917353c8b0eff4cd95f9a5f7719f6756bb8338b1 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 20 Jul 2018 00:23:32 -0700 Subject: [PATCH 0059/1200] Make SignPSBTInput operate on a private SignatureData object --- src/rpc/rawtransaction.cpp | 3 +-- src/script/sign.cpp | 13 ++++++++++++- src/script/sign.h | 2 +- src/wallet/rpcwallet.cpp | 12 +----------- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 8d96add13b..4f9b399a91 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -1641,8 +1641,7 @@ UniValue finalizepsbt(const JSONRPCRequest& request) for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) { PSBTInput& input = psbtx.inputs.at(i); - SignatureData sigdata; - complete &= SignPSBTInput(DUMMY_SIGNING_PROVIDER, *psbtx.tx, input, sigdata, i, 1); + complete &= SignPSBTInput(DUMMY_SIGNING_PROVIDER, *psbtx.tx, input, i, 1); } UniValue result(UniValue::VOBJ); diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 4060111ff2..ea14abce4c 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -237,7 +237,7 @@ bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreato return sigdata.complete; } -bool SignPSBTInput(const SigningProvider& provider, const CMutableTransaction& tx, PSBTInput& input, SignatureData& sigdata, int index, int sighash) +bool SignPSBTInput(const SigningProvider& provider, const CMutableTransaction& tx, PSBTInput& input, int index, int sighash) { // if this input has a final scriptsig or scriptwitness, don't do anything with it if (!input.final_script_sig.empty() || !input.final_script_witness.IsNull()) { @@ -245,6 +245,7 @@ bool SignPSBTInput(const SigningProvider& provider, const CMutableTransaction& t } // Fill SignatureData with input info + SignatureData sigdata; input.FillSignatureData(sigdata); // Get UTXO @@ -276,6 +277,16 @@ bool SignPSBTInput(const SigningProvider& provider, const CMutableTransaction& t // Verify that a witness signature was produced in case one was required. if (require_witness_sig && !sigdata.witness) return false; input.FromSignatureData(sigdata); + + // If both UTXO types are present, drop the unnecessary one. + if (input.non_witness_utxo && !input.witness_utxo.IsNull()) { + if (sigdata.witness) { + input.non_witness_utxo = nullptr; + } else { + input.witness_utxo.SetNull(); + } + } + return sig_complete; } diff --git a/src/script/sign.h b/src/script/sign.h index a4e1eac403..160b3be75b 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -696,7 +696,7 @@ bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, C bool SignSignature(const SigningProvider &provider, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType); /** Signs a PSBTInput, verifying that all provided data matches what is being signed. */ -bool SignPSBTInput(const SigningProvider& provider, const CMutableTransaction& tx, PSBTInput& input, SignatureData& sigdata, int index, int sighash = 1); +bool SignPSBTInput(const SigningProvider& provider, const CMutableTransaction& tx, PSBTInput& input, int index, int sighash = SIGHASH_ALL); /** Extract signature data from a transaction input, and insert it. */ SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nIn, const CTxOut& txout); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index c2cd4ea2a0..b8e7b7fe0c 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4461,17 +4461,7 @@ bool FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, const C throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Specified Sighash and sighash in PSBT do not match."); } - SignatureData sigdata; - complete &= SignPSBTInput(HidingSigningProvider(pwallet, !sign, !bip32derivs), *psbtx.tx, input, sigdata, i, sighash_type); - - if (it != pwallet->mapWallet.end()) { - // Drop the unnecessary UTXO if we added both from the wallet. - if (sigdata.witness) { - input.non_witness_utxo = nullptr; - } else { - input.witness_utxo.SetNull(); - } - } + complete &= SignPSBTInput(HidingSigningProvider(pwallet, !sign, !bip32derivs), *psbtx.tx, input, i, sighash_type); } // Fill in the bip32 keypaths and redeemscripts for the outputs so that hardware wallets can identify change From 36b1b63f20cc718084971d2cadd04497a9b72634 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 4 Jun 2018 18:22:58 -0400 Subject: [PATCH 0060/1200] rpc: Expose ProcessNewBlockHeaders --- src/core_io.h | 2 ++ src/core_read.cpp | 14 ++++++++++++++ src/rpc/mining.cpp | 39 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/core_io.h b/src/core_io.h index ee323a22ee..d53a45c0cb 100644 --- a/src/core_io.h +++ b/src/core_io.h @@ -11,6 +11,7 @@ #include class CBlock; +class CBlockHeader; class CScript; class CTransaction; struct CMutableTransaction; @@ -23,6 +24,7 @@ CScript ParseScript(const std::string& s); std::string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDecode = false); bool DecodeHexTx(CMutableTransaction& tx, const std::string& hex_tx, bool try_no_witness = false, bool try_witness = true); bool DecodeHexBlk(CBlock&, const std::string& strHexBlk); +bool DecodeHexBlockHeader(CBlockHeader&, const std::string& hex_header); uint256 ParseHashStr(const std::string&, const std::string& strName); std::vector ParseHexUV(const UniValue& v, const std::string& strName); bool DecodePSBT(PartiallySignedTransaction& psbt, const std::string& base64_tx, std::string& error); diff --git a/src/core_read.cpp b/src/core_read.cpp index a5df45aba1..b02016c014 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -145,6 +145,20 @@ bool DecodeHexTx(CMutableTransaction& tx, const std::string& hex_tx, bool try_no return false; } +bool DecodeHexBlockHeader(CBlockHeader& header, const std::string& hex_header) +{ + if (!IsHex(hex_header)) return false; + + const std::vector header_data{ParseHex(hex_header)}; + CDataStream ser_header(header_data, SER_NETWORK, PROTOCOL_VERSION); + try { + ser_header >> header; + } catch (const std::exception&) { + return false; + } + return true; +} + bool DecodeHexBlk(CBlock& block, const std::string& strHexBlk) { if (!IsHex(strHexBlk)) diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index e751587dc7..623b0bd86a 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -23,6 +22,7 @@ #include #include #include +#include #include #include @@ -763,6 +763,42 @@ static UniValue submitblock(const JSONRPCRequest& request) return BIP22ValidationResult(sc.state); } +static UniValue submitheader(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 1) { + throw std::runtime_error( + "submitheader \"hexdata\"\n" + "\nDecode the given hexdata as a header and submit it as a candidate chain tip if valid." + "\nThrows when the header is invalid.\n" + "\nArguments\n" + "1. \"hexdata\" (string, required) the hex-encoded block header data\n" + "\nResult:\n" + "None" + "\nExamples:\n" + + HelpExampleCli("submitheader", "\"aabbcc\"") + + HelpExampleRpc("submitheader", "\"aabbcc\"")); + } + + CBlockHeader h; + if (!DecodeHexBlockHeader(h, request.params[0].get_str())) { + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block header decode failed"); + } + { + LOCK(cs_main); + if (!LookupBlockIndex(h.hashPrevBlock)) { + throw JSONRPCError(RPC_VERIFY_ERROR, "Must submit previous header (" + h.hashPrevBlock.GetHex() + ") first"); + } + } + + CValidationState state; + ProcessNewBlockHeaders({h}, state, Params(), /* ppindex */ nullptr, /* first_invalid */ nullptr); + if (state.IsValid()) return NullUniValue; + if (state.IsError()) { + throw JSONRPCError(RPC_VERIFY_ERROR, FormatStateMessage(state)); + } + throw JSONRPCError(RPC_VERIFY_ERROR, state.GetRejectReason()); +} + static UniValue estimatefee(const JSONRPCRequest& request) { throw JSONRPCError(RPC_METHOD_DEPRECATED, "estimatefee was removed in v0.17.\n" @@ -940,6 +976,7 @@ static const CRPCCommand commands[] = { "mining", "prioritisetransaction", &prioritisetransaction, {"txid","dummy","fee_delta"} }, { "mining", "getblocktemplate", &getblocktemplate, {"template_request"} }, { "mining", "submitblock", &submitblock, {"hexdata","dummy"} }, + { "mining", "submitheader", &submitheader, {"hexdata"} }, { "generating", "generatetoaddress", &generatetoaddress, {"nblocks","address","maxtries"} }, From fa091b001605c4481fb4eca415929a98d3478549 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 4 Jun 2018 20:27:08 -0400 Subject: [PATCH 0061/1200] qa: Add tests for submitheader --- test/functional/mining_basic.py | 79 ++++++++++++++++++++++++++++++--- 1 file changed, 74 insertions(+), 5 deletions(-) diff --git a/test/functional/mining_basic.py b/test/functional/mining_basic.py index fa20a2d2f4..15b2d7f757 100755 --- a/test/functional/mining_basic.py +++ b/test/functional/mining_basic.py @@ -9,16 +9,23 @@ - submitblock""" import copy -from binascii import b2a_hex from decimal import Decimal from test_framework.blocktools import create_coinbase -from test_framework.messages import CBlock +from test_framework.messages import ( + CBlock, + CBlockHeader, +) +from test_framework.mininode import ( + P2PDataStore, +) from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_equal, assert_raises_rpc_error +from test_framework.util import ( + assert_equal, + assert_raises_rpc_error, + bytes_to_hex_str as b2x, +) -def b2x(b): - return b2a_hex(b).decode('ascii') def assert_template(node, block, expect, rehash=True): if rehash: @@ -131,5 +138,67 @@ def run_test(self): bad_block.hashPrevBlock = 123 assert_template(node, bad_block, 'inconclusive-not-best-prevblk') + self.log.info('submitheader tests') + assert_raises_rpc_error(-22, 'Block header decode failed', lambda: node.submitheader(hexdata='xx' * 80)) + assert_raises_rpc_error(-22, 'Block header decode failed', lambda: node.submitheader(hexdata='ff' * 78)) + assert_raises_rpc_error(-25, 'Must submit previous header', lambda: node.submitheader(hexdata='ff' * 80)) + + block.solve() + + def chain_tip(b_hash, *, status='headers-only', branchlen=1): + return {'hash': b_hash, 'height': 202, 'branchlen': branchlen, 'status': status} + + assert chain_tip(block.hash) not in node.getchaintips() + node.submitheader(hexdata=b2x(block.serialize())) + assert chain_tip(block.hash) in node.getchaintips() + node.submitheader(hexdata=b2x(CBlockHeader(block).serialize())) # Noop + assert chain_tip(block.hash) in node.getchaintips() + + bad_block_root = copy.deepcopy(block) + bad_block_root.hashMerkleRoot += 2 + bad_block_root.solve() + assert chain_tip(bad_block_root.hash) not in node.getchaintips() + node.submitheader(hexdata=b2x(CBlockHeader(bad_block_root).serialize())) + assert chain_tip(bad_block_root.hash) in node.getchaintips() + # Should still reject invalid blocks, even if we have the header: + assert_equal(node.submitblock(hexdata=b2x(bad_block_root.serialize())), 'invalid') + assert chain_tip(bad_block_root.hash) in node.getchaintips() + # We know the header for this invalid block, so should just return early without error: + node.submitheader(hexdata=b2x(CBlockHeader(bad_block_root).serialize())) + assert chain_tip(bad_block_root.hash) in node.getchaintips() + + bad_block_lock = copy.deepcopy(block) + bad_block_lock.vtx[0].nLockTime = 2**32 - 1 + bad_block_lock.vtx[0].rehash() + bad_block_lock.hashMerkleRoot = bad_block_lock.calc_merkle_root() + bad_block_lock.solve() + assert_equal(node.submitblock(hexdata=b2x(bad_block_lock.serialize())), 'invalid') + # Build a "good" block on top of the submitted bad block + bad_block2 = copy.deepcopy(block) + bad_block2.hashPrevBlock = bad_block_lock.sha256 + bad_block2.solve() + assert_raises_rpc_error(-25, 'bad-prevblk', lambda: node.submitheader(hexdata=b2x(CBlockHeader(bad_block2).serialize()))) + + # Should reject invalid header right away + bad_block_time = copy.deepcopy(block) + bad_block_time.nTime = 1 + bad_block_time.solve() + assert_raises_rpc_error(-25, 'time-too-old', lambda: node.submitheader(hexdata=b2x(CBlockHeader(bad_block_time).serialize()))) + + # Should ask for the block from a p2p node, if they announce the header as well: + node.add_p2p_connection(P2PDataStore()) + node.p2p.wait_for_getheaders(timeout=5) # Drop the first getheaders + node.p2p.send_blocks_and_test(blocks=[block], rpc=node) + # Must be active now: + assert chain_tip(block.hash, status='active', branchlen=0) in node.getchaintips() + + # Building a few blocks should give the same results + node.generate(10) + assert_raises_rpc_error(-25, 'time-too-old', lambda: node.submitheader(hexdata=b2x(CBlockHeader(bad_block_time).serialize()))) + assert_raises_rpc_error(-25, 'bad-prevblk', lambda: node.submitheader(hexdata=b2x(CBlockHeader(bad_block2).serialize()))) + node.submitheader(hexdata=b2x(CBlockHeader(block).serialize())) + node.submitheader(hexdata=b2x(CBlockHeader(bad_block_root).serialize())) + + if __name__ == '__main__': MiningTest().main() From 43811e63380d803e037de69dc0567aae590fa109 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Mon, 13 Aug 2018 14:59:31 -0700 Subject: [PATCH 0062/1200] Fix PSBT deserialization of 0-input transactions 0-input transactions can be ambiguously deserialized as being witness transactions. Since the unsigned transaction is never serialized as a witness transaction as it has no witnesses, we should always deserialize it as a non-witness transaction and set the serialization flags as such. Also always serialize the unsigned transaction as a non-witness transaction. --- src/script/sign.h | 7 +++++-- src/streams.h | 1 + test/functional/data/rpc_psbt.json | 3 ++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/script/sign.h b/src/script/sign.h index 24cddda51b..86188cbb38 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -547,7 +547,8 @@ struct PartiallySignedTransaction SerializeToVector(s, PSBT_GLOBAL_UNSIGNED_TX); // Write serialized tx to a stream - SerializeToVector(s, *tx); + OverrideStream os(&s, s.GetType(), s.GetVersion() | SERIALIZE_TRANSACTION_NO_WITNESS); + SerializeToVector(os, *tx); // Write the unknown things for (auto& entry : unknown) { @@ -601,7 +602,9 @@ struct PartiallySignedTransaction throw std::ios_base::failure("Global unsigned tx key is more than one byte type"); } CMutableTransaction mtx; - UnserializeFromVector(s, mtx); + // Set the stream to serialize with non-witness since this should always be non-witness + OverrideStream os(&s, s.GetType(), s.GetVersion() | SERIALIZE_TRANSACTION_NO_WITNESS); + UnserializeFromVector(os, mtx); tx = std::move(mtx); // Make sure that all scriptSigs and scriptWitnesses are empty for (const CTxIn& txin : tx->vin) { diff --git a/src/streams.h b/src/streams.h index 2dcca6646d..096ebfc9c2 100644 --- a/src/streams.h +++ b/src/streams.h @@ -61,6 +61,7 @@ class OverrideStream int GetVersion() const { return nVersion; } int GetType() const { return nType; } + size_t size() const { return stream->size(); } }; template diff --git a/test/functional/data/rpc_psbt.json b/test/functional/data/rpc_psbt.json index d800fa97a5..e81ea30ff9 100644 --- a/test/functional/data/rpc_psbt.json +++ b/test/functional/data/rpc_psbt.json @@ -24,7 +24,8 @@ "cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEHakcwRAIgR1lmF5fAGwNrJZKJSGhiGDR9iYZLcZ4ff89X0eURZYcCIFMJ6r9Wqk2Ikf/REf3xM286KdqGbX+EhtdVRs7tr5MZASEDXNxh/HupccC1AaZGoqg7ECy0OIEhfKaC3Ibi1z+ogpIAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIAAAA", "cHNidP8BAHUCAAAAASaBcTce3/KF6Tet7qSze3gADAVmy7OtZGQXE8pCFxv2AAAAAAD+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQD9pQEBAAAAAAECiaPHHqtNIOA3G7ukzGmPopXJRjr6Ljl/hTPMti+VZ+UBAAAAFxYAFL4Y0VKpsBIDna89p95PUzSe7LmF/////4b4qkOnHf8USIk6UwpyN+9rRgi7st0tAXHmOuxqSJC0AQAAABcWABT+Pp7xp0XpdNkCxDVZQ6vLNL1TU/////8CAMLrCwAAAAAZdqkUhc/xCX/Z4Ai7NK9wnGIZeziXikiIrHL++E4sAAAAF6kUM5cluiHv1irHU6m80GfWx6ajnQWHAkcwRAIgJxK+IuAnDzlPVoMR3HyppolwuAJf3TskAinwf4pfOiQCIAGLONfc0xTnNMkna9b7QPZzMlvEuqFEyADS8vAtsnZcASED0uFWdJQbrUqZY3LLh+GFbTZSYG2YVi/jnF6efkE/IQUCSDBFAiEA0SuFLYXc2WHS9fSrZgZU327tzHlMDDPOXMMJ/7X85Y0CIGczio4OFyXBl/saiK9Z9R5E5CVbIBZ8hoQDHAXR8lkqASECI7cr7vCWXRC+B3jv7NYfysb3mk6haTkzgHNEZPhPKrMAAAAAAQMEAQAAAAAAAA==", "cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEA3wIAAAABJoFxNx7f8oXpN63upLN7eAAMBWbLs61kZBcTykIXG/YAAAAAakcwRAIgcLIkUSPmv0dNYMW1DAQ9TGkaXSQ18Jo0p2YqncJReQoCIAEynKnazygL3zB0DsA5BCJCLIHLRYOUV663b8Eu3ZWzASECZX0RjTNXuOD0ws1G23s59tnDjZpwq8ubLeXcjb/kzjH+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIACICAurVlmh8qAYEPtw94RbN8p1eklfBls0FXPaYyNAr8k6ZELSmumcAAACAAAAAgAIAAIAAIgIDlPYr6d8ZlSxVh3aK63aYBhrSxKJciU9H2MFitNchPQUQtKa6ZwAAAIABAACAAgAAgAA=", - "cHNidP8BAFUCAAAAASeaIyOl37UfxF8iD6WLD8E+HjNCeSqF1+Ns1jM7XLw5AAAAAAD/////AaBa6gsAAAAAGXapFP/pwAYQl8w7Y28ssEYPpPxCfStFiKwAAAAAAAEBIJVe6gsAAAAAF6kUY0UgD2jRieGtwN8cTRbqjxTA2+uHIgIDsTQcy6doO2r08SOM1ul+cWfVafrEfx5I1HVBhENVvUZGMEMCIAQktY7/qqaU4VWepck7v9SokGQiQFXN8HC2dxRpRC0HAh9cjrD+plFtYLisszrWTt5g6Hhb+zqpS5m9+GFR25qaAQEEIgAgdx/RitRZZm3Unz1WTj28QvTIR3TjYK2haBao7UiNVoEBBUdSIQOxNBzLp2g7avTxI4zW6X5xZ9Vp+sR/HkjUdUGEQ1W9RiED3lXR4drIBeP4pYwfv5uUwC89uq/hJ/78pJlfJvggg71SriIGA7E0HMunaDtq9PEjjNbpfnFn1Wn6xH8eSNR1QYRDVb1GELSmumcAAACAAAAAgAQAAIAiBgPeVdHh2sgF4/iljB+/m5TALz26r+En/vykmV8m+CCDvRC0prpnAAAAgAAAAIAFAACAAAA=" + "cHNidP8BAFUCAAAAASeaIyOl37UfxF8iD6WLD8E+HjNCeSqF1+Ns1jM7XLw5AAAAAAD/////AaBa6gsAAAAAGXapFP/pwAYQl8w7Y28ssEYPpPxCfStFiKwAAAAAAAEBIJVe6gsAAAAAF6kUY0UgD2jRieGtwN8cTRbqjxTA2+uHIgIDsTQcy6doO2r08SOM1ul+cWfVafrEfx5I1HVBhENVvUZGMEMCIAQktY7/qqaU4VWepck7v9SokGQiQFXN8HC2dxRpRC0HAh9cjrD+plFtYLisszrWTt5g6Hhb+zqpS5m9+GFR25qaAQEEIgAgdx/RitRZZm3Unz1WTj28QvTIR3TjYK2haBao7UiNVoEBBUdSIQOxNBzLp2g7avTxI4zW6X5xZ9Vp+sR/HkjUdUGEQ1W9RiED3lXR4drIBeP4pYwfv5uUwC89uq/hJ/78pJlfJvggg71SriIGA7E0HMunaDtq9PEjjNbpfnFn1Wn6xH8eSNR1QYRDVb1GELSmumcAAACAAAAAgAQAAIAiBgPeVdHh2sgF4/iljB+/m5TALz26r+En/vykmV8m+CCDvRC0prpnAAAAgAAAAIAFAACAAAA=", + "cHNidP8BACoCAAAAAAFAQg8AAAAAABepFG6Rty1Vk+fUOR4v9E6R6YXDFkHwhwAAAAAAAA==" ], "creator" : [ { From bd19cc78cfc455cf06e120adb0d12c2f96ba8fca Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Mon, 13 Aug 2018 15:00:06 -0700 Subject: [PATCH 0063/1200] Serialize non-witness utxo as a non-witness tx but always deserialize as witness Strip out the witnesses when serializing the non-witness utxo. However witness serializations are allowed, so make sure we always deserialize as witness. --- src/script/sign.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/script/sign.h b/src/script/sign.h index 86188cbb38..80fda617e9 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -223,7 +223,8 @@ struct PSBTInput // If there is a non-witness utxo, then don't add the witness one. if (non_witness_utxo) { SerializeToVector(s, PSBT_IN_NON_WITNESS_UTXO); - SerializeToVector(s, non_witness_utxo); + OverrideStream os(&s, s.GetType(), s.GetVersion() | SERIALIZE_TRANSACTION_NO_WITNESS); + SerializeToVector(os, non_witness_utxo); } else if (!witness_utxo.IsNull()) { SerializeToVector(s, PSBT_IN_WITNESS_UTXO); SerializeToVector(s, witness_utxo); @@ -297,13 +298,17 @@ struct PSBTInput // Do stuff based on type switch(type) { case PSBT_IN_NON_WITNESS_UTXO: + { if (non_witness_utxo) { throw std::ios_base::failure("Duplicate Key, input non-witness utxo already provided"); } else if (key.size() != 1) { throw std::ios_base::failure("Non-witness utxo key is more than one byte type"); } - UnserializeFromVector(s, non_witness_utxo); + // Set the stream to unserialize with witness since this is always a valid network transaction + OverrideStream os(&s, s.GetType(), s.GetVersion() & ~SERIALIZE_TRANSACTION_NO_WITNESS); + UnserializeFromVector(os, non_witness_utxo); break; + } case PSBT_IN_WITNESS_UTXO: if (!witness_utxo.IsNull()) { throw std::ios_base::failure("Duplicate Key, input witness utxo already provided"); From 16bcc1b8237698c96b8ced2fa7eb76388c7ba85e Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Mon, 13 Aug 2018 18:45:26 -0700 Subject: [PATCH 0064/1200] Remove unused dummy_tx variable from FillPSBT --- src/wallet/rpcwallet.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index a766874f12..c03dbc5d2c 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4544,11 +4544,6 @@ bool FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, const C const CTxOut& out = txConst->vout.at(i); PSBTOutput& psbt_out = psbtx.outputs.at(i); - // Dummy tx so we can use ProduceSignature to get stuff out - CMutableTransaction dummy_tx; - dummy_tx.vin.push_back(CTxIn()); - dummy_tx.vout.push_back(CTxOut()); - // Fill a SignatureData with output info SignatureData sigdata; psbt_out.FillSignatureData(sigdata); From 8845c8aea65897637c330f5893461c0da180eaf8 Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Mon, 13 Aug 2018 19:05:31 -0700 Subject: [PATCH 0065/1200] tests: Replace usage of tostring() with tobytes() tostring() is deprecated as of python 3.7 and results in stderr output causing tests to fail --- test/functional/test_framework/netutil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/test_framework/netutil.py b/test/functional/test_framework/netutil.py index 5f1613d668..45c182f630 100644 --- a/test/functional/test_framework/netutil.py +++ b/test/functional/test_framework/netutil.py @@ -107,7 +107,7 @@ def all_interfaces(): max_possible *= 2 else: break - namestr = names.tostring() + namestr = names.tobytes() return [(namestr[i:i+16].split(b'\0', 1)[0], socket.inet_ntoa(namestr[i+20:i+24])) for i in range(0, outbytes, struct_size)] From 4d0c7924d22ffaa620884c8177e21f89261d057a Mon Sep 17 00:00:00 2001 From: Chun Kuan Lee Date: Tue, 14 Aug 2018 08:37:09 +0800 Subject: [PATCH 0066/1200] Make macro compatible with MSVC --- src/ui_interface.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ui_interface.h b/src/ui_interface.h index 992c585b10..fe466b3ca4 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -75,9 +75,9 @@ class CClientUIInterface MSG_ERROR = (ICON_ERROR | BTN_OK | MODAL) }; -#define ADD_SIGNALS_DECL_WRAPPER(signal_name, rtype, args...) \ - rtype signal_name(args); \ - using signal_name##Sig = rtype(args); \ +#define ADD_SIGNALS_DECL_WRAPPER(signal_name, rtype, ...) \ + rtype signal_name(__VA_ARGS__); \ + using signal_name##Sig = rtype(__VA_ARGS__); \ boost::signals2::connection signal_name##_connect(std::function fn); \ void signal_name##_disconnect(std::function fn); From 90cc69c0c7b0fcfa604584e2666060488346e9fc Mon Sep 17 00:00:00 2001 From: Chun Kuan Lee Date: Tue, 14 Aug 2018 11:41:16 +0800 Subject: [PATCH 0067/1200] ci: Add appveyor.yml to build on MSVC --- appveyor.yml | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 appveyor.yml diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000000..0c0c3d066b --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,34 @@ +skip_tags: true +image: Visual Studio 2017 +configuration: Release +platform: x64 +environment: + APPVEYOR_SAVE_CACHE_ON_ERROR: true +cache: C:\tools\vcpkg\installed\ +before_build: +- ps: >- + $packages = @( + "boost-filesystem", + "boost-signals2", + "boost-interprocess", + "boost-test", + "libevent", + "openssl", + "zeromq", + "berkeleydb", + "secp256k1", + "leveldb" + ) + + for ($i=0; $i -lt $packages.length; $i++) { + $all_packages += $packages[$i] + ":" + $env:PLATFORM + "-windows-static " + } + + Invoke-Expression -Command "vcpkg install $all_packages" +build: + project: build_msvc\bitcoin.sln + parallel: true + verbosity: minimal +test_script: +- cmd: build_msvc\%PLATFORM%\Release\test_bitcoin.exe +deploy: off From a9cf5c9623ad547d9aeebea2b51c2afcfc0f3f4f Mon Sep 17 00:00:00 2001 From: Chun Kuan Lee Date: Tue, 14 Aug 2018 09:26:30 +0000 Subject: [PATCH 0068/1200] Import CInv from correct module --- test/functional/example_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/example_test.py b/test/functional/example_test.py index 714d977380..a8c1474876 100755 --- a/test/functional/example_test.py +++ b/test/functional/example_test.py @@ -15,8 +15,8 @@ # Avoid wildcard * imports if possible from test_framework.blocktools import (create_block, create_coinbase) +from test_framework.messages import CInv from test_framework.mininode import ( - CInv, P2PInterface, mininode_lock, msg_block, From 321159e53e800c1df2d8dfd6ac03374f1829c327 Mon Sep 17 00:00:00 2001 From: Gregory Sanders Date: Tue, 14 Aug 2018 11:34:27 -0400 Subject: [PATCH 0069/1200] don't report minversion wallet entry as unknown --- src/wallet/walletdb.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 15c5b82c52..1b787be198 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -509,7 +509,8 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, strErr = "Error reading wallet database: Unknown non-tolerable wallet flags found"; return false; } - } else if (strType != "bestblock" && strType != "bestblock_nomerkle") { + } else if (strType != "bestblock" && strType != "bestblock_nomerkle" && + strType != "minversion") { wss.m_unknown_records++; } } catch (...) From 2252ec50085c151e7998ca9a30cda6a33ee862b6 Mon Sep 17 00:00:00 2001 From: Gregory Sanders Date: Tue, 14 Aug 2018 14:28:29 -0400 Subject: [PATCH 0070/1200] Allow ConstructTransaction to not throw error with 0-input txn --- 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 608a1b5da2..314184ab06 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -436,7 +436,7 @@ CMutableTransaction ConstructTransaction(const UniValue& inputs_in, const UniVal } } - if (!rbf.isNull() && rbfOptIn != SignalsOptInRBF(rawTx)) { + if (!rbf.isNull() && rawTx.vin.size() > 0 && rbfOptIn != SignalsOptInRBF(rawTx)) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter combination: Sequence number(s) contradict replaceable option"); } From 19efc01aec6b0d8750413fa1b721e04aaecf8f73 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 31 Jul 2018 16:53:02 -0700 Subject: [PATCH 0071/1200] Add PSBT documentation --- doc/README.md | 1 + doc/psbt.md | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 doc/psbt.md diff --git a/doc/README.md b/doc/README.md index 5ffff825b4..b3f875c4a4 100644 --- a/doc/README.md +++ b/doc/README.md @@ -75,6 +75,7 @@ The Bitcoin repo's [root README](/README.md) contains relevant information on th - [Tor Support](tor.md) - [Init Scripts (systemd/upstart/openrc)](init.md) - [ZMQ](zmq.md) +- [PSBT support](psbt.md) License --------------------- diff --git a/doc/psbt.md b/doc/psbt.md new file mode 100644 index 0000000000..95e2f7fa01 --- /dev/null +++ b/doc/psbt.md @@ -0,0 +1,132 @@ +# PSBT Howto for Bitcoin Core + +Since Bitcoin Core 0.17, an RPC interface exists for Partially Signed Bitcoin +Transactions (PSBTs, as specified in +[BIP 174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki)). + +This document describes the overall workflow for producing signed transactions +through the use of PSBT, and the specific RPC commands used in typical +scenarios. + +## PSBT in general + +PSBT is an interchange format for Bitcoin transactions that are not fully signed +yet, together with relevant metadata to help entities work towards signing it. +It is intended to simplify workflows where multiple parties need to cooperate to +produce a transaction. Examples include hardware wallets, multisig setups, and +[CoinJoin](https://bitcointalk.org/?topic=279249) transactions. + +### Overall workflow + +Overall, the construction of a fully signed Bitcoin transaction goes through the +following steps: + +- A **Creator** proposes a particular transaction to be created. They construct + a PSBT that contains certain inputs and outputs, but no additional metadata. +- For each input, an **Updater** adds information about the UTXOs being spent by + the transaction to the PSBT. They also add information about the scripts and + public keys involved in each of the inputs (and possibly outputs) of the PSBT. +- **Signers** inspect the transaction and its metadata to decide whether they + agree with the transaction. They can use amount information from the UTXOs + to assess the values and fees involved. If they agree, they produce a + partial signature for the inputs for which they have relevant key(s). +- A **Finalizer** is run for each input to convert the partial signatures and + possibly script information into a final `scriptSig` and/or `scriptWitness`. +- An **Extractor** produces a valid Bitcoin transaction (in network format) + from a PSBT for which all inputs are finalized. + +Generally, each of the above (excluding Creator and Extractor) will simply +add more and more data to a particular PSBT, until all inputs are fully signed. +In a naive workflow, they all have to operate sequentially, passing the PSBT +from one to the next, until the Extractor can convert it to a real transaction. +In order to permit parallel operation, **Combiners** can be employed which merge +metadata from different PSBTs for the same unsigned transaction. + +The names above in bold are the names of the roles defined in BIP174. They're +useful in understanding the underlying steps, but in practice, software and +hardware implementations will typically implement multiple roles simultaneously. + +## PSBT in Bitcoin Core + +### RPCs + +- **`converttopsbt` (Creator)** is a utility RPC that converts an + unsigned raw transaction to PSBT format. It ignores existing signatures. +- **`createpsbt` (Creator)** is a utility RPC that takes a list of inputs and + outputs and converts them to a PSBT with no additional information. It is + equivalent to calling `createrawtransaction` followed by `converttopsbt`. +- **`walletcreatefundedpsbt` (Creator, Updater)** is a wallet RPC that creates a + PSBT with the specified inputs and outputs, adds additional inputs and change + to it to balance it out, and adds relevant metadata. In particular, for inputs + that the wallet knows about (counting towards its normal or watch-only + balance), UTXO information will be added. For outputs and inputs with UTXO + information present, key and script information will be added which the wallet + knows about. It is equivalent to running `createrawtransaction`, followed by + `fundrawtransaction`, and `converttopsbt`. +- **`walletprocesspsbt` (Updater, Signer, Finalizer)** is a wallet RPC that takes as + input a PSBT, adds UTXO, key, and script data to inputs and outputs that miss + it, and optionally signs inputs. Where possible it also finalizes the partial + signatures. +- **`finalizepsbt` (Finalizer, Extractor)** is a utility RPC that finalizes any + partial signatures, and if all inputs are finalized, converts the result to a + fully signed transaction which can be broadcast with `sendrawtransaction`. +- **`combinepsbt` (Combiner)** is a utility RPC that implements a Combiner. It + can be used at any point in the workflow to merge information added to + different versions of the same PSBT. In particular it is useful to combine the + output of multiple Updaters or Signers. +- **`decodepsbt`** is a diagnostic utility RPC which will show all information in + a PSBT in human-readable form, as well as compute its eventual fee if known. + +### Workflows + +#### Multisig with multiple Bitcoin Core instances + +Alice, Bob, and Carol want to create a 2-of-3 multisig address. They're all using +Bitcoin Core. We assume their wallets only contain the multisig funds. In case +they also have a personal wallet, this can be accomplished through the +multiwallet feature - possibly resulting in a need to add `-rpcwallet=name` to +the command line in case `bitcoin-cli` is used. + +Setup: +- All three call `getnewaddress` to create a new address; call these addresses + *Aalice*, *Abob*, and *Acarol*. +- All three call `getaddressinfo X`, with *X* their respective address, and + remember the corresponding public keys. Call these public keys *Kalice*, + *Kbob*, and *Kcarol*. +- All three now run `addmultisigaddress 2 ["Kalice","Kbob","Kcarol"]` to teach + their wallet about the multisig script. Call the address produced by this + command *Amulti*. They may be required to explicitly specify the same + addresstype option each, to avoid constructing different versions due to + differences in configuration. +- They also run `importaddress "Amulti" "" false` to make their wallets treat + payments to *Amulti* as contributing to the watch-only balance. +- Others can verify the produced address by running + `createmultisig 2 ["Kalice","Kbob","Kcarol"]`, and expecting *Amulti* as + output. Again, it may be necessary to explicitly specify the addresstype + in order to get a result that matches. This command won't enable them to + initiate transactions later, however. +- They can now give out *D* as address others can pay to. + +Later, when *V* BTC has been received on *Amulti*, and Bob and Carol want to +move the coins in their entirety to address *Asend*, with no change. Alice +does not need to be involved. +- One of them - let's assume Carol here - initiates the creation. She runs + `walletcreatefundedpsbt [] {"Asend":V} 0 false {"subtractFeeFromOutputs":[0], "includeWatching":true}`. + We call the resulting PSBT *P*. P does not contain any signatures. +- Carol needs to sign the transaction herself. In order to do so, she runs + `walletprocesspsbt P`, and gives the resulting PSBT *P2* to Bob. +- Bob inspects the PSBT using `decodepsbt "P2"` to determine if the transaction + has indeed just the expected input, and an output to *Asend*, and the fee is + reasonable. If he agrees, he calls `walletprocesspsbt "P2"` to sign. The + resulting PSBT *P3* contains both Carol's and Bob's signature. +- Now anyone can call `finalizepsbt "P2"` to extract a fully signed transaction + *T*. +- Finally anyone can broadcast the transaction using `sendrawtransaction "T"`. + +In case there are more signers, it may be advantageous to let them all sign in +parallel, rather passing the PSBT from one signer to the next one. In the +above example this would translate to Carol handing a copy of *P* to each signer +separately. They can then all invoke `walletprocesspsbt P`, and end up with +their individually-signed PSBT structures. They then all send those back to +Carol (or anyone) who can combine them using `combinepsbt`. The last two steps +(`finalizepsbt` and `sendrawtransaction`) remain unchanged. From 1f6ff04e59fcd1f2315d194f096665d73c8922d2 Mon Sep 17 00:00:00 2001 From: Chun Kuan Lee Date: Tue, 14 Aug 2018 09:18:19 +0000 Subject: [PATCH 0072/1200] Use wildcard path in test_bitcoin.vcxproj --- build_msvc/test_bitcoin/test_bitcoin.vcxproj | 68 +------------------- 1 file changed, 3 insertions(+), 65 deletions(-) diff --git a/build_msvc/test_bitcoin/test_bitcoin.vcxproj b/build_msvc/test_bitcoin/test_bitcoin.vcxproj index 0ab97643fb..444a2ed725 100644 --- a/build_msvc/test_bitcoin/test_bitcoin.vcxproj +++ b/build_msvc/test_bitcoin/test_bitcoin.vcxproj @@ -20,72 +20,10 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - @@ -266,4 +204,4 @@ - \ No newline at end of file + From 8bd98a384603b78f50498a5fc67db1ef7052f399 Mon Sep 17 00:00:00 2001 From: Jon Layton Date: Tue, 14 Aug 2018 18:03:43 -0500 Subject: [PATCH 0073/1200] [trivial] Fix typo in CDiskBlockPos struct's ToString --- src/chain.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chain.h b/src/chain.h index 01011d54f1..1c0c5a7e69 100644 --- a/src/chain.h +++ b/src/chain.h @@ -117,7 +117,7 @@ struct CDiskBlockPos std::string ToString() const { - return strprintf("CBlockDiskPos(nFile=%i, nPos=%i)", nFile, nPos); + return strprintf("CDiskBlockPos(nFile=%i, nPos=%i)", nFile, nPos); } }; From 4b3b85c597a2d4139ecaa6b78b2fa9c89be3319f Mon Sep 17 00:00:00 2001 From: fanquake Date: Wed, 15 Aug 2018 21:05:21 +0800 Subject: [PATCH 0074/1200] refactor: use fs:: over boost::filesystem:: --- src/logging.cpp | 2 +- src/qt/guiutil.cpp | 4 ++-- src/wallet/rpcdump.cpp | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/logging.cpp b/src/logging.cpp index e8e22cbf97..6557dddffb 100644 --- a/src/logging.cpp +++ b/src/logging.cpp @@ -245,7 +245,7 @@ void BCLog::Logger::ShrinkDebugFile() size_t log_size = 0; try { log_size = fs::file_size(m_file_path); - } catch (boost::filesystem::filesystem_error &) {} + } catch (const fs::filesystem_error&) {} // If debug.log file is more than 10% bigger the RECENT_DEBUG_HISTORY_SIZE // trim it down by saving only the last RECENT_DEBUG_HISTORY_SIZE bytes diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index f8f031041c..f8391b6303 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -368,10 +368,10 @@ void openDebugLogfile() bool openBitcoinConf() { - boost::filesystem::path pathConfig = GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)); + fs::path pathConfig = GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)); /* Create the file */ - boost::filesystem::ofstream configFile(pathConfig, std::ios_base::app); + fs::ofstream configFile(pathConfig, std::ios_base::app); if (!configFile.good()) return false; diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 5800e75827..7cb41da39e 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -706,15 +706,15 @@ UniValue dumpwallet(const JSONRPCRequest& request) EnsureWalletIsUnlocked(pwallet); - boost::filesystem::path filepath = request.params[0].get_str(); - filepath = boost::filesystem::absolute(filepath); + fs::path filepath = request.params[0].get_str(); + filepath = fs::absolute(filepath); /* Prevent arbitrary files from being overwritten. There have been reports * that users have overwritten wallet files this way: * https://github.com/bitcoin/bitcoin/issues/9934 * It may also avoid other security issues. */ - if (boost::filesystem::exists(filepath)) { + if (fs::exists(filepath)) { throw JSONRPCError(RPC_INVALID_PARAMETER, filepath.string() + " already exists. If you are sure this is what you want, move it out of the way first"); } From fa6ab8ada14dd265e224496440ab0b5d99dfd0ef Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 15 Aug 2018 13:54:36 -0400 Subject: [PATCH 0075/1200] rpc: Return more specific reject reason for submitblock --- src/rpc/mining.cpp | 6 +----- test/functional/mining_basic.py | 21 +++++++++++++++++++-- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 623b0bd86a..8365f5ed42 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -750,11 +750,7 @@ static UniValue submitblock(const JSONRPCRequest& request) RegisterValidationInterface(&sc); bool accepted = ProcessNewBlock(Params(), blockptr, /* fForceProcessing */ true, /* fNewBlock */ &new_block); UnregisterValidationInterface(&sc); - if (!new_block) { - if (!accepted) { - // TODO Maybe pass down fNewBlock to AcceptBlockHeader, so it is properly set to true in this case? - return "invalid"; - } + if (!new_block && accepted) { return "duplicate"; } if (!sc.found) { diff --git a/test/functional/mining_basic.py b/test/functional/mining_basic.py index 15b2d7f757..ddf760c283 100755 --- a/test/functional/mining_basic.py +++ b/test/functional/mining_basic.py @@ -41,6 +41,12 @@ def set_test_params(self): def run_test(self): node = self.nodes[0] + def assert_submitblock(block, result_str_1, result_str_2=None): + block.solve() + result_str_2 = result_str_2 or 'duplicate-invalid' + assert_equal(result_str_1, node.submitblock(hexdata=b2x(block.serialize()))) + assert_equal(result_str_2, node.submitblock(hexdata=b2x(block.serialize()))) + self.log.info('getmininginfo') mining_info = node.getmininginfo() assert_equal(mining_info['blocks'], 200) @@ -93,6 +99,7 @@ def run_test(self): bad_block = copy.deepcopy(block) bad_block.vtx.append(bad_block.vtx[0]) assert_template(node, bad_block, 'bad-txns-duplicate') + assert_submitblock(bad_block, 'bad-txns-duplicate', 'bad-txns-duplicate') self.log.info("getblocktemplate: Test invalid transaction") bad_block = copy.deepcopy(block) @@ -101,12 +108,14 @@ def run_test(self): bad_tx.rehash() bad_block.vtx.append(bad_tx) assert_template(node, bad_block, 'bad-txns-inputs-missingorspent') + assert_submitblock(bad_block, 'bad-txns-inputs-missingorspent') self.log.info("getblocktemplate: Test nonfinal transaction") bad_block = copy.deepcopy(block) bad_block.vtx[0].nLockTime = 2 ** 32 - 1 bad_block.vtx[0].rehash() assert_template(node, bad_block, 'bad-txns-nonfinal') + assert_submitblock(bad_block, 'bad-txns-nonfinal') self.log.info("getblocktemplate: Test bad tx count") # The tx count is immediately after the block header @@ -125,24 +134,29 @@ def run_test(self): bad_block = copy.deepcopy(block) bad_block.hashMerkleRoot += 1 assert_template(node, bad_block, 'bad-txnmrklroot', False) + assert_submitblock(bad_block, 'bad-txnmrklroot', 'bad-txnmrklroot') self.log.info("getblocktemplate: Test bad timestamps") bad_block = copy.deepcopy(block) bad_block.nTime = 2 ** 31 - 1 assert_template(node, bad_block, 'time-too-new') + assert_submitblock(bad_block, 'time-too-new', 'time-too-new') bad_block.nTime = 0 assert_template(node, bad_block, 'time-too-old') + assert_submitblock(bad_block, 'time-too-old', 'time-too-old') self.log.info("getblocktemplate: Test not best block") bad_block = copy.deepcopy(block) bad_block.hashPrevBlock = 123 assert_template(node, bad_block, 'inconclusive-not-best-prevblk') + assert_submitblock(bad_block, 'prev-blk-not-found', 'prev-blk-not-found') self.log.info('submitheader tests') assert_raises_rpc_error(-22, 'Block header decode failed', lambda: node.submitheader(hexdata='xx' * 80)) assert_raises_rpc_error(-22, 'Block header decode failed', lambda: node.submitheader(hexdata='ff' * 78)) assert_raises_rpc_error(-25, 'Must submit previous header', lambda: node.submitheader(hexdata='ff' * 80)) + block.nTime += 1 block.solve() def chain_tip(b_hash, *, status='headers-only', branchlen=1): @@ -161,7 +175,8 @@ def chain_tip(b_hash, *, status='headers-only', branchlen=1): node.submitheader(hexdata=b2x(CBlockHeader(bad_block_root).serialize())) assert chain_tip(bad_block_root.hash) in node.getchaintips() # Should still reject invalid blocks, even if we have the header: - assert_equal(node.submitblock(hexdata=b2x(bad_block_root.serialize())), 'invalid') + assert_equal(node.submitblock(hexdata=b2x(bad_block_root.serialize())), 'bad-txnmrklroot') + assert_equal(node.submitblock(hexdata=b2x(bad_block_root.serialize())), 'bad-txnmrklroot') assert chain_tip(bad_block_root.hash) in node.getchaintips() # We know the header for this invalid block, so should just return early without error: node.submitheader(hexdata=b2x(CBlockHeader(bad_block_root).serialize())) @@ -172,7 +187,8 @@ def chain_tip(b_hash, *, status='headers-only', branchlen=1): bad_block_lock.vtx[0].rehash() bad_block_lock.hashMerkleRoot = bad_block_lock.calc_merkle_root() bad_block_lock.solve() - assert_equal(node.submitblock(hexdata=b2x(bad_block_lock.serialize())), 'invalid') + assert_equal(node.submitblock(hexdata=b2x(bad_block_lock.serialize())), 'bad-txns-nonfinal') + assert_equal(node.submitblock(hexdata=b2x(bad_block_lock.serialize())), 'duplicate-invalid') # Build a "good" block on top of the submitted bad block bad_block2 = copy.deepcopy(block) bad_block2.hashPrevBlock = bad_block_lock.sha256 @@ -198,6 +214,7 @@ def chain_tip(b_hash, *, status='headers-only', branchlen=1): assert_raises_rpc_error(-25, 'bad-prevblk', lambda: node.submitheader(hexdata=b2x(CBlockHeader(bad_block2).serialize()))) node.submitheader(hexdata=b2x(CBlockHeader(block).serialize())) node.submitheader(hexdata=b2x(CBlockHeader(bad_block_root).serialize())) + assert_equal(node.submitblock(hexdata=b2x(block.serialize())), 'duplicate') # valid if __name__ == '__main__': From 241f8b5de40e1339b3c75defe8fe182a05d16f1b Mon Sep 17 00:00:00 2001 From: Alexander Leishman Date: Wed, 15 Aug 2018 15:18:26 -0700 Subject: [PATCH 0076/1200] Fix typo in feature_blocksdir.py log message --- test/functional/feature_blocksdir.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/functional/feature_blocksdir.py b/test/functional/feature_blocksdir.py index 56f91651a8..784dc2865f 100755 --- a/test/functional/feature_blocksdir.py +++ b/test/functional/feature_blocksdir.py @@ -20,11 +20,11 @@ def run_test(self): self.stop_node(0) shutil.rmtree(self.nodes[0].datadir) initialize_datadir(self.options.tmpdir, 0) - self.log.info("Starting with non exiting blocksdir ...") + self.log.info("Starting with nonexistent blocksdir ...") blocksdir_path = os.path.join(self.options.tmpdir, 'blocksdir') self.nodes[0].assert_start_raises_init_error(["-blocksdir=" + blocksdir_path], 'Error: Specified blocks directory "{}" does not exist.'.format(blocksdir_path)) os.mkdir(blocksdir_path) - self.log.info("Starting with exiting blocksdir ...") + self.log.info("Starting with existing blocksdir ...") self.start_node(0, ["-blocksdir=" + blocksdir_path]) self.log.info("mining blocks..") self.nodes[0].generate(10) From 48618daf262b84c2e2f7322b5ca14375d7d68b64 Mon Sep 17 00:00:00 2001 From: Anthony Towns Date: Thu, 9 Aug 2018 01:52:42 +1000 Subject: [PATCH 0077/1200] Add checks for settxfee reasonableness --- src/wallet/rpcwallet.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 281fd46146..46162556eb 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2982,8 +2982,16 @@ static UniValue settxfee(const JSONRPCRequest& request) LOCK2(cs_main, pwallet->cs_wallet); CAmount nAmount = AmountFromValue(request.params[0]); + CFeeRate tx_fee_rate(nAmount, 1000); + if (tx_fee_rate == 0) { + // automatic selection + } else if (tx_fee_rate < ::minRelayTxFee) { + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("txfee cannot be less than min relay tx fee (%s)", ::minRelayTxFee.ToString())); + } else if (tx_fee_rate < pwallet->m_min_fee) { + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("txfee cannot be less than wallet min fee (%s)", pwallet->m_min_fee.ToString())); + } - pwallet->m_pay_tx_fee = CFeeRate(nAmount, 1000); + pwallet->m_pay_tx_fee = tx_fee_rate; return true; } From ea16c2d04e224a31f7d2e831bdd8db084b694d81 Mon Sep 17 00:00:00 2001 From: Chun Kuan Lee Date: Fri, 17 Aug 2018 12:57:28 +0800 Subject: [PATCH 0078/1200] appveyor: fetch the latest port data --- appveyor.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 0c0c3d066b..c6a5a91ba5 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,3 +1,4 @@ +version: '{branch}.{build}' skip_tags: true image: Visual Studio 2017 configuration: Release @@ -24,6 +25,8 @@ before_build: $all_packages += $packages[$i] + ":" + $env:PLATFORM + "-windows-static " } + git -C C:\Tools\vcpkg pull # This is a temporary fix, can be removed after appveyor update its image to include Microsoft/vcpkg#4046 + Invoke-Expression -Command "vcpkg install $all_packages" build: project: build_msvc\bitcoin.sln From de0b4fba2fb5270dcc8d851243af9187b8ef191a Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 17 Aug 2018 18:49:53 -0400 Subject: [PATCH 0079/1200] depends: fix qt determinism Qt's configure grabs the path to xkb's data root during configure, but the build changes in 5.8 apparently broke the handling for cross builds. As a result, the string embedded in the binary depends on whether or not some files are present in the builder's filesystem. The "-xkb-config-root" configure setting is intended to allow manual overriding but it is also broken. See: https://bugreports.qt.io/browse/QTBUG-60005 This has since been fixed upstream, so just hard-code the path for now. We can drop this patch when we bump to a fixed Qt. Also, fix the "-qt-xkbcommon-x11" config param which was renamed. This does not appear to affect build results, presumably because auto-detection is working, but it does not hurt to be explicit. --- depends/packages/qt.mk | 5 +++-- depends/patches/qt/xkb-default.patch | 26 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 depends/patches/qt/xkb-default.patch diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 422a1c2b19..5286f89c30 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -8,7 +8,7 @@ $(package)_dependencies=openssl zlib $(package)_linux_dependencies=freetype fontconfig libxcb libX11 xproto libXext $(package)_build_subdir=qtbase $(package)_qt_libs=corelib network widgets gui plugins testlib -$(package)_patches=fix_qt_pkgconfig.patch mac-qmake.conf fix_configure_mac.patch fix_no_printer.patch fix_rcc_determinism.patch fix_riscv64_arch.patch +$(package)_patches=fix_qt_pkgconfig.patch mac-qmake.conf fix_configure_mac.patch fix_no_printer.patch fix_rcc_determinism.patch fix_riscv64_arch.patch xkb-default.patch $(package)_qttranslations_file_name=qttranslations-$($(package)_suffix) $(package)_qttranslations_sha256_hash=9822084f8e2d2939ba39f4af4c0c2320e45d5996762a9423f833055607604ed8 @@ -83,7 +83,7 @@ $(package)_config_opts_darwin += -device-option MAC_TARGET=$(host) $(package)_config_opts_darwin += -device-option MAC_LD64_VERSION=$(LD64_VERSION) endif -$(package)_config_opts_linux = -qt-xkbcommon +$(package)_config_opts_linux = -qt-xkbcommon-x11 $(package)_config_opts_linux += -qt-xcb $(package)_config_opts_linux += -system-freetype $(package)_config_opts_linux += -no-feature-sessionmanager @@ -137,6 +137,7 @@ define $(package)_preprocess_cmds patch -p1 -i $($(package)_patch_dir)/fix_configure_mac.patch &&\ patch -p1 -i $($(package)_patch_dir)/fix_no_printer.patch &&\ patch -p1 -i $($(package)_patch_dir)/fix_rcc_determinism.patch &&\ + patch -p1 -i $($(package)_patch_dir)/xkb-default.patch &&\ echo "!host_build: QMAKE_CFLAGS += $($(package)_cflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ echo "!host_build: QMAKE_CXXFLAGS += $($(package)_cxxflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ echo "!host_build: QMAKE_LFLAGS += $($(package)_ldflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ diff --git a/depends/patches/qt/xkb-default.patch b/depends/patches/qt/xkb-default.patch new file mode 100644 index 0000000000..165abf3e2e --- /dev/null +++ b/depends/patches/qt/xkb-default.patch @@ -0,0 +1,26 @@ +--- old/qtbase/src/gui/configure.pri 2018-06-06 17:28:10.000000000 -0400 ++++ new/qtbase/src/gui/configure.pri 2018-08-17 18:43:01.589384567 -0400 +@@ -43,18 +43,11 @@ + } + + defineTest(qtConfTest_xkbConfigRoot) { +- qtConfTest_getPkgConfigVariable($${1}): return(true) +- +- for (dir, $$list("/usr/share/X11/xkb", "/usr/local/share/X11/xkb")) { +- exists($$dir) { +- $${1}.value = $$dir +- export($${1}.value) +- $${1}.cache += value +- export($${1}.cache) +- return(true) +- } +- } +- return(false) ++ $${1}.value = "/usr/share/X11/xkb" ++ export($${1}.value) ++ $${1}.cache += value ++ export($${1}.cache) ++ return(true) + } + + defineTest(qtConfTest_qpaDefaultPlatform) { From 18c49eb8877d8b11f763083a79a7b8250e060106 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Barbosa?= Date: Fri, 17 Aug 2018 15:33:02 +0100 Subject: [PATCH 0080/1200] http: Add const modifier to HTTPRequest methods --- src/httpserver.cpp | 8 ++++---- src/httpserver.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 8962fe6a42..0fdc3e5ff3 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -536,7 +536,7 @@ HTTPRequest::~HTTPRequest() // evhttpd cleans up the request, as long as a reply was sent. } -std::pair HTTPRequest::GetHeader(const std::string& hdr) +std::pair HTTPRequest::GetHeader(const std::string& hdr) const { const struct evkeyvalq* headers = evhttp_request_get_input_headers(req); assert(headers); @@ -606,7 +606,7 @@ void HTTPRequest::WriteReply(int nStatus, const std::string& strReply) req = nullptr; // transferred back to main thread } -CService HTTPRequest::GetPeer() +CService HTTPRequest::GetPeer() const { evhttp_connection* con = evhttp_request_get_connection(req); CService peer; @@ -620,12 +620,12 @@ CService HTTPRequest::GetPeer() return peer; } -std::string HTTPRequest::GetURI() +std::string HTTPRequest::GetURI() const { return evhttp_request_get_uri(req); } -HTTPRequest::RequestMethod HTTPRequest::GetRequestMethod() +HTTPRequest::RequestMethod HTTPRequest::GetRequestMethod() const { switch (evhttp_request_get_command(req)) { case EVHTTP_REQ_GET: diff --git a/src/httpserver.h b/src/httpserver.h index fa7cc4a5d3..67c6a88314 100644 --- a/src/httpserver.h +++ b/src/httpserver.h @@ -74,21 +74,21 @@ class HTTPRequest /** Get requested URI. */ - std::string GetURI(); + std::string GetURI() const; /** Get CService (address:ip) for the origin of the http request. */ - CService GetPeer(); + CService GetPeer() const; /** Get request method. */ - RequestMethod GetRequestMethod(); + RequestMethod GetRequestMethod() const; /** * Get the request header specified by hdr, or an empty string. * Return a pair (isPresent,string). */ - std::pair GetHeader(const std::string& hdr); + std::pair GetHeader(const std::string& hdr) const; /** * Read request body. From d9d79576f423cd9c5cef4547c7e3648dbb339460 Mon Sep 17 00:00:00 2001 From: Kostiantyn Stepaniuk Date: Mon, 20 Aug 2018 14:19:43 +0200 Subject: [PATCH 0081/1200] Preserve a format of RPC command definitions Currently RPC commands are formatted in a way that it's easy to read and that test/lint/check-rpc-mappings.py can parse it. To void breaking test/lint/check-rpc-mappings.py script by running clang-format, RPC command definitions should be disabled for clang-format. --- src/coins.h | 4 ++-- src/rpc/blockchain.cpp | 2 ++ src/rpc/client.cpp | 2 ++ src/rpc/mining.cpp | 2 ++ src/rpc/misc.cpp | 2 ++ src/rpc/net.cpp | 2 ++ src/rpc/rawtransaction.cpp | 2 ++ src/rpc/server.cpp | 2 ++ src/wallet/rpcwallet.cpp | 2 ++ 9 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/coins.h b/src/coins.h index 41a422f485..3867a37b39 100644 --- a/src/coins.h +++ b/src/coins.h @@ -285,8 +285,8 @@ class CCoinsViewCache : public CCoinsViewBacked * Note that lightweight clients may not know anything besides the hash of previous transactions, * so may not be able to calculate this. * - * @param[in] tx transaction for which we are checking input total - * @return Sum of value of all inputs (scriptSigs) + * @param[in] tx transaction for which we are checking input total + * @return Sum of value of all inputs (scriptSigs) */ CAmount GetValueIn(const CTransaction& tx) const; diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 51bc218d39..9bc955542f 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -2179,6 +2179,7 @@ UniValue scantxoutset(const JSONRPCRequest& request) return result; } +// clang-format off static const CRPCCommand commands[] = { // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- @@ -2214,6 +2215,7 @@ static const CRPCCommand commands[] = { "hidden", "waitforblockheight", &waitforblockheight, {"height","timeout"} }, { "hidden", "syncwithvalidationinterfacequeue", &syncwithvalidationinterfacequeue, {} }, }; +// clang-format on void RegisterBlockchainRPCCommands(CRPCTable &t) { diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 6738b206c9..7fb8eb9255 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -18,6 +18,7 @@ class CRPCConvertParam std::string paramName; //!< parameter name }; +// clang-format off /** * Specify a (method, idx, name) here if the argument is a non-string RPC * argument and needs to be converted from JSON. @@ -174,6 +175,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "rescanblockchain", 1, "stop_height"}, { "createwallet", 1, "disable_private_keys"}, }; +// clang-format on class CRPCConvertTable { diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 623b0bd86a..a69feb37ad 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -968,6 +968,7 @@ static UniValue estimaterawfee(const JSONRPCRequest& request) return result; } +// clang-format off static const CRPCCommand commands[] = { // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- @@ -986,6 +987,7 @@ static const CRPCCommand commands[] = { "hidden", "estimaterawfee", &estimaterawfee, {"conf_target", "threshold"} }, }; +// clang-format on void RegisterMiningRPCCommands(CRPCTable &t) { diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 40418545c1..d8a5a921ea 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -456,6 +456,7 @@ static UniValue echo(const JSONRPCRequest& request) return request.params; } +// clang-format off static const CRPCCommand commands[] = { // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- @@ -471,6 +472,7 @@ static const CRPCCommand commands[] = { "hidden", "echo", &echo, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}}, { "hidden", "echojson", &echo, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}}, }; +// clang-format on void RegisterMiscRPCCommands(CRPCTable &t) { diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 610a1fee6f..c6efb63d65 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -624,6 +624,7 @@ static UniValue setnetworkactive(const JSONRPCRequest& request) return g_connman->GetNetworkActive(); } +// clang-format off static const CRPCCommand commands[] = { // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- @@ -640,6 +641,7 @@ static const CRPCCommand commands[] = { "network", "clearbanned", &clearbanned, {} }, { "network", "setnetworkactive", &setnetworkactive, {"state"} }, }; +// clang-format on void RegisterNetRPCCommands(CRPCTable &t) { diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 608a1b5da2..0df0f97200 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -1801,6 +1801,7 @@ UniValue converttopsbt(const JSONRPCRequest& request) return EncodeBase64((unsigned char*)ssTx.data(), ssTx.size()); } +// clang-format off static const CRPCCommand commands[] = { // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- @@ -1822,6 +1823,7 @@ static const CRPCCommand commands[] = { "blockchain", "gettxoutproof", &gettxoutproof, {"txids", "blockhash"} }, { "blockchain", "verifytxoutproof", &verifytxoutproof, {"proof"} }, }; +// clang-format on void RegisterRawTransactionRPCCommands(CRPCTable &t) { diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index e46bf2f765..367a68475c 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -255,6 +255,7 @@ static UniValue uptime(const JSONRPCRequest& jsonRequest) return GetTime() - GetStartupTime(); } +// clang-format off /** * Call Table */ @@ -266,6 +267,7 @@ static const CRPCCommand vRPCCommands[] = { "control", "stop", &stop, {} }, { "control", "uptime", &uptime, {} }, }; +// clang-format on CRPCTable::CRPCTable() { diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 281fd46146..65b3235a89 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4760,6 +4760,7 @@ UniValue importprunedfunds(const JSONRPCRequest& request); UniValue removeprunedfunds(const JSONRPCRequest& request); UniValue importmulti(const JSONRPCRequest& request); +// clang-format off static const CRPCCommand commands[] = { // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- @@ -4834,6 +4835,7 @@ static const CRPCCommand commands[] = { "generating", "generate", &generate, {"nblocks","maxtries"} }, }; +// clang-format on void RegisterWalletRPCCommands(CRPCTable &t) { From 1f18d7b591ffcc8bb9422a9b728bd9a0d8da6a2a Mon Sep 17 00:00:00 2001 From: Gregory Sanders Date: Tue, 14 Aug 2018 21:12:33 -0400 Subject: [PATCH 0082/1200] walletcreatefundedpsbt: remove duplicate replaceable arg --- src/rpc/client.cpp | 5 ++--- src/wallet/rpcwallet.cpp | 16 +++++++--------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 6738b206c9..c7f3e38ac0 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -113,9 +113,8 @@ static const CRPCConvertParam vRPCConvertParams[] = { "walletcreatefundedpsbt", 0, "inputs" }, { "walletcreatefundedpsbt", 1, "outputs" }, { "walletcreatefundedpsbt", 2, "locktime" }, - { "walletcreatefundedpsbt", 3, "replaceable" }, - { "walletcreatefundedpsbt", 4, "options" }, - { "walletcreatefundedpsbt", 5, "bip32derivs" }, + { "walletcreatefundedpsbt", 3, "options" }, + { "walletcreatefundedpsbt", 4, "bip32derivs" }, { "walletprocesspsbt", 1, "sign" }, { "walletprocesspsbt", 3, "bip32derivs" }, { "createpsbt", 0, "inputs" }, diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 281fd46146..03c1a0f62c 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4643,7 +4643,7 @@ UniValue walletcreatefundedpsbt(const JSONRPCRequest& request) return NullUniValue; } - if (request.fHelp || request.params.size() < 2 || request.params.size() > 6) + if (request.fHelp || request.params.size() < 2 || request.params.size() > 5) throw std::runtime_error( "walletcreatefundedpsbt [{\"txid\":\"id\",\"vout\":n},...] [{\"address\":amount},{\"data\":\"hex\"},...] ( locktime ) ( replaceable ) ( options bip32derivs )\n" "\nCreates and funds a transaction in the Partially Signed Transaction format. Inputs will be added if supplied inputs are not enough\n" @@ -4670,9 +4670,8 @@ UniValue walletcreatefundedpsbt(const JSONRPCRequest& request) " accepted as second parameter.\n" " ]\n" "3. locktime (numeric, optional, default=0) Raw locktime. Non-0 value also locktime-activates inputs\n" - "4. replaceable (boolean, optional, default=false) Marks this transaction as BIP125 replaceable.\n" " Allows this transaction to be replaced by a transaction with higher fees. If provided, it is an error if explicit sequence numbers are incompatible.\n" - "5. options (object, optional)\n" + "4. options (object, optional)\n" " {\n" " \"changeAddress\" (string, optional, default pool address) The bitcoin address to receive the change\n" " \"changePosition\" (numeric, optional, default random) The index of the change output\n" @@ -4694,7 +4693,7 @@ UniValue walletcreatefundedpsbt(const JSONRPCRequest& request) " \"ECONOMICAL\"\n" " \"CONSERVATIVE\"\n" " }\n" - "6. bip32derivs (boolean, optiona, default=false) If true, includes the BIP 32 derivation paths for public keys if we know them\n" + "5. bip32derivs (boolean, optiona, default=false) If true, includes the BIP 32 derivation paths for public keys if we know them\n" "\nResult:\n" "{\n" " \"psbt\": \"value\", (string) The resulting raw transaction (base64-encoded string)\n" @@ -4710,15 +4709,14 @@ UniValue walletcreatefundedpsbt(const JSONRPCRequest& request) UniValue::VARR, UniValueType(), // ARR or OBJ, checked later UniValue::VNUM, - UniValue::VBOOL, UniValue::VOBJ }, true ); CAmount fee; int change_position; - CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], request.params[3]); - FundTransaction(pwallet, rawTx, fee, change_position, request.params[4]); + CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], request.params[3]["replaceable"]); + FundTransaction(pwallet, rawTx, fee, change_position, request.params[3]); // Make a blank psbt PartiallySignedTransaction psbtx; @@ -4735,7 +4733,7 @@ UniValue walletcreatefundedpsbt(const JSONRPCRequest& request) const CTransaction txConst(*psbtx.tx); // Fill transaction with out data but don't sign - bool bip32derivs = request.params[5].isNull() ? false : request.params[5].get_bool(); + bool bip32derivs = request.params[4].isNull() ? false : request.params[5].get_bool(); FillPSBT(pwallet, psbtx, &txConst, 1, false, bip32derivs); // Serialize the PSBT @@ -4765,7 +4763,7 @@ static const CRPCCommand commands[] = // --------------------- ------------------------ ----------------------- ---------- { "rawtransactions", "fundrawtransaction", &fundrawtransaction, {"hexstring","options","iswitness"} }, { "wallet", "walletprocesspsbt", &walletprocesspsbt, {"psbt","sign","sighashtype","bip32derivs"} }, - { "wallet", "walletcreatefundedpsbt", &walletcreatefundedpsbt, {"inputs","outputs","locktime","replaceable","options","bip32derivs"} }, + { "wallet", "walletcreatefundedpsbt", &walletcreatefundedpsbt, {"inputs","outputs","locktime","options","bip32derivs"} }, { "hidden", "resendwallettransactions", &resendwallettransactions, {} }, { "wallet", "abandontransaction", &abandontransaction, {"txid"} }, { "wallet", "abortrescan", &abortrescan, {} }, From 1f0c4282e961baea85d5f74d7493bd7459784391 Mon Sep 17 00:00:00 2001 From: Gregory Sanders Date: Tue, 14 Aug 2018 21:52:16 -0400 Subject: [PATCH 0083/1200] QA: add basic walletcreatefunded optional arg test --- test/functional/rpc_psbt.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/test/functional/rpc_psbt.py b/test/functional/rpc_psbt.py index 99c4131d61..f847a01e59 100755 --- a/test/functional/rpc_psbt.py +++ b/test/functional/rpc_psbt.py @@ -11,6 +11,8 @@ import json import os +MAX_BIP125_RBF_SEQUENCE = 0xfffffffd + # Create one-input, one-output, no-fee transaction: class PSBTTest(BitcoinTestFramework): @@ -135,6 +137,33 @@ def run_test(self): self.nodes[0].generate(6) self.sync_all() + # Test additional args in walletcreatepsbt + # Make sure both pre-included and funded inputs + # have the correct sequence numbers based on + # replaceable arg + block_height = self.nodes[0].getblockcount() + unspent = self.nodes[0].listunspent()[0] + psbtx_info = self.nodes[0].walletcreatefundedpsbt([{"txid":unspent["txid"], "vout":unspent["vout"]}], [{self.nodes[2].getnewaddress():unspent["amount"]+1}], block_height+2, {"replaceable":True}) + decoded_psbt = self.nodes[0].decodepsbt(psbtx_info["psbt"]) + for tx_in in decoded_psbt["tx"]["vin"]: + assert_equal(tx_in["sequence"], MAX_BIP125_RBF_SEQUENCE) + assert_equal(decoded_psbt["tx"]["locktime"], block_height+2) + + # Same construction with only locktime set + psbtx_info = self.nodes[0].walletcreatefundedpsbt([{"txid":unspent["txid"], "vout":unspent["vout"]}], [{self.nodes[2].getnewaddress():unspent["amount"]+1}], block_height) + decoded_psbt = self.nodes[0].decodepsbt(psbtx_info["psbt"]) + for tx_in in decoded_psbt["tx"]["vin"]: + assert tx_in["sequence"] > MAX_BIP125_RBF_SEQUENCE + assert_equal(decoded_psbt["tx"]["locktime"], block_height) + + # Same construction without optional arguments + psbtx_info = self.nodes[0].walletcreatefundedpsbt([{"txid":unspent["txid"], "vout":unspent["vout"]}], [{self.nodes[2].getnewaddress():unspent["amount"]+1}]) + decoded_psbt = self.nodes[0].decodepsbt(psbtx_info["psbt"]) + for tx_in in decoded_psbt["tx"]["vin"]: + assert tx_in["sequence"] > MAX_BIP125_RBF_SEQUENCE + assert_equal(decoded_psbt["tx"]["locktime"], 0) + + # BIP 174 Test Vectors # Check that unknown values are just passed through From faaac5caaab4d5131040292f4ef2404074ad268b Mon Sep 17 00:00:00 2001 From: Gregory Sanders Date: Mon, 20 Aug 2018 12:57:06 -0400 Subject: [PATCH 0084/1200] RPCTypeCheck bip32derivs arg in walletcreatefunded --- src/wallet/rpcwallet.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 03c1a0f62c..0966334b82 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4709,7 +4709,8 @@ UniValue walletcreatefundedpsbt(const JSONRPCRequest& request) UniValue::VARR, UniValueType(), // ARR or OBJ, checked later UniValue::VNUM, - UniValue::VOBJ + UniValue::VOBJ, + UniValue::VBOOL }, true ); From a3197c5294df4711bab0ff6dcdd061ceab115c7d Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Mon, 20 Aug 2018 15:24:55 -0400 Subject: [PATCH 0085/1200] Disable wallet and address book Qt tests on macOS minimal platform macOS Qt minimal platform is frequently broken, and these are currently failing with Qt 5.11.1. The tests do pass when run on the full cocoa platform (with `test_bitcoin-qt -platform cocoa`). --- src/qt/test/addressbooktests.cpp | 12 ++++++++++++ src/qt/test/wallettests.cpp | 11 +++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/qt/test/addressbooktests.cpp b/src/qt/test/addressbooktests.cpp index c3d33c76d4..3525846044 100644 --- a/src/qt/test/addressbooktests.cpp +++ b/src/qt/test/addressbooktests.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -139,5 +140,16 @@ void TestAddAddressesToSendBook() void AddressBookTests::addressBookTests() { +#ifdef Q_OS_MAC + if (QApplication::platformName() == "minimal") { + // Disable for mac on "minimal" platform to avoid crashes inside the Qt + // framework when it tries to look up unimplemented cocoa functions, + // and fails to handle returned nulls + // (https://bugreports.qt.io/browse/QTBUG-49686). + QWARN("Skipping AddressBookTests on mac build with 'minimal' platform set due to Qt bugs. To run AppTests, invoke " + "with 'test_bitcoin-qt -platform cocoa' on mac, or else use a linux or windows build."); + return; + } +#endif TestAddAddressesToSendBook(); } diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp index c314dadde4..9598d64845 100644 --- a/src/qt/test/wallettests.cpp +++ b/src/qt/test/wallettests.cpp @@ -243,5 +243,16 @@ void TestGUI() void WalletTests::walletTests() { +#ifdef Q_OS_MAC + if (QApplication::platformName() == "minimal") { + // Disable for mac on "minimal" platform to avoid crashes inside the Qt + // framework when it tries to look up unimplemented cocoa functions, + // and fails to handle returned nulls + // (https://bugreports.qt.io/browse/QTBUG-49686). + QWARN("Skipping WalletTests on mac build with 'minimal' platform set due to Qt bugs. To run AppTests, invoke " + "with 'test_bitcoin-qt -platform cocoa' on mac, or else use a linux or windows build."); + return; + } +#endif TestGUI(); } From 317f2cb3f4499afbaa63e3cac80567744f12c95b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Barbosa?= Date: Mon, 20 Aug 2018 18:34:39 +0100 Subject: [PATCH 0086/1200] test: Check RPC settxfee errors --- test/functional/wallet_bumpfee.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/functional/wallet_bumpfee.py b/test/functional/wallet_bumpfee.py index dd95bb5e22..a49590df19 100755 --- a/test/functional/wallet_bumpfee.py +++ b/test/functional/wallet_bumpfee.py @@ -31,7 +31,7 @@ class BumpFeeTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 2 self.setup_clean_chain = True - self.extra_args = [["-deprecatedrpc=addwitnessaddress", "-walletrbf={}".format(i)] + self.extra_args = [["-deprecatedrpc=addwitnessaddress", "-walletrbf={}".format(i), "-mintxfee=0.00002"] for i in range(self.num_nodes)] def run_test(self): @@ -190,6 +190,8 @@ def test_dust_to_fee(rbf_node, dest_address): def test_settxfee(rbf_node, dest_address): + assert_raises_rpc_error(-8, "txfee cannot be less than min relay tx fee", rbf_node.settxfee, Decimal('0.000005')) + assert_raises_rpc_error(-8, "txfee cannot be less than wallet min fee", rbf_node.settxfee, Decimal('0.000015')) # check that bumpfee reacts correctly to the use of settxfee (paytxfee) rbfid = spend_one_input(rbf_node, dest_address) requested_feerate = Decimal("0.00025000") From f78558f1e39198779bdb17e2b0e256fb99ad4b28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Barbosa?= Date: Sun, 24 Jun 2018 16:18:22 +0100 Subject: [PATCH 0087/1200] qt: Use new Qt5 connect syntax --- src/qt/addressbookpage.cpp | 22 +++---- src/qt/askpassphrasedialog.cpp | 8 +-- src/qt/bitcoin.cpp | 39 ++++++------ src/qt/bitcoinamountfield.cpp | 6 +- src/qt/bitcoingui.cpp | 93 +++++++++++++++-------------- src/qt/bitcoingui.h | 10 ++-- src/qt/clientmodel.cpp | 2 +- src/qt/coincontroldialog.cpp | 40 ++++++------- src/qt/guiutil.cpp | 8 +-- src/qt/intro.cpp | 8 +-- src/qt/modaloverlay.cpp | 2 +- src/qt/optionsdialog.cpp | 46 +++++++------- src/qt/overviewpage.cpp | 14 ++--- src/qt/paymentserver.cpp | 13 ++-- src/qt/peertablemodel.cpp | 2 +- src/qt/qvalidatedlineedit.cpp | 2 +- src/qt/qvaluecombobox.cpp | 2 +- src/qt/receivecoinsdialog.cpp | 18 +++--- src/qt/receiverequestdialog.cpp | 8 +-- src/qt/recentrequeststablemodel.cpp | 2 +- src/qt/rpcconsole.cpp | 60 +++++++++---------- src/qt/rpcconsole.h | 3 +- src/qt/sendcoinsdialog.cpp | 64 ++++++++++---------- src/qt/sendcoinsentry.cpp | 14 ++--- src/qt/test/paymentservertests.cpp | 8 +-- src/qt/test/util.cpp | 2 +- src/qt/test/wallettests.cpp | 2 +- src/qt/trafficgraphwidget.cpp | 2 +- src/qt/transactiontablemodel.cpp | 2 +- src/qt/transactionview.cpp | 57 +++++++++--------- src/qt/walletframe.cpp | 6 +- src/qt/walletmodel.cpp | 2 +- src/qt/walletview.cpp | 41 +++++++------ 33 files changed, 304 insertions(+), 304 deletions(-) diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index e1d9b1addf..26bdf60d4a 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -85,7 +85,7 @@ AddressBookPage::AddressBookPage(const PlatformStyle *platformStyle, Mode _mode, case SendingTab: setWindowTitle(tr("Choose the address to send coins to")); break; case ReceivingTab: setWindowTitle(tr("Choose the address to receive coins with")); break; } - connect(ui->tableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(accept())); + connect(ui->tableView, &QTableView::doubleClicked, this, &QDialog::accept); ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); ui->tableView->setFocus(); ui->closeButton->setText(tr("C&hoose")); @@ -129,14 +129,14 @@ AddressBookPage::AddressBookPage(const PlatformStyle *platformStyle, Mode _mode, contextMenu->addSeparator(); // Connect signals for context menu actions - connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(on_copyAddress_clicked())); - connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(onCopyLabelAction())); - connect(editAction, SIGNAL(triggered()), this, SLOT(onEditAction())); - connect(deleteAction, SIGNAL(triggered()), this, SLOT(on_deleteAddress_clicked())); + connect(copyAddressAction, &QAction::triggered, this, &AddressBookPage::on_copyAddress_clicked); + connect(copyLabelAction, &QAction::triggered, this, &AddressBookPage::onCopyLabelAction); + connect(editAction, &QAction::triggered, this, &AddressBookPage::onEditAction); + connect(deleteAction, &QAction::triggered, this, &AddressBookPage::on_deleteAddress_clicked); - connect(ui->tableView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextualMenu(QPoint))); + connect(ui->tableView, &QWidget::customContextMenuRequested, this, &AddressBookPage::contextualMenu); - connect(ui->closeButton, SIGNAL(clicked()), this, SLOT(accept())); + connect(ui->closeButton, &QPushButton::clicked, this, &QDialog::accept); } AddressBookPage::~AddressBookPage() @@ -154,7 +154,7 @@ void AddressBookPage::setModel(AddressTableModel *_model) proxyModel = new AddressBookSortFilterProxyModel(type, this); proxyModel->setSourceModel(_model); - connect(ui->searchLineEdit, SIGNAL(textChanged(QString)), proxyModel, SLOT(setFilterWildcard(QString))); + connect(ui->searchLineEdit, &QLineEdit::textChanged, proxyModel, &QSortFilterProxyModel::setFilterWildcard); ui->tableView->setModel(proxyModel); ui->tableView->sortByColumn(0, Qt::AscendingOrder); @@ -163,11 +163,11 @@ void AddressBookPage::setModel(AddressTableModel *_model) ui->tableView->horizontalHeader()->setSectionResizeMode(AddressTableModel::Label, QHeaderView::Stretch); ui->tableView->horizontalHeader()->setSectionResizeMode(AddressTableModel::Address, QHeaderView::ResizeToContents); - connect(ui->tableView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), - this, SLOT(selectionChanged())); + connect(ui->tableView->selectionModel(), &QItemSelectionModel::selectionChanged, + this, &AddressBookPage::selectionChanged); // Select row for newly created address - connect(_model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(selectNewAddress(QModelIndex,int,int))); + connect(_model, &AddressTableModel::rowsInserted, this, &AddressBookPage::selectNewAddress); selectionChanged(); } diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index 812d2251e1..673f63a19b 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -70,10 +70,10 @@ AskPassphraseDialog::AskPassphraseDialog(Mode _mode, QWidget *parent) : break; } textChanged(); - connect(ui->toggleShowPasswordButton, SIGNAL(toggled(bool)), this, SLOT(toggleShowPassword(bool))); - connect(ui->passEdit1, SIGNAL(textChanged(QString)), this, SLOT(textChanged())); - connect(ui->passEdit2, SIGNAL(textChanged(QString)), this, SLOT(textChanged())); - connect(ui->passEdit3, SIGNAL(textChanged(QString)), this, SLOT(textChanged())); + connect(ui->toggleShowPasswordButton, &QPushButton::toggled, this, &AskPassphraseDialog::toggleShowPassword); + connect(ui->passEdit1, &QLineEdit::textChanged, this, &AskPassphraseDialog::textChanged); + connect(ui->passEdit2, &QLineEdit::textChanged, this, &AskPassphraseDialog::textChanged); + connect(ui->passEdit3, &QLineEdit::textChanged, this, &AskPassphraseDialog::textChanged); } AskPassphraseDialog::~AskPassphraseDialog() diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index d3ec67e441..85fb88d338 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -353,7 +353,7 @@ void BitcoinApplication::createWindow(const NetworkStyle *networkStyle) window = new BitcoinGUI(m_node, platformStyle, networkStyle, 0); pollShutdownTimer = new QTimer(window); - connect(pollShutdownTimer, SIGNAL(timeout()), window, SLOT(detectShutdown())); + connect(pollShutdownTimer, &QTimer::timeout, window, &BitcoinGUI::detectShutdown); } void BitcoinApplication::createSplashScreen(const NetworkStyle *networkStyle) @@ -362,8 +362,8 @@ void BitcoinApplication::createSplashScreen(const NetworkStyle *networkStyle) // We don't hold a direct pointer to the splash screen after creation, but the splash // screen will take care of deleting itself when slotFinish happens. splash->show(); - connect(this, SIGNAL(splashFinished(QWidget*)), splash, SLOT(slotFinish(QWidget*))); - connect(this, SIGNAL(requestedShutdown()), splash, SLOT(close())); + connect(this, &BitcoinApplication::splashFinished, splash, &SplashScreen::slotFinish); + connect(this, &BitcoinApplication::requestedShutdown, splash, &QWidget::close); } void BitcoinApplication::startThread() @@ -375,14 +375,14 @@ void BitcoinApplication::startThread() executor->moveToThread(coreThread); /* communication to and from thread */ - connect(executor, SIGNAL(initializeResult(bool)), this, SLOT(initializeResult(bool))); - connect(executor, SIGNAL(shutdownResult()), this, SLOT(shutdownResult())); - connect(executor, SIGNAL(runawayException(QString)), this, SLOT(handleRunawayException(QString))); - connect(this, SIGNAL(requestedInitialize()), executor, SLOT(initialize())); - connect(this, SIGNAL(requestedShutdown()), executor, SLOT(shutdown())); + connect(executor, &BitcoinCore::initializeResult, this, &BitcoinApplication::initializeResult); + connect(executor, &BitcoinCore::shutdownResult, this, &BitcoinApplication::shutdownResult); + connect(executor, &BitcoinCore::runawayException, this, &BitcoinApplication::handleRunawayException); + connect(this, &BitcoinApplication::requestedInitialize, executor, &BitcoinCore::initialize); + connect(this, &BitcoinApplication::requestedShutdown, executor, &BitcoinCore::shutdown); /* make sure executor object is deleted in its own thread */ - connect(this, SIGNAL(stopThread()), executor, SLOT(deleteLater())); - connect(this, SIGNAL(stopThread()), coreThread, SLOT(quit())); + connect(this, &BitcoinApplication::stopThread, executor, &QObject::deleteLater); + connect(this, &BitcoinApplication::stopThread, coreThread, &QThread::quit); coreThread->start(); } @@ -442,9 +442,9 @@ void BitcoinApplication::addWallet(WalletModel* walletModel) window->setCurrentWallet(walletModel->getWalletName()); } - connect(walletModel, SIGNAL(coinsSent(WalletModel*, SendCoinsRecipient, QByteArray)), - paymentServer, SLOT(fetchPaymentACK(WalletModel*, const SendCoinsRecipient&, QByteArray))); - connect(walletModel, SIGNAL(unload()), this, SLOT(removeWallet())); + connect(walletModel, &WalletModel::coinsSent, + paymentServer, &PaymentServer::fetchPaymentACK); + connect(walletModel, &WalletModel::unload, this, &BitcoinApplication::removeWallet); m_wallet_models.push_back(walletModel); #endif @@ -504,13 +504,12 @@ void BitcoinApplication::initializeResult(bool success) #ifdef ENABLE_WALLET // Now that initialization/startup is done, process any command-line // bitcoin: URIs or payment requests: - connect(paymentServer, SIGNAL(receivedPaymentRequest(SendCoinsRecipient)), - window, SLOT(handlePaymentRequest(SendCoinsRecipient))); - connect(window, SIGNAL(receivedURI(QString)), - paymentServer, SLOT(handleURIOrFile(QString))); - connect(paymentServer, SIGNAL(message(QString,QString,unsigned int)), - window, SLOT(message(QString,QString,unsigned int))); - QTimer::singleShot(100, paymentServer, SLOT(uiReady())); + connect(paymentServer, &PaymentServer::receivedPaymentRequest, window, &BitcoinGUI::handlePaymentRequest); + connect(window, &BitcoinGUI::receivedURI, paymentServer, &PaymentServer::handleURIOrFile); + connect(paymentServer, &PaymentServer::message, [this](const QString& title, const QString& message, unsigned int style) { + window->message(title, message, style); + }); + QTimer::singleShot(100, paymentServer, &PaymentServer::uiReady); #endif pollShutdownTimer->start(200); } else { diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp index 6726019a3f..b68f3a439b 100644 --- a/src/qt/bitcoinamountfield.cpp +++ b/src/qt/bitcoinamountfield.cpp @@ -29,7 +29,7 @@ class AmountSpinBox: public QAbstractSpinBox { setAlignment(Qt::AlignRight); - connect(lineEdit(), SIGNAL(textEdited(QString)), this, SIGNAL(valueChanged())); + connect(lineEdit(), &QLineEdit::textEdited, this, &AmountSpinBox::valueChanged); } QValidator::State validate(QString &text, int &pos) const @@ -213,8 +213,8 @@ BitcoinAmountField::BitcoinAmountField(QWidget *parent) : setFocusProxy(amount); // If one if the widgets changes, the combined content changes as well - connect(amount, SIGNAL(valueChanged()), this, SIGNAL(valueChanged())); - connect(unit, SIGNAL(currentIndexChanged(int)), this, SLOT(unitChanged(int))); + connect(amount, &AmountSpinBox::valueChanged, this, &BitcoinAmountField::valueChanged); + connect(unit, static_cast(&QComboBox::currentIndexChanged), this, &BitcoinAmountField::unitChanged); // Set default based on configuration unitChanged(unit->currentIndex()); diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index ff0641dcf5..cefa9004ed 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -203,9 +203,9 @@ BitcoinGUI::BitcoinGUI(interfaces::Node& node, const PlatformStyle *_platformSty modalOverlay = new ModalOverlay(this->centralWidget()); #ifdef ENABLE_WALLET if(enableWallet) { - connect(walletFrame, SIGNAL(requestedSyncWarningInfo()), this, SLOT(showModalOverlay())); - connect(labelBlocksIcon, SIGNAL(clicked(QPoint)), this, SLOT(showModalOverlay())); - connect(progressBar, SIGNAL(clicked(QPoint)), this, SLOT(showModalOverlay())); + connect(walletFrame, &WalletFrame::requestedSyncWarningInfo, this, &BitcoinGUI::showModalOverlay); + connect(labelBlocksIcon, &GUIUtil::ClickableLabel::clicked, this, &BitcoinGUI::showModalOverlay); + connect(progressBar, &GUIUtil::ClickableProgressBar::clicked, this, &BitcoinGUI::showModalOverlay); } #endif } @@ -270,18 +270,18 @@ void BitcoinGUI::createActions() #ifdef ENABLE_WALLET // These showNormalIfMinimized are needed because Send Coins and Receive Coins // can be triggered from the tray menu, and need to show the GUI to be useful. - connect(overviewAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); - connect(overviewAction, SIGNAL(triggered()), this, SLOT(gotoOverviewPage())); - connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); - connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage())); - connect(sendCoinsMenuAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); - connect(sendCoinsMenuAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage())); - connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); - connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage())); - connect(receiveCoinsMenuAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); - connect(receiveCoinsMenuAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage())); - connect(historyAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); - connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage())); + connect(overviewAction, &QAction::triggered, this, static_cast(&BitcoinGUI::showNormalIfMinimized)); + connect(overviewAction, &QAction::triggered, this, &BitcoinGUI::gotoOverviewPage); + connect(sendCoinsAction, &QAction::triggered, this, static_cast(&BitcoinGUI::showNormalIfMinimized)); + connect(sendCoinsAction, &QAction::triggered, [this]{ gotoSendCoinsPage(); }); + connect(sendCoinsMenuAction, &QAction::triggered, this, static_cast(&BitcoinGUI::showNormalIfMinimized)); + connect(sendCoinsMenuAction, &QAction::triggered, [this]{ gotoSendCoinsPage(); }); + connect(receiveCoinsAction, &QAction::triggered, this, static_cast(&BitcoinGUI::showNormalIfMinimized)); + connect(receiveCoinsAction, &QAction::triggered, this, &BitcoinGUI::gotoReceiveCoinsPage); + connect(receiveCoinsMenuAction, &QAction::triggered, this, static_cast(&BitcoinGUI::showNormalIfMinimized)); + connect(receiveCoinsMenuAction, &QAction::triggered, this, &BitcoinGUI::gotoReceiveCoinsPage); + connect(historyAction, &QAction::triggered, this, static_cast(&BitcoinGUI::showNormalIfMinimized)); + connect(historyAction, &QAction::triggered, this, &BitcoinGUI::gotoHistoryPage); #endif // ENABLE_WALLET quitAction = new QAction(platformStyle->TextColorIcon(":/icons/quit"), tr("E&xit"), this); @@ -331,32 +331,32 @@ void BitcoinGUI::createActions() showHelpMessageAction->setMenuRole(QAction::NoRole); showHelpMessageAction->setStatusTip(tr("Show the %1 help message to get a list with possible Bitcoin command-line options").arg(tr(PACKAGE_NAME))); - connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); - connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutClicked())); - connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt())); - connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked())); - connect(toggleHideAction, SIGNAL(triggered()), this, SLOT(toggleHidden())); - connect(showHelpMessageAction, SIGNAL(triggered()), this, SLOT(showHelpMessageClicked())); - connect(openRPCConsoleAction, SIGNAL(triggered()), this, SLOT(showDebugWindow())); + connect(quitAction, &QAction::triggered, qApp, QApplication::quit); + connect(aboutAction, &QAction::triggered, this, &BitcoinGUI::aboutClicked); + connect(aboutQtAction, &QAction::triggered, qApp, QApplication::aboutQt); + connect(optionsAction, &QAction::triggered, this, &BitcoinGUI::optionsClicked); + connect(toggleHideAction, &QAction::triggered, this, &BitcoinGUI::toggleHidden); + connect(showHelpMessageAction, &QAction::triggered, this, &BitcoinGUI::showHelpMessageClicked); + connect(openRPCConsoleAction, &QAction::triggered, this, &BitcoinGUI::showDebugWindow); // prevents an open debug window from becoming stuck/unusable on client shutdown - connect(quitAction, SIGNAL(triggered()), rpcConsole, SLOT(hide())); + connect(quitAction, &QAction::triggered, rpcConsole, &QWidget::hide); #ifdef ENABLE_WALLET if(walletFrame) { - connect(encryptWalletAction, SIGNAL(triggered(bool)), walletFrame, SLOT(encryptWallet(bool))); - connect(backupWalletAction, SIGNAL(triggered()), walletFrame, SLOT(backupWallet())); - connect(changePassphraseAction, SIGNAL(triggered()), walletFrame, SLOT(changePassphrase())); - connect(signMessageAction, SIGNAL(triggered()), this, SLOT(gotoSignMessageTab())); - connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(gotoVerifyMessageTab())); - connect(usedSendingAddressesAction, SIGNAL(triggered()), walletFrame, SLOT(usedSendingAddresses())); - connect(usedReceivingAddressesAction, SIGNAL(triggered()), walletFrame, SLOT(usedReceivingAddresses())); - connect(openAction, SIGNAL(triggered()), this, SLOT(openClicked())); + connect(encryptWalletAction, &QAction::triggered, walletFrame, &WalletFrame::encryptWallet); + connect(backupWalletAction, &QAction::triggered, walletFrame, &WalletFrame::backupWallet); + connect(changePassphraseAction, &QAction::triggered, walletFrame, &WalletFrame::changePassphrase); + connect(signMessageAction, &QAction::triggered, [this]{ gotoSignMessageTab(); }); + connect(verifyMessageAction, &QAction::triggered, [this]{ gotoVerifyMessageTab(); }); + connect(usedSendingAddressesAction, &QAction::triggered, walletFrame, &WalletFrame::usedSendingAddresses); + connect(usedReceivingAddressesAction, &QAction::triggered, walletFrame, &WalletFrame::usedReceivingAddresses); + connect(openAction, &QAction::triggered, this, &BitcoinGUI::openClicked); } #endif // ENABLE_WALLET - new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_C), this, SLOT(showDebugWindowActivateConsole())); - new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_D), this, SLOT(showDebugWindow())); + connect(new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_C), this), &QShortcut::activated, this, &BitcoinGUI::showDebugWindowActivateConsole); + connect(new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_D), this), &QShortcut::activated, this, &BitcoinGUI::showDebugWindow); } void BitcoinGUI::createMenuBar() @@ -425,7 +425,7 @@ void BitcoinGUI::createToolBars() toolbar->addWidget(spacer); m_wallet_selector = new QComboBox(); - connect(m_wallet_selector, SIGNAL(currentIndexChanged(int)), this, SLOT(setCurrentWalletBySelectorIndex(int))); + connect(m_wallet_selector, static_cast(&QComboBox::currentIndexChanged), this, &BitcoinGUI::setCurrentWalletBySelectorIndex); m_wallet_selector_label = new QLabel(); m_wallet_selector_label->setText(tr("Wallet:") + " "); @@ -451,18 +451,20 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel) // Keep up to date with client updateNetworkState(); - connect(_clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int))); - connect(_clientModel, SIGNAL(networkActiveChanged(bool)), this, SLOT(setNetworkActive(bool))); + connect(_clientModel, &ClientModel::numConnectionsChanged, this, &BitcoinGUI::setNumConnections); + connect(_clientModel, &ClientModel::networkActiveChanged, this, &BitcoinGUI::setNetworkActive); modalOverlay->setKnownBestHeight(_clientModel->getHeaderTipHeight(), QDateTime::fromTime_t(_clientModel->getHeaderTipTime())); setNumBlocks(m_node.getNumBlocks(), QDateTime::fromTime_t(m_node.getLastBlockTime()), m_node.getVerificationProgress(), false); - connect(_clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(setNumBlocks(int,QDateTime,double,bool))); + connect(_clientModel, &ClientModel::numBlocksChanged, this, &BitcoinGUI::setNumBlocks); // Receive and report messages from client model - connect(_clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int))); + connect(_clientModel, &ClientModel::message, [this](const QString &title, const QString &message, unsigned int style){ + this->message(title, message, style); + }); // Show progress dialog - connect(_clientModel, SIGNAL(showProgress(QString,int)), this, SLOT(showProgress(QString,int))); + connect(_clientModel, &ClientModel::showProgress, this, &BitcoinGUI::showProgress); rpcConsole->setClientModel(_clientModel); @@ -480,7 +482,7 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel) if(optionsModel) { // be aware of the tray icon disable state change reported by the OptionsModel object. - connect(optionsModel,SIGNAL(hideTrayIconChanged(bool)),this,SLOT(setTrayIconVisible(bool))); + connect(optionsModel, &OptionsModel::hideTrayIconChanged, this, &BitcoinGUI::setTrayIconVisible); // initialize the disable state of the tray icon with the current value in the model. setTrayIconVisible(optionsModel->getHideTrayIcon()); @@ -601,8 +603,7 @@ void BitcoinGUI::createTrayIconMenu() trayIconMenu = new QMenu(this); trayIcon->setContextMenu(trayIconMenu); - connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), - this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason))); + connect(trayIcon, &QSystemTrayIcon::activated, this, &BitcoinGUI::trayIconActivated); #else // Note: On Mac, the dock icon is used to provide the tray's functionality. MacDockIconHandler *dockIconHandler = MacDockIconHandler::instance(); @@ -956,12 +957,12 @@ void BitcoinGUI::changeEvent(QEvent *e) QWindowStateChangeEvent *wsevt = static_cast(e); if(!(wsevt->oldState() & Qt::WindowMinimized) && isMinimized()) { - QTimer::singleShot(0, this, SLOT(hide())); + QTimer::singleShot(0, this, &BitcoinGUI::hide); e->ignore(); } else if((wsevt->oldState() & Qt::WindowMinimized) && !isMinimized()) { - QTimer::singleShot(0, this, SLOT(show())); + QTimer::singleShot(0, this, &BitcoinGUI::show); e->ignore(); } } @@ -1276,7 +1277,7 @@ void UnitDisplayStatusBarControl::createContextMenu() menuAction->setData(QVariant(u)); menu->addAction(menuAction); } - connect(menu,SIGNAL(triggered(QAction*)),this,SLOT(onMenuSelection(QAction*))); + connect(menu, &QMenu::triggered, this, &UnitDisplayStatusBarControl::onMenuSelection); } /** Lets the control know about the Options Model (and its signals) */ @@ -1287,7 +1288,7 @@ void UnitDisplayStatusBarControl::setOptionsModel(OptionsModel *_optionsModel) this->optionsModel = _optionsModel; // be aware of a display unit change reported by the OptionsModel object. - connect(_optionsModel,SIGNAL(displayUnitChanged(int)),this,SLOT(updateDisplayUnit(int))); + connect(_optionsModel, &OptionsModel::displayUnitChanged, this, &UnitDisplayStatusBarControl::updateDisplayUnit); // initialize the display units label with the current value in the model. updateDisplayUnit(_optionsModel->getDisplayUnit()); diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 3a8ef3ad8c..61cd6f76cc 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -49,6 +49,7 @@ QT_END_NAMESPACE namespace GUIUtil { class ClickableLabel; +class ClickableProgressBar; } /** @@ -101,9 +102,9 @@ class BitcoinGUI : public QMainWindow QLabel* labelWalletHDStatusIcon = nullptr; GUIUtil::ClickableLabel* labelProxyIcon = nullptr; GUIUtil::ClickableLabel* connectionsControl = nullptr; - QLabel* labelBlocksIcon = nullptr; + GUIUtil::ClickableLabel* labelBlocksIcon = nullptr; QLabel* progressBarLabel = nullptr; - QProgressBar* progressBar = nullptr; + GUIUtil::ClickableProgressBar* progressBar = nullptr; QProgressDialog* progressDialog = nullptr; QMenuBar* appMenuBar = nullptr; @@ -227,7 +228,7 @@ public Q_SLOTS: /** Set the proxy-enabled icon as shown in the UI. */ void updateProxyIcon(); -private Q_SLOTS: +public Q_SLOTS: #ifdef ENABLE_WALLET /** Switch to overview (home) page */ void gotoOverviewPage(); @@ -262,7 +263,8 @@ private Q_SLOTS: #endif /** Show window if hidden, unminimize when minimized, rise when obscured or show if hidden and fToggleHidden is true */ - void showNormalIfMinimized(bool fToggleHidden = false); + void showNormalIfMinimized() { showNormalIfMinimized(false); } + void showNormalIfMinimized(bool fToggleHidden); /** Simply calls showNormalIfMinimized(true) for use in SLOT() macro */ void toggleHidden(); diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 7154ac14be..b2cf4b6399 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -44,7 +44,7 @@ ClientModel::ClientModel(interfaces::Node& node, OptionsModel *_optionsModel, QO peerTableModel = new PeerTableModel(m_node, this); banTableModel = new BanTableModel(m_node, this); pollTimer = new QTimer(this); - connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer())); + connect(pollTimer, &QTimer::timeout, this, &ClientModel::updateTimer); pollTimer->start(MODEL_UPDATE_DELAY); subscribeToCoreSignals(); diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index ca3598334d..68330c51fa 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -68,13 +68,13 @@ CoinControlDialog::CoinControlDialog(const PlatformStyle *_platformStyle, QWidge contextMenu->addAction(unlockAction); // context menu signals - connect(ui->treeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showMenu(QPoint))); - connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(copyAddress())); - connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(copyLabel())); - connect(copyAmountAction, SIGNAL(triggered()), this, SLOT(copyAmount())); - connect(copyTransactionHashAction, SIGNAL(triggered()), this, SLOT(copyTransactionHash())); - connect(lockAction, SIGNAL(triggered()), this, SLOT(lockCoin())); - connect(unlockAction, SIGNAL(triggered()), this, SLOT(unlockCoin())); + connect(ui->treeWidget, &QWidget::customContextMenuRequested, this, &CoinControlDialog::showMenu); + connect(copyAddressAction, &QAction::triggered, this, &CoinControlDialog::copyAddress); + connect(copyLabelAction, &QAction::triggered, this, &CoinControlDialog::copyLabel); + connect(copyAmountAction, &QAction::triggered, this, &CoinControlDialog::copyAmount); + connect(copyTransactionHashAction, &QAction::triggered, this, &CoinControlDialog::copyTransactionHash); + connect(lockAction, &QAction::triggered, this, &CoinControlDialog::lockCoin); + connect(unlockAction, &QAction::triggered, this, &CoinControlDialog::unlockCoin); // clipboard actions QAction *clipboardQuantityAction = new QAction(tr("Copy quantity"), this); @@ -85,13 +85,13 @@ CoinControlDialog::CoinControlDialog(const PlatformStyle *_platformStyle, QWidge QAction *clipboardLowOutputAction = new QAction(tr("Copy dust"), this); QAction *clipboardChangeAction = new QAction(tr("Copy change"), this); - connect(clipboardQuantityAction, SIGNAL(triggered()), this, SLOT(clipboardQuantity())); - connect(clipboardAmountAction, SIGNAL(triggered()), this, SLOT(clipboardAmount())); - connect(clipboardFeeAction, SIGNAL(triggered()), this, SLOT(clipboardFee())); - connect(clipboardAfterFeeAction, SIGNAL(triggered()), this, SLOT(clipboardAfterFee())); - connect(clipboardBytesAction, SIGNAL(triggered()), this, SLOT(clipboardBytes())); - connect(clipboardLowOutputAction, SIGNAL(triggered()), this, SLOT(clipboardLowOutput())); - connect(clipboardChangeAction, SIGNAL(triggered()), this, SLOT(clipboardChange())); + connect(clipboardQuantityAction, &QAction::triggered, this, &CoinControlDialog::clipboardQuantity); + connect(clipboardAmountAction, &QAction::triggered, this, &CoinControlDialog::clipboardAmount); + connect(clipboardFeeAction, &QAction::triggered, this, &CoinControlDialog::clipboardFee); + connect(clipboardAfterFeeAction, &QAction::triggered, this, &CoinControlDialog::clipboardAfterFee); + connect(clipboardBytesAction, &QAction::triggered, this, &CoinControlDialog::clipboardBytes); + connect(clipboardLowOutputAction, &QAction::triggered, this, &CoinControlDialog::clipboardLowOutput); + connect(clipboardChangeAction, &QAction::triggered, this, &CoinControlDialog::clipboardChange); ui->labelCoinControlQuantity->addAction(clipboardQuantityAction); ui->labelCoinControlAmount->addAction(clipboardAmountAction); @@ -102,21 +102,21 @@ CoinControlDialog::CoinControlDialog(const PlatformStyle *_platformStyle, QWidge ui->labelCoinControlChange->addAction(clipboardChangeAction); // toggle tree/list mode - connect(ui->radioTreeMode, SIGNAL(toggled(bool)), this, SLOT(radioTreeMode(bool))); - connect(ui->radioListMode, SIGNAL(toggled(bool)), this, SLOT(radioListMode(bool))); + connect(ui->radioTreeMode, &QRadioButton::toggled, this, &CoinControlDialog::radioTreeMode); + connect(ui->radioListMode, &QRadioButton::toggled, this, &CoinControlDialog::radioListMode); // click on checkbox - connect(ui->treeWidget, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(viewItemChanged(QTreeWidgetItem*, int))); + connect(ui->treeWidget, &QTreeWidget::itemChanged, this, &CoinControlDialog::viewItemChanged); // click on header ui->treeWidget->header()->setSectionsClickable(true); - connect(ui->treeWidget->header(), SIGNAL(sectionClicked(int)), this, SLOT(headerSectionClicked(int))); + connect(ui->treeWidget->header(), &QHeaderView::sectionClicked, this, &CoinControlDialog::headerSectionClicked); // ok button - connect(ui->buttonBox, SIGNAL(clicked( QAbstractButton*)), this, SLOT(buttonBoxClicked(QAbstractButton*))); + connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &CoinControlDialog::buttonBoxClicked); // (un)select all - connect(ui->pushButtonSelectAll, SIGNAL(clicked()), this, SLOT(buttonSelectAllClicked())); + connect(ui->pushButtonSelectAll, &QPushButton::clicked, this, &CoinControlDialog::buttonSelectAllClicked); ui->treeWidget->setColumnWidth(COLUMN_CHECKBOX, 84); ui->treeWidget->setColumnWidth(COLUMN_AMOUNT, 110); diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index f8391b6303..bbf60d96fd 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -409,15 +409,15 @@ bool ToolTipToRichTextFilter::eventFilter(QObject *obj, QEvent *evt) void TableViewLastColumnResizingFixer::connectViewHeadersSignals() { - connect(tableView->horizontalHeader(), SIGNAL(sectionResized(int,int,int)), this, SLOT(on_sectionResized(int,int,int))); - connect(tableView->horizontalHeader(), SIGNAL(geometriesChanged()), this, SLOT(on_geometriesChanged())); + connect(tableView->horizontalHeader(), &QHeaderView::sectionResized, this, &TableViewLastColumnResizingFixer::on_sectionResized); + connect(tableView->horizontalHeader(), &QHeaderView::geometriesChanged, this, &TableViewLastColumnResizingFixer::on_geometriesChanged); } // We need to disconnect these while handling the resize events, otherwise we can enter infinite loops. void TableViewLastColumnResizingFixer::disconnectViewHeadersSignals() { - disconnect(tableView->horizontalHeader(), SIGNAL(sectionResized(int,int,int)), this, SLOT(on_sectionResized(int,int,int))); - disconnect(tableView->horizontalHeader(), SIGNAL(geometriesChanged()), this, SLOT(on_geometriesChanged())); + disconnect(tableView->horizontalHeader(), &QHeaderView::sectionResized, this, &TableViewLastColumnResizingFixer::on_sectionResized); + disconnect(tableView->horizontalHeader(), &QHeaderView::geometriesChanged, this, &TableViewLastColumnResizingFixer::on_geometriesChanged); } // Setup the resize mode, handles compatibility for Qt5 and below as the method signatures changed. diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index dbba3c1b3b..b19cc17a4d 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -303,11 +303,11 @@ void Intro::startThread() FreespaceChecker *executor = new FreespaceChecker(this); executor->moveToThread(thread); - connect(executor, SIGNAL(reply(int,QString,quint64)), this, SLOT(setStatus(int,QString,quint64))); - connect(this, SIGNAL(requestCheck()), executor, SLOT(check())); + connect(executor, &FreespaceChecker::reply, this, &Intro::setStatus); + connect(this, &Intro::requestCheck, executor, &FreespaceChecker::check); /* make sure executor object is deleted in its own thread */ - connect(this, SIGNAL(stopThread()), executor, SLOT(deleteLater())); - connect(this, SIGNAL(stopThread()), thread, SLOT(quit())); + connect(this, &Intro::stopThread, executor, &QObject::deleteLater); + connect(this, &Intro::stopThread, thread, &QThread::quit); thread->start(); } diff --git a/src/qt/modaloverlay.cpp b/src/qt/modaloverlay.cpp index dec9d78326..c5bedf007a 100644 --- a/src/qt/modaloverlay.cpp +++ b/src/qt/modaloverlay.cpp @@ -21,7 +21,7 @@ layerIsVisible(false), userClosed(false) { ui->setupUi(this); - connect(ui->closeButton, SIGNAL(clicked()), this, SLOT(closeClicked())); + connect(ui->closeButton, &QPushButton::clicked, this, &ModalOverlay::closeClicked); if (parent) { parent->installEventFilter(this); raise(); diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index d1477d362d..b51322394f 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -46,7 +46,7 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : ui->pruneWarning->setStyleSheet("QLabel { color: red; }"); ui->pruneSize->setEnabled(false); - connect(ui->prune, SIGNAL(toggled(bool)), ui->pruneSize, SLOT(setEnabled(bool))); + connect(ui->prune, &QPushButton::toggled, ui->pruneSize, &QWidget::setEnabled); /* Network elements init */ #ifndef USE_UPNP @@ -61,13 +61,13 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : ui->proxyPortTor->setEnabled(false); ui->proxyPortTor->setValidator(new QIntValidator(1, 65535, this)); - connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyIp, SLOT(setEnabled(bool))); - connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyPort, SLOT(setEnabled(bool))); - connect(ui->connectSocks, SIGNAL(toggled(bool)), this, SLOT(updateProxyValidationState())); + connect(ui->connectSocks, &QPushButton::toggled, ui->proxyIp, &QWidget::setEnabled); + connect(ui->connectSocks, &QPushButton::toggled, ui->proxyPort, &QWidget::setEnabled); + connect(ui->connectSocks, &QPushButton::toggled, this, &OptionsDialog::updateProxyValidationState); - connect(ui->connectSocksTor, SIGNAL(toggled(bool)), ui->proxyIpTor, SLOT(setEnabled(bool))); - connect(ui->connectSocksTor, SIGNAL(toggled(bool)), ui->proxyPortTor, SLOT(setEnabled(bool))); - connect(ui->connectSocksTor, SIGNAL(toggled(bool)), this, SLOT(updateProxyValidationState())); + connect(ui->connectSocksTor, &QPushButton::toggled, ui->proxyIpTor, &QWidget::setEnabled); + connect(ui->connectSocksTor, &QPushButton::toggled, ui->proxyPortTor, &QWidget::setEnabled); + connect(ui->connectSocksTor, &QPushButton::toggled, this, &OptionsDialog::updateProxyValidationState); /* Window elements init */ #ifdef Q_OS_MAC @@ -122,10 +122,10 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : /* setup/change UI elements when proxy IPs are invalid/valid */ ui->proxyIp->setCheckValidator(new ProxyAddressValidator(parent)); ui->proxyIpTor->setCheckValidator(new ProxyAddressValidator(parent)); - connect(ui->proxyIp, SIGNAL(validationDidChange(QValidatedLineEdit *)), this, SLOT(updateProxyValidationState())); - connect(ui->proxyIpTor, SIGNAL(validationDidChange(QValidatedLineEdit *)), this, SLOT(updateProxyValidationState())); - connect(ui->proxyPort, SIGNAL(textChanged(const QString&)), this, SLOT(updateProxyValidationState())); - connect(ui->proxyPortTor, SIGNAL(textChanged(const QString&)), this, SLOT(updateProxyValidationState())); + connect(ui->proxyIp, &QValidatedLineEdit::validationDidChange, this, &OptionsDialog::updateProxyValidationState); + connect(ui->proxyIpTor, &QValidatedLineEdit::validationDidChange, this, &OptionsDialog::updateProxyValidationState); + connect(ui->proxyPort, &QLineEdit::textChanged, this, &OptionsDialog::updateProxyValidationState); + connect(ui->proxyPortTor, &QLineEdit::textChanged, this, &OptionsDialog::updateProxyValidationState); } OptionsDialog::~OptionsDialog() @@ -158,20 +158,20 @@ void OptionsDialog::setModel(OptionsModel *_model) /* warn when one of the following settings changes by user action (placed here so init via mapper doesn't trigger them) */ /* Main */ - connect(ui->prune, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning())); - connect(ui->prune, SIGNAL(clicked(bool)), this, SLOT(togglePruneWarning(bool))); - connect(ui->pruneSize, SIGNAL(valueChanged(int)), this, SLOT(showRestartWarning())); - connect(ui->databaseCache, SIGNAL(valueChanged(int)), this, SLOT(showRestartWarning())); - connect(ui->threadsScriptVerif, SIGNAL(valueChanged(int)), this, SLOT(showRestartWarning())); + connect(ui->prune, &QCheckBox::clicked, this, &OptionsDialog::showRestartWarning); + connect(ui->prune, &QCheckBox::clicked, this, &OptionsDialog::togglePruneWarning); + connect(ui->pruneSize, static_cast(&QSpinBox::valueChanged), this, &OptionsDialog::showRestartWarning); + connect(ui->databaseCache, static_cast(&QSpinBox::valueChanged), this, &OptionsDialog::showRestartWarning); + connect(ui->threadsScriptVerif, static_cast(&QSpinBox::valueChanged), this, &OptionsDialog::showRestartWarning); /* Wallet */ - connect(ui->spendZeroConfChange, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning())); + connect(ui->spendZeroConfChange, &QCheckBox::clicked, this, &OptionsDialog::showRestartWarning); /* Network */ - connect(ui->allowIncoming, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning())); - connect(ui->connectSocks, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning())); - connect(ui->connectSocksTor, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning())); + connect(ui->allowIncoming, &QCheckBox::clicked, this, &OptionsDialog::showRestartWarning); + connect(ui->connectSocks, &QCheckBox::clicked, this, &OptionsDialog::showRestartWarning); + connect(ui->connectSocksTor, &QCheckBox::clicked, this, &OptionsDialog::showRestartWarning); /* Display */ - connect(ui->lang, SIGNAL(valueChanged()), this, SLOT(showRestartWarning())); - connect(ui->thirdPartyTxUrls, SIGNAL(textChanged(const QString &)), this, SLOT(showRestartWarning())); + connect(ui->lang, static_cast(&QValueComboBox::valueChanged), [this]{ showRestartWarning(); }); + connect(ui->thirdPartyTxUrls, &QLineEdit::textChanged, [this]{ showRestartWarning(); }); } void OptionsDialog::setCurrentTab(OptionsDialog::Tab tab) @@ -300,7 +300,7 @@ void OptionsDialog::showRestartWarning(bool fPersistent) ui->statusLabel->setText(tr("This change would require a client restart.")); // clear non-persistent status label after 10 seconds // Todo: should perhaps be a class attribute, if we extend the use of statusLabel - QTimer::singleShot(10000, this, SLOT(clearStatusLabel())); + QTimer::singleShot(10000, this, &OptionsDialog::clearStatusLabel); } } diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index ba47935196..1db9609979 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -133,12 +133,12 @@ OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent) ui->listTransactions->setMinimumHeight(NUM_ITEMS * (DECORATION_SIZE + 2)); ui->listTransactions->setAttribute(Qt::WA_MacShowFocusRect, false); - connect(ui->listTransactions, SIGNAL(clicked(QModelIndex)), this, SLOT(handleTransactionClicked(QModelIndex))); + connect(ui->listTransactions, &QListView::clicked, this, &OverviewPage::handleTransactionClicked); // start with displaying the "out of sync" warnings showOutOfSyncWarning(true); - connect(ui->labelWalletStatus, SIGNAL(clicked()), this, SLOT(handleOutOfSyncWarningClicks())); - connect(ui->labelTransactionsStatus, SIGNAL(clicked()), this, SLOT(handleOutOfSyncWarningClicks())); + connect(ui->labelWalletStatus, &QPushButton::clicked, this, &OverviewPage::handleOutOfSyncWarningClicks); + connect(ui->labelTransactionsStatus, &QPushButton::clicked, this, &OverviewPage::handleOutOfSyncWarningClicks); } void OverviewPage::handleTransactionClicked(const QModelIndex &index) @@ -201,7 +201,7 @@ void OverviewPage::setClientModel(ClientModel *model) if(model) { // Show warning if this is a prerelease version - connect(model, SIGNAL(alertsChanged(QString)), this, SLOT(updateAlerts(QString))); + connect(model, &ClientModel::alertsChanged, this, &OverviewPage::updateAlerts); updateAlerts(model->getStatusBarWarnings()); } } @@ -227,12 +227,12 @@ void OverviewPage::setWalletModel(WalletModel *model) interfaces::Wallet& wallet = model->wallet(); interfaces::WalletBalances balances = wallet.getBalances(); setBalance(balances); - connect(model, SIGNAL(balanceChanged(interfaces::WalletBalances)), this, SLOT(setBalance(interfaces::WalletBalances))); + connect(model, &WalletModel::balanceChanged, this, &OverviewPage::setBalance); - connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + connect(model->getOptionsModel(), &OptionsModel::displayUnitChanged, this, &OverviewPage::updateDisplayUnit); updateWatchOnlyLabels(wallet.haveWatchOnly()); - connect(model, SIGNAL(notifyWatchonlyChanged(bool)), this, SLOT(updateWatchOnlyLabels(bool))); + connect(model, &WalletModel::notifyWatchonlyChanged, this, &OverviewPage::updateWatchOnlyLabels); } // update the display unit, to not use the default ("BTC") diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 5bf2bb8a0e..bcafc8f859 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -318,8 +318,8 @@ PaymentServer::PaymentServer(QObject* parent, bool startLocalServer) : tr("Cannot start bitcoin: click-to-pay handler")); } else { - connect(uriServer, SIGNAL(newConnection()), this, SLOT(handleURIConnection())); - connect(this, SIGNAL(receivedPaymentACK(QString)), this, SLOT(handlePaymentACK(QString))); + connect(uriServer, &QLocalServer::newConnection, this, &PaymentServer::handleURIConnection); + connect(this, &PaymentServer::receivedPaymentACK, this, &PaymentServer::handlePaymentACK); } } } @@ -369,10 +369,8 @@ void PaymentServer::initNetManager() else qDebug() << "PaymentServer::initNetManager: No active proxy server found."; - connect(netManager, SIGNAL(finished(QNetworkReply*)), - this, SLOT(netRequestFinished(QNetworkReply*))); - connect(netManager, SIGNAL(sslErrors(QNetworkReply*, const QList &)), - this, SLOT(reportSslErrors(QNetworkReply*, const QList &))); + connect(netManager, &QNetworkAccessManager::finished, this, &PaymentServer::netRequestFinished); + connect(netManager, &QNetworkAccessManager::sslErrors, this, &PaymentServer::reportSslErrors); } void PaymentServer::uiReady() @@ -470,8 +468,7 @@ void PaymentServer::handleURIConnection() while (clientConnection->bytesAvailable() < (int)sizeof(quint32)) clientConnection->waitForReadyRead(); - connect(clientConnection, SIGNAL(disconnected()), - clientConnection, SLOT(deleteLater())); + connect(clientConnection, &QLocalSocket::disconnected, clientConnection, &QLocalSocket::deleteLater); QDataStream in(clientConnection); in.setVersion(QDataStream::Qt_4_0); diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp index 715fc8b5e0..59a751fb12 100644 --- a/src/qt/peertablemodel.cpp +++ b/src/qt/peertablemodel.cpp @@ -113,7 +113,7 @@ PeerTableModel::PeerTableModel(interfaces::Node& node, ClientModel *parent) : // set up timer for auto refresh timer = new QTimer(this); - connect(timer, SIGNAL(timeout()), SLOT(refresh())); + connect(timer, &QTimer::timeout, this, &PeerTableModel::refresh); timer->setInterval(MODEL_UPDATE_DELAY); // load initial data diff --git a/src/qt/qvalidatedlineedit.cpp b/src/qt/qvalidatedlineedit.cpp index de42490361..85c5a58a84 100644 --- a/src/qt/qvalidatedlineedit.cpp +++ b/src/qt/qvalidatedlineedit.cpp @@ -12,7 +12,7 @@ QValidatedLineEdit::QValidatedLineEdit(QWidget *parent) : valid(true), checkValidator(0) { - connect(this, SIGNAL(textChanged(QString)), this, SLOT(markValid())); + connect(this, &QValidatedLineEdit::textChanged, this, &QValidatedLineEdit::markValid); } void QValidatedLineEdit::setValid(bool _valid) diff --git a/src/qt/qvaluecombobox.cpp b/src/qt/qvaluecombobox.cpp index c2c0e84d65..76f94ecf85 100644 --- a/src/qt/qvaluecombobox.cpp +++ b/src/qt/qvaluecombobox.cpp @@ -7,7 +7,7 @@ QValueComboBox::QValueComboBox(QWidget *parent) : QComboBox(parent), role(Qt::UserRole) { - connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(handleSelectionChanged(int))); + connect(this, static_cast(&QComboBox::currentIndexChanged), this, &QValueComboBox::handleSelectionChanged); } QVariant QValueComboBox::value() const diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index 12de189229..a7cc5da19e 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -57,13 +57,13 @@ ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *_platformStyle, QWid contextMenu->addAction(copyAmountAction); // context menu signals - connect(ui->recentRequestsView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showMenu(QPoint))); - connect(copyURIAction, SIGNAL(triggered()), this, SLOT(copyURI())); - connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(copyLabel())); - connect(copyMessageAction, SIGNAL(triggered()), this, SLOT(copyMessage())); - connect(copyAmountAction, SIGNAL(triggered()), this, SLOT(copyAmount())); + connect(ui->recentRequestsView, &QWidget::customContextMenuRequested, this, &ReceiveCoinsDialog::showMenu); + connect(copyURIAction, &QAction::triggered, this, &ReceiveCoinsDialog::copyURI); + connect(copyLabelAction, &QAction::triggered, this, &ReceiveCoinsDialog::copyLabel); + connect(copyMessageAction, &QAction::triggered, this, &ReceiveCoinsDialog::copyMessage); + connect(copyAmountAction, &QAction::triggered, this, &ReceiveCoinsDialog::copyAmount); - connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear())); + connect(ui->clearButton, &QPushButton::clicked, this, &ReceiveCoinsDialog::clear); } void ReceiveCoinsDialog::setModel(WalletModel *_model) @@ -73,7 +73,7 @@ void ReceiveCoinsDialog::setModel(WalletModel *_model) if(_model && _model->getOptionsModel()) { _model->getRecentRequestsTableModel()->sort(RecentRequestsTableModel::Date, Qt::DescendingOrder); - connect(_model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + connect(_model->getOptionsModel(), &OptionsModel::displayUnitChanged, this, &ReceiveCoinsDialog::updateDisplayUnit); updateDisplayUnit(); QTableView* tableView = ui->recentRequestsView; @@ -89,8 +89,8 @@ void ReceiveCoinsDialog::setModel(WalletModel *_model) tableView->setColumnWidth(RecentRequestsTableModel::Amount, AMOUNT_MINIMUM_COLUMN_WIDTH); connect(tableView->selectionModel(), - SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, - SLOT(recentRequestsView_selectionChanged(QItemSelection, QItemSelection))); + &QItemSelectionModel::selectionChanged, this, + &ReceiveCoinsDialog::recentRequestsView_selectionChanged); // Last 2 columns are set by the columnResizingFixer, when the table geometry is ready. columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(tableView, AMOUNT_MINIMUM_COLUMN_WIDTH, DATE_COLUMN_WIDTH, this); diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index 5bc5568e9a..c561d948be 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -30,10 +30,10 @@ QRImageWidget::QRImageWidget(QWidget *parent): { contextMenu = new QMenu(this); QAction *saveImageAction = new QAction(tr("&Save Image..."), this); - connect(saveImageAction, SIGNAL(triggered()), this, SLOT(saveImage())); + connect(saveImageAction, &QAction::triggered, this, &QRImageWidget::saveImage); contextMenu->addAction(saveImageAction); QAction *copyImageAction = new QAction(tr("&Copy Image"), this); - connect(copyImageAction, SIGNAL(triggered()), this, SLOT(copyImage())); + connect(copyImageAction, &QAction::triggered, this, &QRImageWidget::copyImage); contextMenu->addAction(copyImageAction); } @@ -97,7 +97,7 @@ ReceiveRequestDialog::ReceiveRequestDialog(QWidget *parent) : ui->lblQRCode->setVisible(false); #endif - connect(ui->btnSaveAs, SIGNAL(clicked()), ui->lblQRCode, SLOT(saveImage())); + connect(ui->btnSaveAs, &QPushButton::clicked, ui->lblQRCode, &QRImageWidget::saveImage); } ReceiveRequestDialog::~ReceiveRequestDialog() @@ -110,7 +110,7 @@ void ReceiveRequestDialog::setModel(WalletModel *_model) this->model = _model; if (_model) - connect(_model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(update())); + connect(_model->getOptionsModel(), &OptionsModel::displayUnitChanged, this, &ReceiveRequestDialog::update); // update the display unit if necessary update(); diff --git a/src/qt/recentrequeststablemodel.cpp b/src/qt/recentrequeststablemodel.cpp index f0d2aba370..82ab48ac20 100644 --- a/src/qt/recentrequeststablemodel.cpp +++ b/src/qt/recentrequeststablemodel.cpp @@ -26,7 +26,7 @@ RecentRequestsTableModel::RecentRequestsTableModel(WalletModel *parent) : /* These columns must match the indices in the ColumnIndex enumeration */ columns << tr("Date") << tr("Label") << tr("Message") << getAmountTitle(); - connect(walletModel->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + connect(walletModel->getOptionsModel(), &OptionsModel::displayUnitChanged, this, &RecentRequestsTableModel::updateDisplayUnit); } RecentRequestsTableModel::~RecentRequestsTableModel() diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 2b0307d286..66e36f0b67 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -105,12 +105,10 @@ class QtRPCTimerBase: public QObject, public RPCTimerBase func(_func) { timer.setSingleShot(true); - connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); + connect(&timer, &QTimer::timeout, [this]{ func(); }); timer.start(millis); } ~QtRPCTimerBase() {} -private Q_SLOTS: - void timeout() { func(); } private: QTimer timer; std::function func; @@ -474,10 +472,10 @@ RPCConsole::RPCConsole(interfaces::Node& node, const PlatformStyle *_platformSty ui->lineEdit->installEventFilter(this); ui->messagesWidget->installEventFilter(this); - connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear())); - connect(ui->fontBiggerButton, SIGNAL(clicked()), this, SLOT(fontBigger())); - connect(ui->fontSmallerButton, SIGNAL(clicked()), this, SLOT(fontSmaller())); - connect(ui->btnClearTrafficGraph, SIGNAL(clicked()), ui->trafficGraph, SLOT(clear())); + connect(ui->clearButton, &QPushButton::clicked, this, &RPCConsole::clear); + connect(ui->fontBiggerButton, &QPushButton::clicked, this, &RPCConsole::fontBigger); + connect(ui->fontSmallerButton, &QPushButton::clicked, this, &RPCConsole::fontSmaller); + connect(ui->btnClearTrafficGraph, &QPushButton::clicked, ui->trafficGraph, &TrafficGraphWidget::clear); // disable the wallet selector by default ui->WalletSelector->setVisible(false); @@ -565,19 +563,19 @@ void RPCConsole::setClientModel(ClientModel *model) if (model && clientModel->getPeerTableModel() && clientModel->getBanTableModel()) { // Keep up to date with client setNumConnections(model->getNumConnections()); - connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int))); + connect(model, &ClientModel::numConnectionsChanged, this, &RPCConsole::setNumConnections); interfaces::Node& node = clientModel->node(); setNumBlocks(node.getNumBlocks(), QDateTime::fromTime_t(node.getLastBlockTime()), node.getVerificationProgress(), false); - connect(model, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(setNumBlocks(int,QDateTime,double,bool))); + connect(model, &ClientModel::numBlocksChanged, this, &RPCConsole::setNumBlocks); updateNetworkState(); - connect(model, SIGNAL(networkActiveChanged(bool)), this, SLOT(setNetworkActive(bool))); + connect(model, &ClientModel::networkActiveChanged, this, &RPCConsole::setNetworkActive); updateTrafficStats(node.getTotalBytesRecv(), node.getTotalBytesSent()); - connect(model, SIGNAL(bytesChanged(quint64,quint64)), this, SLOT(updateTrafficStats(quint64, quint64))); + connect(model, &ClientModel::bytesChanged, this, &RPCConsole::updateTrafficStats); - connect(model, SIGNAL(mempoolSizeChanged(long,size_t)), this, SLOT(setMempoolSize(long,size_t))); + connect(model, &ClientModel::mempoolSizeChanged, this, &RPCConsole::setMempoolSize); // set up peer table ui->peerWidget->setModel(model->getPeerTableModel()); @@ -614,23 +612,22 @@ void RPCConsole::setClientModel(ClientModel *model) signalMapper->setMapping(banAction24h, 60*60*24); signalMapper->setMapping(banAction7d, 60*60*24*7); signalMapper->setMapping(banAction365d, 60*60*24*365); - connect(banAction1h, SIGNAL(triggered()), signalMapper, SLOT(map())); - connect(banAction24h, SIGNAL(triggered()), signalMapper, SLOT(map())); - connect(banAction7d, SIGNAL(triggered()), signalMapper, SLOT(map())); - connect(banAction365d, SIGNAL(triggered()), signalMapper, SLOT(map())); - connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(banSelectedNode(int))); + connect(banAction1h, &QAction::triggered, signalMapper, static_cast(&QSignalMapper::map)); + connect(banAction24h, &QAction::triggered, signalMapper, static_cast(&QSignalMapper::map)); + connect(banAction7d, &QAction::triggered, signalMapper, static_cast(&QSignalMapper::map)); + connect(banAction365d, &QAction::triggered, signalMapper, static_cast(&QSignalMapper::map)); + connect(signalMapper, static_cast(&QSignalMapper::mapped), this, &RPCConsole::banSelectedNode); // peer table context menu signals - connect(ui->peerWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showPeersTableContextMenu(const QPoint&))); - connect(disconnectAction, SIGNAL(triggered()), this, SLOT(disconnectSelectedNode())); + connect(ui->peerWidget, &QTableView::customContextMenuRequested, this, &RPCConsole::showPeersTableContextMenu); + connect(disconnectAction, &QAction::triggered, this, &RPCConsole::disconnectSelectedNode); // peer table signal handling - update peer details when selecting new node - connect(ui->peerWidget->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), - this, SLOT(peerSelected(const QItemSelection &, const QItemSelection &))); + connect(ui->peerWidget->selectionModel(), &QItemSelectionModel::selectionChanged, this, &RPCConsole::peerSelected); // peer table signal handling - update peer details when new nodes are added to the model - connect(model->getPeerTableModel(), SIGNAL(layoutChanged()), this, SLOT(peerLayoutChanged())); + connect(model->getPeerTableModel(), &PeerTableModel::layoutChanged, this, &RPCConsole::peerLayoutChanged); // peer table signal handling - cache selected node ids - connect(model->getPeerTableModel(), SIGNAL(layoutAboutToBeChanged()), this, SLOT(peerLayoutAboutToChange())); + connect(model->getPeerTableModel(), &PeerTableModel::layoutAboutToBeChanged, this, &RPCConsole::peerLayoutAboutToChange); // set up ban table ui->banlistWidget->setModel(model->getBanTableModel()); @@ -651,13 +648,13 @@ void RPCConsole::setClientModel(ClientModel *model) banTableContextMenu->addAction(unbanAction); // ban table context menu signals - connect(ui->banlistWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showBanTableContextMenu(const QPoint&))); - connect(unbanAction, SIGNAL(triggered()), this, SLOT(unbanSelectedNode())); + connect(ui->banlistWidget, &QTableView::customContextMenuRequested, this, &RPCConsole::showBanTableContextMenu); + connect(unbanAction, &QAction::triggered, this, &RPCConsole::unbanSelectedNode); // ban table signal handling - clear peer details when clicking a peer in the ban table - connect(ui->banlistWidget, SIGNAL(clicked(const QModelIndex&)), this, SLOT(clearSelectedNode())); + connect(ui->banlistWidget, &QTableView::clicked, this, &RPCConsole::clearSelectedNode); // ban table signal handling - ensure ban table is shown or hidden (if empty) - connect(model->getBanTableModel(), SIGNAL(layoutChanged()), this, SLOT(showOrHideBanTableIfRequired())); + connect(model->getBanTableModel(), &BanTableModel::layoutChanged, this, &RPCConsole::showOrHideBanTableIfRequired); showOrHideBanTableIfRequired(); // Provide initial values @@ -972,15 +969,16 @@ void RPCConsole::startExecutor() executor->moveToThread(&thread); // Replies from executor object must go to this object - connect(executor, SIGNAL(reply(int,QString)), this, SLOT(message(int,QString))); + connect(executor, &RPCExecutor::reply, this, static_cast(&RPCConsole::message)); + // Requests from this object must go to executor - connect(this, SIGNAL(cmdRequest(QString, QString)), executor, SLOT(request(QString, QString))); + connect(this, &RPCConsole::cmdRequest, executor, &RPCExecutor::request); // On stopExecutor signal // - quit the Qt event loop in the execution thread - connect(this, SIGNAL(stopExecutor()), &thread, SLOT(quit())); + connect(this, &RPCConsole::stopExecutor, &thread, &QThread::quit); // - queue executor for deletion (in execution thread) - connect(&thread, SIGNAL(finished()), executor, SLOT(deleteLater()), Qt::DirectConnection); + connect(&thread, &QThread::finished, executor, &RPCExecutor::deleteLater, Qt::DirectConnection); // Default implementation of QThread::run() simply spins up an event loop in the thread, // which is what we want. diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 0671b47782..db77043951 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -96,7 +96,8 @@ public Q_SLOTS: void fontSmaller(); void setFontSize(int newSize); /** Append the message to the message widget */ - void message(int category, const QString &message, bool html = false); + void message(int category, const QString &msg) { message(category, msg, false); } + void message(int category, const QString &message, bool html); /** Set number of connections shown in the UI */ void setNumConnections(int count); /** Set network state shown in the UI */ diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index da155f872c..eed71397ab 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -72,13 +72,13 @@ SendCoinsDialog::SendCoinsDialog(const PlatformStyle *_platformStyle, QWidget *p addEntry(); - connect(ui->addButton, SIGNAL(clicked()), this, SLOT(addEntry())); - connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear())); + connect(ui->addButton, &QPushButton::clicked, this, &SendCoinsDialog::addEntry); + connect(ui->clearButton, &QPushButton::clicked, this, &SendCoinsDialog::clear); // Coin Control - connect(ui->pushButtonCoinControl, SIGNAL(clicked()), this, SLOT(coinControlButtonClicked())); - connect(ui->checkBoxCoinControlChange, SIGNAL(stateChanged(int)), this, SLOT(coinControlChangeChecked(int))); - connect(ui->lineEditCoinControlChange, SIGNAL(textEdited(const QString &)), this, SLOT(coinControlChangeEdited(const QString &))); + connect(ui->pushButtonCoinControl, &QPushButton::clicked, this, &SendCoinsDialog::coinControlButtonClicked); + connect(ui->checkBoxCoinControlChange, &QCheckBox::stateChanged, this, &SendCoinsDialog::coinControlChangeChecked); + connect(ui->lineEditCoinControlChange, &QValidatedLineEdit::textEdited, this, &SendCoinsDialog::coinControlChangeEdited); // Coin Control: clipboard actions QAction *clipboardQuantityAction = new QAction(tr("Copy quantity"), this); @@ -88,13 +88,13 @@ SendCoinsDialog::SendCoinsDialog(const PlatformStyle *_platformStyle, QWidget *p QAction *clipboardBytesAction = new QAction(tr("Copy bytes"), this); QAction *clipboardLowOutputAction = new QAction(tr("Copy dust"), this); QAction *clipboardChangeAction = new QAction(tr("Copy change"), this); - connect(clipboardQuantityAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardQuantity())); - connect(clipboardAmountAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardAmount())); - connect(clipboardFeeAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardFee())); - connect(clipboardAfterFeeAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardAfterFee())); - connect(clipboardBytesAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardBytes())); - connect(clipboardLowOutputAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardLowOutput())); - connect(clipboardChangeAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardChange())); + connect(clipboardQuantityAction, &QAction::triggered, this, &SendCoinsDialog::coinControlClipboardQuantity); + connect(clipboardAmountAction, &QAction::triggered, this, &SendCoinsDialog::coinControlClipboardAmount); + connect(clipboardFeeAction, &QAction::triggered, this, &SendCoinsDialog::coinControlClipboardFee); + connect(clipboardAfterFeeAction, &QAction::triggered, this, &SendCoinsDialog::coinControlClipboardAfterFee); + connect(clipboardBytesAction, &QAction::triggered, this, &SendCoinsDialog::coinControlClipboardBytes); + connect(clipboardLowOutputAction, &QAction::triggered, this, &SendCoinsDialog::coinControlClipboardLowOutput); + connect(clipboardChangeAction, &QAction::triggered, this, &SendCoinsDialog::coinControlClipboardChange); ui->labelCoinControlQuantity->addAction(clipboardQuantityAction); ui->labelCoinControlAmount->addAction(clipboardAmountAction); ui->labelCoinControlFee->addAction(clipboardFeeAction); @@ -130,7 +130,7 @@ void SendCoinsDialog::setClientModel(ClientModel *_clientModel) this->clientModel = _clientModel; if (_clientModel) { - connect(_clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(updateSmartFeeLabel())); + connect(_clientModel, &ClientModel::numBlocksChanged, this, &SendCoinsDialog::updateSmartFeeLabel); } } @@ -151,13 +151,13 @@ void SendCoinsDialog::setModel(WalletModel *_model) interfaces::WalletBalances balances = _model->wallet().getBalances(); setBalance(balances); - connect(_model, SIGNAL(balanceChanged(interfaces::WalletBalances)), this, SLOT(setBalance(interfaces::WalletBalances))); - connect(_model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + connect(_model, &WalletModel::balanceChanged, this, &SendCoinsDialog::setBalance); + connect(_model->getOptionsModel(), &OptionsModel::displayUnitChanged, this, &SendCoinsDialog::updateDisplayUnit); updateDisplayUnit(); // Coin Control - connect(_model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(coinControlUpdateLabels())); - connect(_model->getOptionsModel(), SIGNAL(coinControlFeaturesChanged(bool)), this, SLOT(coinControlFeatureChanged(bool))); + connect(_model->getOptionsModel(), &OptionsModel::displayUnitChanged, this, &SendCoinsDialog::coinControlUpdateLabels); + connect(_model->getOptionsModel(), &OptionsModel::coinControlFeaturesChanged, this, &SendCoinsDialog::coinControlFeatureChanged); ui->frameCoinControl->setVisible(_model->getOptionsModel()->getCoinControlFeatures()); coinControlUpdateLabels(); @@ -165,16 +165,16 @@ void SendCoinsDialog::setModel(WalletModel *_model) for (const int n : confTargets) { ui->confTargetSelector->addItem(tr("%1 (%2 blocks)").arg(GUIUtil::formatNiceTimeOffset(n*Params().GetConsensus().nPowTargetSpacing)).arg(n)); } - connect(ui->confTargetSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSmartFeeLabel())); - connect(ui->confTargetSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(coinControlUpdateLabels())); - connect(ui->groupFee, SIGNAL(buttonClicked(int)), this, SLOT(updateFeeSectionControls())); - connect(ui->groupFee, SIGNAL(buttonClicked(int)), this, SLOT(coinControlUpdateLabels())); - connect(ui->customFee, SIGNAL(valueChanged()), this, SLOT(coinControlUpdateLabels())); - connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(setMinimumFee())); - connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(updateFeeSectionControls())); - connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(coinControlUpdateLabels())); - connect(ui->optInRBF, SIGNAL(stateChanged(int)), this, SLOT(updateSmartFeeLabel())); - connect(ui->optInRBF, SIGNAL(stateChanged(int)), this, SLOT(coinControlUpdateLabels())); + connect(ui->confTargetSelector, static_cast(&QComboBox::currentIndexChanged), this, &SendCoinsDialog::updateSmartFeeLabel); + connect(ui->confTargetSelector, static_cast(&QComboBox::currentIndexChanged), this, &SendCoinsDialog::coinControlUpdateLabels); + connect(ui->groupFee, static_cast(&QButtonGroup::buttonClicked), this, &SendCoinsDialog::updateFeeSectionControls); + connect(ui->groupFee, static_cast(&QButtonGroup::buttonClicked), this, &SendCoinsDialog::coinControlUpdateLabels); + connect(ui->customFee, &BitcoinAmountField::valueChanged, this, &SendCoinsDialog::coinControlUpdateLabels); + connect(ui->checkBoxMinimumFee, &QCheckBox::stateChanged, this, &SendCoinsDialog::setMinimumFee); + connect(ui->checkBoxMinimumFee, &QCheckBox::stateChanged, this, &SendCoinsDialog::updateFeeSectionControls); + connect(ui->checkBoxMinimumFee, &QCheckBox::stateChanged, this, &SendCoinsDialog::coinControlUpdateLabels); + connect(ui->optInRBF, &QCheckBox::stateChanged, this, &SendCoinsDialog::updateSmartFeeLabel); + connect(ui->optInRBF, &QCheckBox::stateChanged, this, &SendCoinsDialog::coinControlUpdateLabels); ui->customFee->setSingleStep(model->wallet().getRequiredFee(1000)); updateFeeSectionControls(); updateMinFeeLabel(); @@ -417,10 +417,10 @@ SendCoinsEntry *SendCoinsDialog::addEntry() SendCoinsEntry *entry = new SendCoinsEntry(platformStyle, this); entry->setModel(model); ui->entries->addWidget(entry); - connect(entry, SIGNAL(removeEntry(SendCoinsEntry*)), this, SLOT(removeEntry(SendCoinsEntry*))); - connect(entry, SIGNAL(useAvailableBalance(SendCoinsEntry*)), this, SLOT(useAvailableBalance(SendCoinsEntry*))); - connect(entry, SIGNAL(payAmountChanged()), this, SLOT(coinControlUpdateLabels())); - connect(entry, SIGNAL(subtractFeeFromAmountChanged()), this, SLOT(coinControlUpdateLabels())); + connect(entry, &SendCoinsEntry::removeEntry, this, &SendCoinsDialog::removeEntry); + connect(entry, &SendCoinsEntry::useAvailableBalance, this, &SendCoinsDialog::useAvailableBalance); + connect(entry, &SendCoinsEntry::payAmountChanged, this, &SendCoinsDialog::coinControlUpdateLabels); + connect(entry, &SendCoinsEntry::subtractFeeFromAmountChanged, this, &SendCoinsDialog::coinControlUpdateLabels); // Focus the field, so that entry can start immediately entry->clear(); @@ -897,7 +897,7 @@ SendConfirmationDialog::SendConfirmationDialog(const QString &title, const QStri setDefaultButton(QMessageBox::Cancel); yesButton = button(QMessageBox::Yes); updateYesButton(); - connect(&countDownTimer, SIGNAL(timeout()), this, SLOT(countDown())); + connect(&countDownTimer, &QTimer::timeout, this, &SendConfirmationDialog::countDown); } int SendConfirmationDialog::exec() diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index d53f91dffa..b394ff3150 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -40,12 +40,12 @@ SendCoinsEntry::SendCoinsEntry(const PlatformStyle *_platformStyle, QWidget *par ui->payTo_is->setFont(GUIUtil::fixedPitchFont()); // Connect signals - connect(ui->payAmount, SIGNAL(valueChanged()), this, SIGNAL(payAmountChanged())); - connect(ui->checkboxSubtractFeeFromAmount, SIGNAL(toggled(bool)), this, SIGNAL(subtractFeeFromAmountChanged())); - connect(ui->deleteButton, SIGNAL(clicked()), this, SLOT(deleteClicked())); - connect(ui->deleteButton_is, SIGNAL(clicked()), this, SLOT(deleteClicked())); - connect(ui->deleteButton_s, SIGNAL(clicked()), this, SLOT(deleteClicked())); - connect(ui->useAvailableBalanceButton, SIGNAL(clicked()), this, SLOT(useAvailableBalanceClicked())); + connect(ui->payAmount, &BitcoinAmountField::valueChanged, this, &SendCoinsEntry::payAmountChanged); + connect(ui->checkboxSubtractFeeFromAmount, &QCheckBox::toggled, this, &SendCoinsEntry::subtractFeeFromAmountChanged); + connect(ui->deleteButton, &QPushButton::clicked, this, &SendCoinsEntry::deleteClicked); + connect(ui->deleteButton_is, &QPushButton::clicked, this, &SendCoinsEntry::deleteClicked); + connect(ui->deleteButton_s, &QPushButton::clicked, this, &SendCoinsEntry::deleteClicked); + connect(ui->useAvailableBalanceButton, &QPushButton::clicked, this, &SendCoinsEntry::useAvailableBalanceClicked); } SendCoinsEntry::~SendCoinsEntry() @@ -82,7 +82,7 @@ void SendCoinsEntry::setModel(WalletModel *_model) this->model = _model; if (_model && _model->getOptionsModel()) - connect(_model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + connect(_model->getOptionsModel(), &OptionsModel::displayUnitChanged, this, &SendCoinsEntry::updateDisplayUnit); clear(); } diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp index e92f9d7a5b..5384b9e8b0 100644 --- a/src/qt/test/paymentservertests.cpp +++ b/src/qt/test/paymentservertests.cpp @@ -39,8 +39,8 @@ X509 *parse_b64der_cert(const char* cert_data) static SendCoinsRecipient handleRequest(PaymentServer* server, std::vector& data) { RecipientCatcher sigCatcher; - QObject::connect(server, SIGNAL(receivedPaymentRequest(SendCoinsRecipient)), - &sigCatcher, SLOT(getRecipient(SendCoinsRecipient))); + QObject::connect(server, &PaymentServer::receivedPaymentRequest, + &sigCatcher, &RecipientCatcher::getRecipient); // Write data to a temp file: QTemporaryFile f; @@ -57,8 +57,8 @@ static SendCoinsRecipient handleRequest(PaymentServer* server, std::vectorgetOptionsModel()->getDisplayUnit()); priv->refreshWallet(walletModel->wallet()); - connect(walletModel->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + connect(walletModel->getOptionsModel(), &OptionsModel::displayUnitChanged, this, &TransactionTableModel::updateDisplayUnit); subscribeToCoreSignals(); } diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 23c50f55ba..6d08a3b0fb 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -176,30 +176,31 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa mapperThirdPartyTxUrls = new QSignalMapper(this); // Connect actions - connect(mapperThirdPartyTxUrls, SIGNAL(mapped(QString)), this, SLOT(openThirdPartyTxUrl(QString))); - - connect(dateWidget, SIGNAL(activated(int)), this, SLOT(chooseDate(int))); - connect(typeWidget, SIGNAL(activated(int)), this, SLOT(chooseType(int))); - connect(watchOnlyWidget, SIGNAL(activated(int)), this, SLOT(chooseWatchonly(int))); - connect(amountWidget, SIGNAL(textChanged(QString)), amount_typing_delay, SLOT(start())); - connect(amount_typing_delay, SIGNAL(timeout()), this, SLOT(changedAmount())); - connect(search_widget, SIGNAL(textChanged(QString)), prefix_typing_delay, SLOT(start())); - connect(prefix_typing_delay, SIGNAL(timeout()), this, SLOT(changedSearch())); - - connect(view, SIGNAL(doubleClicked(QModelIndex)), this, SIGNAL(doubleClicked(QModelIndex))); - connect(view, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextualMenu(QPoint))); - - connect(bumpFeeAction, SIGNAL(triggered()), this, SLOT(bumpFee())); - connect(abandonAction, SIGNAL(triggered()), this, SLOT(abandonTx())); - connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(copyAddress())); - connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(copyLabel())); - connect(copyAmountAction, SIGNAL(triggered()), this, SLOT(copyAmount())); - connect(copyTxIDAction, SIGNAL(triggered()), this, SLOT(copyTxID())); - connect(copyTxHexAction, SIGNAL(triggered()), this, SLOT(copyTxHex())); - connect(copyTxPlainText, SIGNAL(triggered()), this, SLOT(copyTxPlainText())); - connect(editLabelAction, SIGNAL(triggered()), this, SLOT(editLabel())); - connect(showDetailsAction, SIGNAL(triggered()), this, SLOT(showDetails())); - + connect(mapperThirdPartyTxUrls, static_cast(&QSignalMapper::mapped), this, &TransactionView::openThirdPartyTxUrl); + + connect(dateWidget, static_cast(&QComboBox::activated), this, &TransactionView::chooseDate); + connect(typeWidget, static_cast(&QComboBox::activated), this, &TransactionView::chooseType); + connect(watchOnlyWidget, static_cast(&QComboBox::activated), this, &TransactionView::chooseWatchonly); + connect(amountWidget, &QLineEdit::textChanged, amount_typing_delay, static_cast(&QTimer::start)); + connect(amount_typing_delay, &QTimer::timeout, this, &TransactionView::changedAmount); + connect(search_widget, &QLineEdit::textChanged, prefix_typing_delay, static_cast(&QTimer::start)); + connect(prefix_typing_delay, &QTimer::timeout, this, &TransactionView::changedSearch); + + connect(view, &QTableView::doubleClicked, this, &TransactionView::doubleClicked); + connect(view, &QTableView::customContextMenuRequested, this, &TransactionView::contextualMenu); + + connect(bumpFeeAction, &QAction::triggered, this, &TransactionView::bumpFee); + connect(abandonAction, &QAction::triggered, this, &TransactionView::abandonTx); + connect(copyAddressAction, &QAction::triggered, this, &TransactionView::copyAddress); + connect(copyLabelAction, &QAction::triggered, this, &TransactionView::copyLabel); + connect(copyAmountAction, &QAction::triggered, this, &TransactionView::copyAmount); + connect(copyTxIDAction, &QAction::triggered, this, &TransactionView::copyTxID); + connect(copyTxHexAction, &QAction::triggered, this, &TransactionView::copyTxHex); + connect(copyTxPlainText, &QAction::triggered, this, &TransactionView::copyTxPlainText); + connect(editLabelAction, &QAction::triggered, this, &TransactionView::editLabel); + connect(showDetailsAction, &QAction::triggered, this, &TransactionView::showDetails); + // Double-clicking on a transaction on the transaction history page shows details + connect(this, &TransactionView::doubleClicked, this, &TransactionView::showDetails); // Highlight transaction after fee bump connect(this, &TransactionView::bumpedFee, [this](const uint256& txid) { focusTransaction(txid); @@ -249,7 +250,7 @@ void TransactionView::setModel(WalletModel *_model) if (i == 0) contextMenu->addSeparator(); contextMenu->addAction(thirdPartyTxUrlAction); - connect(thirdPartyTxUrlAction, SIGNAL(triggered()), mapperThirdPartyTxUrls, SLOT(map())); + connect(thirdPartyTxUrlAction, &QAction::triggered, mapperThirdPartyTxUrls, static_cast(&QSignalMapper::map)); mapperThirdPartyTxUrls->setMapping(thirdPartyTxUrlAction, listUrls[i].trimmed()); } } @@ -259,7 +260,7 @@ void TransactionView::setModel(WalletModel *_model) updateWatchOnlyColumn(_model->wallet().haveWatchOnly()); // Watch-only signal - connect(_model, SIGNAL(notifyWatchonlyChanged(bool)), this, SLOT(updateWatchOnlyColumn(bool))); + connect(_model, &WalletModel::notifyWatchonlyChanged, this, &TransactionView::updateWatchOnlyColumn); } } @@ -573,8 +574,8 @@ QWidget *TransactionView::createDateRangeWidget() dateRangeWidget->setVisible(false); // Notify on change - connect(dateFrom, SIGNAL(dateChanged(QDate)), this, SLOT(dateRangeChanged())); - connect(dateTo, SIGNAL(dateChanged(QDate)), this, SLOT(dateRangeChanged())); + connect(dateFrom, &QDateTimeEdit::dateChanged, this, &TransactionView::dateRangeChanged); + connect(dateTo, &QDateTimeEdit::dateChanged, this, &TransactionView::dateRangeChanged); return dateRangeWidget; } diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp index e8fd83d427..d15bd95b8e 100644 --- a/src/qt/walletframe.cpp +++ b/src/qt/walletframe.cpp @@ -68,9 +68,11 @@ bool WalletFrame::addWallet(WalletModel *walletModel) mapWalletViews[name] = walletView; // Ensure a walletView is able to show the main window - connect(walletView, SIGNAL(showNormalIfMinimized()), gui, SLOT(showNormalIfMinimized())); + connect(walletView, &WalletView::showNormalIfMinimized, [this]{ + gui->showNormalIfMinimized(); + }); - connect(walletView, SIGNAL(outOfSyncWarningClicked()), this, SLOT(outOfSyncWarningClicked())); + connect(walletView, &WalletView::outOfSyncWarningClicked, this, &WalletFrame::outOfSyncWarningClicked); return true; } diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index d91cdcdc1f..18a5bda9c3 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -44,7 +44,7 @@ WalletModel::WalletModel(std::unique_ptr wallet, interfaces: // This timer will be fired repeatedly to update the balance pollTimer = new QTimer(this); - connect(pollTimer, SIGNAL(timeout()), this, SLOT(pollBalanceChanged())); + connect(pollTimer, &QTimer::timeout, this, &WalletModel::pollBalanceChanged); pollTimer->start(MODEL_UPDATE_DELAY); subscribeToCoreSignals(); diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 9af29b5d60..053e951921 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -66,22 +66,20 @@ WalletView::WalletView(const PlatformStyle *_platformStyle, QWidget *parent): addWidget(sendCoinsPage); // Clicking on a transaction on the overview pre-selects the transaction on the transaction history page - connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), transactionView, SLOT(focusTransaction(QModelIndex))); - connect(overviewPage, SIGNAL(outOfSyncWarningClicked()), this, SLOT(requestedSyncWarningInfo())); + connect(overviewPage, &OverviewPage::transactionClicked, transactionView, static_cast(&TransactionView::focusTransaction)); - // Highlight transaction after send - connect(sendCoinsPage, SIGNAL(coinsSent(uint256)), transactionView, SLOT(focusTransaction(uint256))); + connect(overviewPage, &OverviewPage::outOfSyncWarningClicked, this, &WalletView::requestedSyncWarningInfo); - // Double-clicking on a transaction on the transaction history page shows details - connect(transactionView, SIGNAL(doubleClicked(QModelIndex)), transactionView, SLOT(showDetails())); + // Highlight transaction after send + connect(sendCoinsPage, &SendCoinsDialog::coinsSent, transactionView, static_cast(&TransactionView::focusTransaction)); // Clicking on "Export" allows to export the transaction list - connect(exportButton, SIGNAL(clicked()), transactionView, SLOT(exportClicked())); + connect(exportButton, &QPushButton::clicked, transactionView, &TransactionView::exportClicked); // Pass through messages from sendCoinsPage - connect(sendCoinsPage, SIGNAL(message(QString,QString,unsigned int)), this, SIGNAL(message(QString,QString,unsigned int))); + connect(sendCoinsPage, &SendCoinsDialog::message, this, &WalletView::message); // Pass through messages from transactionView - connect(transactionView, SIGNAL(message(QString,QString,unsigned int)), this, SIGNAL(message(QString,QString,unsigned int))); + connect(transactionView, &TransactionView::message, this, &WalletView::message); } WalletView::~WalletView() @@ -93,22 +91,24 @@ void WalletView::setBitcoinGUI(BitcoinGUI *gui) if (gui) { // Clicking on a transaction on the overview page simply sends you to transaction history page - connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), gui, SLOT(gotoHistoryPage())); + connect(overviewPage, &OverviewPage::transactionClicked, gui, &BitcoinGUI::gotoHistoryPage); // Navigate to transaction history page after send - connect(sendCoinsPage, SIGNAL(coinsSent(uint256)), gui, SLOT(gotoHistoryPage())); + connect(sendCoinsPage, &SendCoinsDialog::coinsSent, gui, &BitcoinGUI::gotoHistoryPage); // Receive and report messages - connect(this, SIGNAL(message(QString,QString,unsigned int)), gui, SLOT(message(QString,QString,unsigned int))); + connect(this, &WalletView::message, [gui](const QString &title, const QString &message, unsigned int style) { + gui->message(title, message, style); + }); // Pass through encryption status changed signals - connect(this, SIGNAL(encryptionStatusChanged()), gui, SLOT(updateWalletStatus())); + connect(this, &WalletView::encryptionStatusChanged, gui, &BitcoinGUI::updateWalletStatus); // Pass through transaction notifications - connect(this, SIGNAL(incomingTransaction(QString,int,CAmount,QString,QString,QString,QString)), gui, SLOT(incomingTransaction(QString,int,CAmount,QString,QString,QString,QString))); + connect(this, &WalletView::incomingTransaction, gui, &BitcoinGUI::incomingTransaction); // Connect HD enabled state signal - connect(this, SIGNAL(hdEnabledStatusChanged()), gui, SLOT(updateWalletStatus())); + connect(this, &WalletView::hdEnabledStatusChanged, gui, &BitcoinGUI::updateWalletStatus); } } @@ -135,24 +135,23 @@ void WalletView::setWalletModel(WalletModel *_walletModel) if (_walletModel) { // Receive and pass through messages from wallet model - connect(_walletModel, SIGNAL(message(QString,QString,unsigned int)), this, SIGNAL(message(QString,QString,unsigned int))); + connect(_walletModel, &WalletModel::message, this, &WalletView::message); // Handle changes in encryption status - connect(_walletModel, SIGNAL(encryptionStatusChanged()), this, SIGNAL(encryptionStatusChanged())); + connect(_walletModel, &WalletModel::encryptionStatusChanged, this, &WalletView::encryptionStatusChanged); updateEncryptionStatus(); // update HD status Q_EMIT hdEnabledStatusChanged(); // Balloon pop-up for new transaction - connect(_walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex,int,int)), - this, SLOT(processNewTransaction(QModelIndex,int,int))); + connect(_walletModel->getTransactionTableModel(), &TransactionTableModel::rowsInserted, this, &WalletView::processNewTransaction); // Ask for passphrase if needed - connect(_walletModel, SIGNAL(requireUnlock()), this, SLOT(unlockWallet())); + connect(_walletModel, &WalletModel::requireUnlock, this, &WalletView::unlockWallet); // Show progress dialog - connect(_walletModel, SIGNAL(showProgress(QString,int)), this, SLOT(showProgress(QString,int))); + connect(_walletModel, &WalletModel::showProgress, this, &WalletView::showProgress); } } From 3567b247f43decb6fc102d5b0989d1746fce0441 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Barbosa?= Date: Sun, 24 Jun 2018 18:12:07 +0100 Subject: [PATCH 0088/1200] test: Add lint to prevent SIGNAL/SLOT connect style --- test/lint/lint-qt.sh | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100755 test/lint/lint-qt.sh diff --git a/test/lint/lint-qt.sh b/test/lint/lint-qt.sh new file mode 100755 index 0000000000..2e77682aa2 --- /dev/null +++ b/test/lint/lint-qt.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2018 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# +# Check for SIGNAL/SLOT connect style, removed since Qt4 support drop. + +export LC_ALL=C + +EXIT_CODE=0 + +OUTPUT=$(git grep -E '(SIGNAL|, ?SLOT)\(' -- src/qt) +if [[ ${OUTPUT} != "" ]]; then + echo "Use Qt5 connect style in:" + echo "$OUTPUT" + EXIT_CODE=1 +fi + +exit ${EXIT_CODE} From 8563341714a1ec452dd3304a39dd880face49c84 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 21 Aug 2018 06:55:24 +0000 Subject: [PATCH 0089/1200] Bugfix: NSIS: Exclude Makefile* from docs Otherwise, the generated Makefile is included in the NSIS-installed documentation, which can lead to non-determinism (eg, if gawk is installed on some build VMs, but others only have mawk) --- share/setup.nsi.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/setup.nsi.in b/share/setup.nsi.in index dd42085a27..8cfb6d76bb 100644 --- a/share/setup.nsi.in +++ b/share/setup.nsi.in @@ -80,7 +80,7 @@ Section -Main SEC0000 File @abs_top_srcdir@/release/@BITCOIN_DAEMON_NAME@@EXEEXT@ File @abs_top_srcdir@/release/@BITCOIN_CLI_NAME@@EXEEXT@ SetOutPath $INSTDIR\doc - File /r @abs_top_srcdir@/doc\*.* + File /r /x Makefile* @abs_top_srcdir@/doc\*.* SetOutPath $INSTDIR WriteRegStr HKCU "${REGKEY}\Components" Main 1 SectionEnd From fa5099ceb757c9d56fa54a08d0441750df6c8869 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 22 Aug 2018 09:24:43 -0400 Subject: [PATCH 0090/1200] p2p: Remove dead code for nVersion=10300 --- src/net_processing.cpp | 5 +---- test/functional/test_framework/messages.py | 2 -- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 88999ba735..0fad012257 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1662,8 +1662,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr return false; } - if (nVersion < MIN_PEER_PROTO_VERSION) - { + if (nVersion < MIN_PEER_PROTO_VERSION) { // disconnect from peers older than this proto version LogPrint(BCLog::NET, "peer=%d using obsolete version %i; disconnecting\n", pfrom->GetId(), nVersion); if (enable_bip61) { @@ -1674,8 +1673,6 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr return false; } - if (nVersion == 10300) - nVersion = 300; if (!vRecv.empty()) vRecv >> addrFrom >> nNonce; if (!vRecv.empty()) { diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py index 7276f6b450..3cd148a02e 100755 --- a/test/functional/test_framework/messages.py +++ b/test/functional/test_framework/messages.py @@ -904,8 +904,6 @@ def __init__(self): def deserialize(self, f): self.nVersion = struct.unpack(" Date: Wed, 22 Aug 2018 01:33:34 +0100 Subject: [PATCH 0091/1200] test: Add tests for RPC help --- test/functional/rpc_help.py | 31 +++++++++++++++++++++++++++++++ test/functional/test_runner.py | 1 + 2 files changed, 32 insertions(+) create mode 100755 test/functional/rpc_help.py diff --git a/test/functional/rpc_help.py b/test/functional/rpc_help.py new file mode 100755 index 0000000000..e878ded258 --- /dev/null +++ b/test/functional/rpc_help.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +"""Test RPC help output.""" + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, assert_raises_rpc_error + +class HelpRpcTest(BitcoinTestFramework): + def set_test_params(self): + self.num_nodes = 1 + + def run_test(self): + node = self.nodes[0] + + # wrong argument count + assert_raises_rpc_error(-1, 'help', node.help, 'foo', 'bar') + + # invalid argument + assert_raises_rpc_error(-1, 'JSON value is not a string as expected', node.help, 0) + + # help of unknown command + assert_equal(node.help('foo'), 'help: unknown command: foo') + + # command titles + titles = [line[3:-3] for line in node.help().splitlines() if line.startswith('==')] + assert_equal(titles, ['Blockchain', 'Control', 'Generating', 'Mining', 'Network', 'Rawtransactions', 'Util', 'Wallet', 'Zmq']) + +if __name__ == '__main__': + HelpRpcTest().main() diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index feea2a327a..13c687fd92 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -152,6 +152,7 @@ 'p2p_node_network_limited.py', 'feature_blocksdir.py', 'feature_config_args.py', + 'rpc_help.py', 'feature_help.py', # Don't append tests at the end to avoid merge conflicts # Put them in a random line within the section that fits their approximate run-time From 00f58f8c48db05dce9dceed73a0028482e037f0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Barbosa?= Date: Thu, 23 Aug 2018 01:46:59 +0100 Subject: [PATCH 0092/1200] rpc: Avoid locking cs_main in some wallet RPC --- src/rpc/rawtransaction.cpp | 1 - src/wallet/rpcwallet.cpp | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 608a1b5da2..637c9f73ab 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -562,7 +562,6 @@ static UniValue decoderawtransaction(const JSONRPCRequest& request) + HelpExampleRpc("decoderawtransaction", "\"hexstring\"") ); - LOCK(cs_main); RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL}); CMutableTransaction mtx; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 4e539a85de..c0c59da7bd 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -165,7 +165,7 @@ static UniValue getnewaddress(const JSONRPCRequest& request) throw JSONRPCError(RPC_WALLET_ERROR, "Error: Private keys are disabled for this wallet"); } - LOCK2(cs_main, pwallet->cs_wallet); + LOCK(pwallet->cs_wallet); // Parse the label first so we don't generate a key if there's an error std::string label; @@ -276,7 +276,7 @@ static UniValue getrawchangeaddress(const JSONRPCRequest& request) throw JSONRPCError(RPC_WALLET_ERROR, "Error: Private keys are disabled for this wallet"); } - LOCK2(cs_main, pwallet->cs_wallet); + LOCK(pwallet->cs_wallet); if (!pwallet->IsLocked()) { pwallet->TopUpKeyPool(); @@ -331,7 +331,7 @@ static UniValue setlabel(const JSONRPCRequest& request) + HelpExampleRpc("setlabel", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"tabby\"") ); - LOCK2(cs_main, pwallet->cs_wallet); + LOCK(pwallet->cs_wallet); CTxDestination dest = DecodeDestination(request.params[0].get_str()); if (!IsValidDestination(dest)) { From e8c4a1e36969d2ef816d9dfaaee979a8cf6bfffe Mon Sep 17 00:00:00 2001 From: Antoine Riard Date: Mon, 20 Aug 2018 23:46:34 +0000 Subject: [PATCH 0093/1200] Add new regtest ports in doc following #10825 ports reattributions Add checkmempool and checkblockindex regtest true in doc --- src/bitcoin-cli.cpp | 3 ++- src/init.cpp | 10 ++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index db713f58d2..6ae2bd0f5e 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -33,6 +33,7 @@ static void SetupCliArgs() { const auto defaultBaseParams = CreateBaseChainParams(CBaseChainParams::MAIN); const auto testnetBaseParams = CreateBaseChainParams(CBaseChainParams::TESTNET); + const auto regtestBaseParams = CreateBaseChainParams(CBaseChainParams::REGTEST); gArgs.AddArg("-?", "This help message", false, OptionsCategory::OPTIONS); gArgs.AddArg("-version", "Print version and exit", false, OptionsCategory::OPTIONS); @@ -45,7 +46,7 @@ static void SetupCliArgs() gArgs.AddArg("-rpcconnect=", strprintf("Send commands to node running on (default: %s)", DEFAULT_RPCCONNECT), false, OptionsCategory::OPTIONS); gArgs.AddArg("-rpccookiefile=", _("Location of the auth cookie. Relative paths will be prefixed by a net-specific datadir location. (default: data dir)"), false, OptionsCategory::OPTIONS); gArgs.AddArg("-rpcpassword=", "Password for JSON-RPC connections", false, OptionsCategory::OPTIONS); - gArgs.AddArg("-rpcport=", strprintf("Connect to JSON-RPC on (default: %u or testnet: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort()), false, OptionsCategory::OPTIONS); + gArgs.AddArg("-rpcport=", strprintf("Connect to JSON-RPC on (default: %u, testnet: %u, regtest: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort(), regtestBaseParams->RPCPort()), false, OptionsCategory::OPTIONS); gArgs.AddArg("-rpcuser=", "Username for JSON-RPC connections", false, OptionsCategory::OPTIONS); gArgs.AddArg("-rpcwait", "Wait for RPC server to start", false, OptionsCategory::OPTIONS); gArgs.AddArg("-rpcwallet=", "Send RPC for non-default wallet on RPC server (needs to exactly match corresponding -wallet option passed to bitcoind)", false, OptionsCategory::OPTIONS); diff --git a/src/init.cpp b/src/init.cpp index 2131a6adc0..1e73263e3d 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -343,8 +343,10 @@ void SetupServerArgs() { const auto defaultBaseParams = CreateBaseChainParams(CBaseChainParams::MAIN); const auto testnetBaseParams = CreateBaseChainParams(CBaseChainParams::TESTNET); + const auto regtestBaseParams = CreateBaseChainParams(CBaseChainParams::REGTEST); const auto defaultChainParams = CreateChainParams(CBaseChainParams::MAIN); const auto testnetChainParams = CreateChainParams(CBaseChainParams::TESTNET); + const auto regtestChainParams = CreateChainParams(CBaseChainParams::REGTEST); // Hidden Options std::vector hidden_args = {"-rpcssl", "-benchmark", "-h", "-help", "-socks", "-tor", "-debugnet", "-whitelistalwaysrelay", @@ -416,7 +418,7 @@ void SetupServerArgs() gArgs.AddArg("-onlynet=", "Make outgoing connections only through network (ipv4, ipv6 or onion). Incoming connections are not affected by this option. This option can be specified multiple times to allow multiple networks.", false, OptionsCategory::CONNECTION); gArgs.AddArg("-peerbloomfilters", strprintf("Support filtering of blocks and transaction with bloom filters (default: %u)", DEFAULT_PEERBLOOMFILTERS), false, OptionsCategory::CONNECTION); gArgs.AddArg("-permitbaremultisig", strprintf("Relay non-P2SH multisig (default: %u)", DEFAULT_PERMIT_BAREMULTISIG), false, OptionsCategory::CONNECTION); - gArgs.AddArg("-port=", strprintf("Listen for connections on (default: %u or testnet: %u)", defaultChainParams->GetDefaultPort(), testnetChainParams->GetDefaultPort()), false, OptionsCategory::CONNECTION); + gArgs.AddArg("-port=", strprintf("Listen for connections on (default: %u, testnet: %u, regtest: %u)", defaultChainParams->GetDefaultPort(), testnetChainParams->GetDefaultPort(), regtestChainParams->GetDefaultPort()), false, OptionsCategory::CONNECTION); gArgs.AddArg("-proxy=", "Connect through SOCKS5 proxy", false, OptionsCategory::CONNECTION); gArgs.AddArg("-proxyrandomize", strprintf("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)", DEFAULT_PROXYRANDOMIZE), false, OptionsCategory::CONNECTION); gArgs.AddArg("-seednode=", "Connect to a node to retrieve peer addresses, and disconnect. This option can be specified multiple times to connect to multiple nodes.", false, OptionsCategory::CONNECTION); @@ -452,8 +454,8 @@ void SetupServerArgs() gArgs.AddArg("-checkblocks=", strprintf("How many blocks to check at startup (default: %u, 0 = all)", DEFAULT_CHECKBLOCKS), true, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-checklevel=", strprintf("How thorough the block verification of -checkblocks is (0-4, default: %u)", DEFAULT_CHECKLEVEL), true, OptionsCategory::DEBUG_TEST); - gArgs.AddArg("-checkblockindex", strprintf("Do a full consistency check for mapBlockIndex, setBlockIndexCandidates, chainActive and mapBlocksUnlinked occasionally. (default: %u)", defaultChainParams->DefaultConsistencyChecks()), true, OptionsCategory::DEBUG_TEST); - gArgs.AddArg("-checkmempool=", strprintf("Run checks every transactions (default: %u)", defaultChainParams->DefaultConsistencyChecks()), true, OptionsCategory::DEBUG_TEST); + gArgs.AddArg("-checkblockindex", strprintf("Do a full consistency check for mapBlockIndex, setBlockIndexCandidates, chainActive and mapBlocksUnlinked occasionally. (default: %u, regtest: %u)", defaultChainParams->DefaultConsistencyChecks(), regtestChainParams->DefaultConsistencyChecks()), true, OptionsCategory::DEBUG_TEST); + gArgs.AddArg("-checkmempool=", strprintf("Run checks every transactions (default: %u, regtest: %u)", defaultChainParams->DefaultConsistencyChecks(), regtestChainParams->DefaultConsistencyChecks()), true, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-checkpoints", strprintf("Disable expensive verification for known chain history (default: %u)", DEFAULT_CHECKPOINTS_ENABLED), true, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-deprecatedrpc=", "Allows deprecated RPC method(s) to be used", true, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-dropmessagestest=", "Randomly drop 1 of every network messages", true, OptionsCategory::DEBUG_TEST); @@ -507,7 +509,7 @@ void SetupServerArgs() gArgs.AddArg("-rpcbind=[:port]", "Bind to given address to listen for JSON-RPC connections. This option is ignored unless -rpcallowip is also passed. Port is optional and overrides -rpcport. Use [host]:port notation for IPv6. This option can be specified multiple times (default: 127.0.0.1 and ::1 i.e., localhost, or if -rpcallowip has been specified, 0.0.0.0 and :: i.e., all addresses)", false, OptionsCategory::RPC); gArgs.AddArg("-rpccookiefile=", "Location of the auth cookie. Relative paths will be prefixed by a net-specific datadir location. (default: data dir)", false, OptionsCategory::RPC); gArgs.AddArg("-rpcpassword=", "Password for JSON-RPC connections", false, OptionsCategory::RPC); - gArgs.AddArg("-rpcport=", strprintf("Listen for JSON-RPC connections on (default: %u or testnet: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort()), false, OptionsCategory::RPC); + gArgs.AddArg("-rpcport=", strprintf("Listen for JSON-RPC connections on (default: %u, testnet: %u, regtest: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort(), regtestBaseParams->RPCPort()), false, OptionsCategory::RPC); gArgs.AddArg("-rpcserialversion", strprintf("Sets the serialization of raw transaction or block hex returned in non-verbose mode, non-segwit(0) or segwit(1) (default: %d)", DEFAULT_RPC_SERIALIZE_VERSION), false, OptionsCategory::RPC); gArgs.AddArg("-rpcservertimeout=", strprintf("Timeout during HTTP requests (default: %d)", DEFAULT_HTTP_SERVER_TIMEOUT), true, OptionsCategory::RPC); gArgs.AddArg("-rpcthreads=", strprintf("Set the number of threads to service RPC calls (default: %d)", DEFAULT_HTTP_THREADS), false, OptionsCategory::RPC); From 497e90c02b96e8739e8faf3d43e41ba1ff0627b7 Mon Sep 17 00:00:00 2001 From: Ben Woosley Date: Thu, 23 Aug 2018 02:57:39 -0700 Subject: [PATCH 0094/1200] Remove default argument to prevector constructor to remove ambiguity The call with this default argument is redundant with prevector(size_type). --- src/prevector.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prevector.h b/src/prevector.h index 033952c959..7a13b98214 100644 --- a/src/prevector.h +++ b/src/prevector.h @@ -252,7 +252,7 @@ class prevector { resize(n); } - explicit prevector(size_type n, const T& val = T()) : _size(0) { + explicit prevector(size_type n, const T& val) : _size(0) { change_capacity(n); _size += n; fill(item_ptr(0), n, val); From 66b3fc543706aad1aaccc403b4ee08f65fa5d17b Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Wed, 22 Aug 2018 23:29:01 +0000 Subject: [PATCH 0095/1200] Skip stale tip checking if outbound connections are off or if reindexing. --- src/net.h | 3 +++ src/net_processing.cpp | 7 +++---- src/net_processing.h | 5 ++++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/net.h b/src/net.h index f9cfea59b7..e074dbb624 100644 --- a/src/net.h +++ b/src/net.h @@ -149,6 +149,7 @@ class CConnman nLocalServices = connOptions.nLocalServices; nMaxConnections = connOptions.nMaxConnections; nMaxOutbound = std::min(connOptions.nMaxOutbound, connOptions.nMaxConnections); + m_use_addrman_outgoing = connOptions.m_use_addrman_outgoing; nMaxAddnode = connOptions.nMaxAddnode; nMaxFeeler = connOptions.nMaxFeeler; nBestHeight = connOptions.nBestHeight; @@ -174,6 +175,7 @@ class CConnman void Stop(); void Interrupt(); bool GetNetworkActive() const { return fNetworkActive; }; + bool GetUseAddrmanOutgoing() const { return m_use_addrman_outgoing; }; void SetNetworkActive(bool active); void OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound = nullptr, const char *strDest = nullptr, bool fOneShot = false, bool fFeeler = false, bool manual_connection = false); bool CheckIncomingNonce(uint64_t nonce); @@ -416,6 +418,7 @@ class CConnman int nMaxOutbound; int nMaxAddnode; int nMaxFeeler; + bool m_use_addrman_outgoing; std::atomic nBestHeight; CClientUIInterface* clientInterface; NetEventsInterface* m_msgproc; diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 88999ba735..2a0ba3970d 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -3166,8 +3166,6 @@ void PeerLogicValidation::EvictExtraOutboundPeers(int64_t time_in_seconds) NodeId worst_peer = -1; int64_t oldest_block_announcement = std::numeric_limits::max(); - LOCK(cs_main); - connman->ForEachNode([&](CNode* pnode) { AssertLockHeld(cs_main); @@ -3215,6 +3213,8 @@ void PeerLogicValidation::EvictExtraOutboundPeers(int64_t time_in_seconds) void PeerLogicValidation::CheckForStaleTipAndEvictPeers(const Consensus::Params &consensusParams) { + LOCK(cs_main); + if (connman == nullptr) return; int64_t time_in_seconds = GetTime(); @@ -3222,10 +3222,9 @@ void PeerLogicValidation::CheckForStaleTipAndEvictPeers(const Consensus::Params EvictExtraOutboundPeers(time_in_seconds); if (time_in_seconds > m_stale_tip_check_time) { - LOCK(cs_main); // Check whether our tip is stale, and if so, allow using an extra // outbound peer - if (TipMayBeStale(consensusParams)) { + if (!fImporting && !fReindex && connman->GetNetworkActive() && connman->GetUseAddrmanOutgoing() && TipMayBeStale(consensusParams)) { LogPrintf("Potential stale tip detected, will try using extra outbound peer (last tip update: %d seconds ago)\n", time_in_seconds - g_last_tip_update); connman->SetTryNewOutboundPeer(true); } else if (connman->GetTryNewOutboundPeer()) { diff --git a/src/net_processing.h b/src/net_processing.h index 7caefc80ca..01b8e97075 100644 --- a/src/net_processing.h +++ b/src/net_processing.h @@ -9,6 +9,9 @@ #include #include #include +#include + +extern CCriticalSection cs_main; /** Default for -maxorphantx, maximum number of orphan transactions kept in memory */ static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100; @@ -65,7 +68,7 @@ class PeerLogicValidation final : public CValidationInterface, public NetEventsI /** Evict extra outbound peers. If we think our tip may be stale, connect to an extra outbound */ void CheckForStaleTipAndEvictPeers(const Consensus::Params &consensusParams); /** If we have extra outbound peers, try to disconnect the one with the oldest block announcement */ - void EvictExtraOutboundPeers(int64_t time_in_seconds); + void EvictExtraOutboundPeers(int64_t time_in_seconds) EXCLUSIVE_LOCKS_REQUIRED(cs_main); private: int64_t m_stale_tip_check_time; //! Next time to check for stale tip From fa74d3d720f72c5f1184ca3e03b0c14a2bc06ed5 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Thu, 23 Aug 2018 10:10:13 -0400 Subject: [PATCH 0096/1200] qa: Remove unused deserialization code in msg_version --- test/functional/test_framework/messages.py | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py index 3cd148a02e..0a3907cba4 100755 --- a/test/functional/test_framework/messages.py +++ b/test/functional/test_framework/messages.py @@ -909,21 +909,12 @@ def deserialize(self, f): self.addrTo = CAddress() self.addrTo.deserialize(f, False) - if self.nVersion >= 106: - self.addrFrom = CAddress() - self.addrFrom.deserialize(f, False) - self.nNonce = struct.unpack("= 209: - self.nStartingHeight = struct.unpack("= 70001: # Relay field is optional for version 70001 onwards From f1640d093fa682c98b000e377916cc32b2267e23 Mon Sep 17 00:00:00 2001 From: Ben Woosley Date: Thu, 23 Aug 2018 03:17:43 -0700 Subject: [PATCH 0097/1200] Make IS_TRIVIALLY_CONSTRUCTIBLE consistent on GCC < 5 std::is_trivially_constructible is equivalent to std::is_trivially_default_constructible std::has_trivial_default_constructor is the GCC < 5 name for std::is_trivially_default_constructible std::is_trivial was also used when compiling with clang, due to clang's use of __GNUC__. Test __clang__ to target the intended implementations. --- src/compat.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compat.h b/src/compat.h index 19f9813fd4..d228611160 100644 --- a/src/compat.h +++ b/src/compat.h @@ -14,10 +14,10 @@ // GCC 4.8 is missing some C++11 type_traits, // https://www.gnu.org/software/gcc/gcc-5/changes.html -#if defined(__GNUC__) && __GNUC__ < 5 -#define IS_TRIVIALLY_CONSTRUCTIBLE std::is_trivial +#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5 +#define IS_TRIVIALLY_CONSTRUCTIBLE std::has_trivial_default_constructor #else -#define IS_TRIVIALLY_CONSTRUCTIBLE std::is_trivially_constructible +#define IS_TRIVIALLY_CONSTRUCTIBLE std::is_trivially_default_constructible #endif #ifdef WIN32 From 0d00fd5901102d9ca2b99d6f17a3bd96c946e3b7 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 23 Aug 2018 17:24:15 -0400 Subject: [PATCH 0098/1200] depends: allow CC/CXX to be overridden during configure --- depends/config.site.in | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/depends/config.site.in b/depends/config.site.in index 8444dc26f2..b7a5e795c8 100644 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -61,9 +61,12 @@ fi CPPFLAGS="-I$depends_prefix/include/ $CPPFLAGS" LDFLAGS="-L$depends_prefix/lib $LDFLAGS" -CC="@CC@" -CXX="@CXX@" -OBJC="${CC}" +if test -n "@CC@" -a -z "${CC}"; then + CC="@CC@" +fi +if test -n "@CXX@" -a -z "${CXX}"; then + CXX="@CXX@" +fi PYTHONPATH=$depends_prefix/native/lib/python/dist-packages:$PYTHONPATH if test -n "@AR@"; then From 5bb0164ceecc2e61f1839b482e821909e05a736e Mon Sep 17 00:00:00 2001 From: Chun Kuan Lee Date: Sun, 5 Aug 2018 18:08:29 +0000 Subject: [PATCH 0099/1200] depends: Enable unicode support on dbd for Windows --- depends/packages/bdb.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/depends/packages/bdb.mk b/depends/packages/bdb.mk index 6c9876c2c7..3cd2e28858 100644 --- a/depends/packages/bdb.mk +++ b/depends/packages/bdb.mk @@ -10,6 +10,7 @@ $(package)_config_opts=--disable-shared --enable-cxx --disable-replication $(package)_config_opts_mingw32=--enable-mingw $(package)_config_opts_linux=--with-pic $(package)_cxxflags=-std=c++11 +$(package)_cppflags_mingw32=-DUNICODE -D_UNICODE endef define $(package)_preprocess_cmds From ddddce0e46e73d4ca369f2ce9696231cc579e1f9 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 13 Aug 2018 16:13:29 -0400 Subject: [PATCH 0100/1200] util: Replace boost::signals2 with std::function --- src/bench/bench_bitcoin.cpp | 2 ++ src/bitcoin-cli.cpp | 2 ++ src/bitcoin-tx.cpp | 2 ++ src/bitcoind.cpp | 2 ++ src/noui.cpp | 2 ++ src/qt/bitcoin.cpp | 10 +++------- src/qt/bitcoingui.cpp | 2 ++ src/qt/splashscreen.cpp | 4 +++- src/qt/transactiontablemodel.cpp | 4 +++- src/test/test_bitcoin.cpp | 10 ++++++---- src/test/test_bitcoin_fuzzy.cpp | 12 +++++++----- src/util.cpp | 2 -- src/util.h | 23 +++++++---------------- src/wallet/coinselection.cpp | 3 +++ 14 files changed, 44 insertions(+), 36 deletions(-) diff --git a/src/bench/bench_bitcoin.cpp b/src/bench/bench_bitcoin.cpp index 603b858e54..d7b8083e7c 100644 --- a/src/bench/bench_bitcoin.cpp +++ b/src/bench/bench_bitcoin.cpp @@ -13,6 +13,8 @@ #include +const std::function G_TRANSLATION_FUN = nullptr; + static const int64_t DEFAULT_BENCH_EVALUATIONS = 5; static const char* DEFAULT_BENCH_FILTER = ".*"; static const char* DEFAULT_BENCH_SCALING = "1.0"; diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index db713f58d2..c9414e67c7 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -24,6 +24,8 @@ #include +const std::function G_TRANSLATION_FUN = nullptr; + static const char DEFAULT_RPCCONNECT[] = "127.0.0.1"; static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900; static const bool DEFAULT_NAMED=false; diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 5fef4724c9..20f0218ac1 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -31,6 +31,8 @@ static bool fCreateBlank; static std::map registers; static const int CONTINUE_EXECUTION=-1; +const std::function G_TRANSLATION_FUN = nullptr; + static void SetupBitcoinTxArgs() { gArgs.AddArg("-?", "This help message", false, OptionsCategory::OPTIONS); diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 06f8622426..bf04d95b50 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -23,6 +23,8 @@ #include +const std::function G_TRANSLATION_FUN = nullptr; + /* Introduction text for doxygen: */ /*! \mainpage Developer documentation diff --git a/src/noui.cpp b/src/noui.cpp index e6d01e7b26..3a1ec2d050 100644 --- a/src/noui.cpp +++ b/src/noui.cpp @@ -12,6 +12,8 @@ #include #include +#include + static bool noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style) { bool fSecure = style & CClientUIInterface::SECURE; diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index d3ec67e441..5da54c5b2d 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -76,13 +76,10 @@ static void InitMessage(const std::string &message) LogPrintf("init message: %s\n", message); } -/* - Translate string to current locale using Qt. - */ -static std::string Translate(const char* psz) -{ +/** Translate string to current locale using Qt. */ +const std::function G_TRANSLATION_FUN = [](const char* psz) { return QCoreApplication::translate("bitcoin-core", psz).toStdString(); -} +}; static QString GetLangTerritory() { @@ -619,7 +616,6 @@ int main(int argc, char *argv[]) // Now that QSettings are accessible, initialize translations QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator; initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator); - translationInterface.Translate.connect(Translate); // Show help message immediately after parsing command-line options (for "-lang") and setting locale, // but before showing splash screen. diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index e2488092e2..71bfe74de5 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -57,6 +57,8 @@ #include #include +#include + const std::string BitcoinGUI::DEFAULT_UIPLATFORM = #if defined(Q_OS_MAC) "macosx" diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index e438d22919..0b111cc6d7 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -14,8 +14,8 @@ #include #include #include -#include #include +#include #include #include @@ -24,6 +24,8 @@ #include #include +#include + SplashScreen::SplashScreen(interfaces::Node& node, Qt::WindowFlags f, const NetworkStyle *networkStyle) : QWidget(0, f), curAlignment(0), m_node(node) { diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index e100cac533..3443852023 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -16,10 +16,10 @@ #include #include #include -#include #include #include #include +#include #include #include @@ -27,6 +27,8 @@ #include #include +#include + // Amount column is right-aligned it contains numbers static int column_alignments[] = { Qt::AlignLeft|Qt::AlignVCenter, /* status */ diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 9c3285fb0c..a89bf785f1 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -8,15 +8,17 @@ #include #include #include -#include #include #include #include -#include -#include -#include #include +#include #include