From 5412789739ce18e46918d3ba27cec936c0c96df5 Mon Sep 17 00:00:00 2001 From: Anthony Towns Date: Fri, 20 Nov 2020 05:23:25 +1000 Subject: [PATCH 01/84] tests: shrink feature_taproot transfer of funds tx (cherry picked from commit 7ffac12545328cadd92a3caec4f1c6ca7c127493) --- test/functional/feature_taproot.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/test/functional/feature_taproot.py b/test/functional/feature_taproot.py index ff0ce58e85..ea52769ebb 100755 --- a/test/functional/feature_taproot.py +++ b/test/functional/feature_taproot.py @@ -1475,17 +1475,23 @@ class TaprootTest(BitcoinTestFramework): g_genesis_hash = uint256_from_str(bytes.fromhex(self.nodes[1].getblockhash(0))[::-1]) self.test_spenders(self.nodes[1], spenders_taproot_active(), input_counts=[1, 2, 2, 2, 2, 3]) - # Transfer funds to pre-taproot node. + # Transfer value of the largest 500 coins to pre-taproot node. addr = self.nodes[0].getnewaddress() + + unsp = self.nodes[1].listunspent() + unsp = sorted(unsp, key=lambda i: i['amount'], reverse=True) + unsp = unsp[:500] + rawtx = self.nodes[1].createrawtransaction( inputs=[{ 'txid': i['txid'], 'vout': i['vout'] - } for i in self.nodes[1].listunspent()], - outputs=[{addr: self.nodes[1].getbalance()['bitcoin']}], + } for i in unsp], + outputs=[{addr: sum(i['amount'] for i in unsp)}] ) rawtx = self.nodes[1].signrawtransactionwithwallet(rawtx)['hex'] - # Transaction is too large to fit into the mempool, so put it into a block + + # Mine a block with the transaction block = create_block(tmpl=self.nodes[1].getblocktemplate(NORMAL_GBT_REQUEST_PARAMS), txlist=[rawtx]) add_witness_commitment(block) block.rehash() From 4f36e4cfc685e5e0f025067025b4e68267c981e1 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sat, 21 Nov 2020 19:06:25 +0000 Subject: [PATCH 02/84] RPC/Wallet: unloadwallet: Clarify docs/error when both the RPC endpoint and wallet_name parameter specify a wallet (cherry picked from commit b1f59d55d920d2b35269b474762f94fec87bfb16) --- src/wallet/rpcwallet.cpp | 4 ++-- test/functional/wallet_multiwallet.py | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index c4f30b9973..b961d70355 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2954,7 +2954,7 @@ static RPCHelpMan unloadwallet() "Unloads the wallet referenced by the request endpoint otherwise unloads the wallet specified in the argument.\n" "Specifying the wallet name on a wallet endpoint is invalid.", { - {"wallet_name", RPCArg::Type::STR, /* default */ "the wallet name from the RPC request", "The name of the wallet to unload."}, + {"wallet_name", RPCArg::Type::STR, /* default */ "the wallet name from the RPC endpoint", "The name of the wallet to unload. Must be provided in the RPC endpoint or this parameter (but not both)."}, {"load_on_startup", RPCArg::Type::BOOL, /* default */ "null", "Save wallet name to persistent settings and load on startup. True to add wallet to startup list, false to remove, null to leave unchanged."}, }, RPCResult{RPCResult::Type::OBJ, "", "", { @@ -2969,7 +2969,7 @@ static RPCHelpMan unloadwallet() std::string wallet_name; if (GetWalletNameFromJSONRPCRequest(request, wallet_name)) { if (!request.params[0].isNull()) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot unload the requested wallet"); + throw JSONRPCError(RPC_INVALID_PARAMETER, "Both the RPC endpoint wallet and wallet_name parameter were provided (only one allowed)"); } } else { wallet_name = request.params[0].get_str(); diff --git a/test/functional/wallet_multiwallet.py b/test/functional/wallet_multiwallet.py index f9c7fc4234..438514c4e2 100755 --- a/test/functional/wallet_multiwallet.py +++ b/test/functional/wallet_multiwallet.py @@ -355,7 +355,8 @@ class MultiWalletTest(BitcoinTestFramework): assert_raises_rpc_error(-1, "JSON value is not a string as expected", self.nodes[0].unloadwallet) assert_raises_rpc_error(-18, "Requested wallet does not exist or is not loaded", self.nodes[0].unloadwallet, "dummy") assert_raises_rpc_error(-18, "Requested wallet does not exist or is not loaded", node.get_wallet_rpc("dummy").unloadwallet) - assert_raises_rpc_error(-8, "Cannot unload the requested wallet", w1.unloadwallet, "w2"), + assert_raises_rpc_error(-8, "Both the RPC endpoint wallet and wallet_name parameter were provided (only one allowed)", w1.unloadwallet, "w2"), + assert_raises_rpc_error(-8, "Both the RPC endpoint wallet and wallet_name parameter were provided (only one allowed)", w1.unloadwallet, "w1"), # Successfully unload the specified wallet name self.nodes[0].unloadwallet("w1") From ae8a5a5baa2698073ad61f25cec8631630ee8370 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Sat, 21 Nov 2020 01:51:48 -0500 Subject: [PATCH 03/84] Fix QPainter non-determinism on macOS Aplies a patch to Qt that fixes the non-determinism by modifying Qt. The source of the non-determinism is how LLVM 8 optimizes qt_intersect_spans when compiling. The particular optimization that seems to be causing the problems is that a temp variable is being added for spans->y. For some reason, when it does this, it chooses different instructions to use when making that variable. We bypass this problem by patching qt_intersect_spans to always make and use this local variable. Github-Pull: #20447 Rebased-From: 8f7d1b39efbe65ab2747c593cc3560d4a449a333 Tree-SHA512: 558da5c2bb0373e2a89f2c219170f802036e0e87cc8e808336b23d074152cb893007a440f46ec957156b0921355cd18502710f2d224f27bc26e934c50ebebc41 (cherry picked from commit ab23a83400d5ad13137ce0f9697a51f0b70e9d29) --- depends/packages/qt.mk | 2 + .../qt/fix_qpainter_non_determinism.patch | 63 +++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 depends/patches/qt/fix_qpainter_non_determinism.patch diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 083bc68d66..2a9e066510 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -12,6 +12,7 @@ $(package)_patches=fix_qt_pkgconfig.patch mac-qmake.conf fix_configure_mac.patch $(package)_patches+= fix_rcc_determinism.patch fix_riscv64_arch.patch xkb-default.patch no-xlib.patch $(package)_patches+= fix_android_qmake_conf.patch fix_android_jni_static.patch dont_hardcode_pwd.patch $(package)_patches+= freetype_back_compat.patch drop_lrelease_dependency.patch fix_powerpc_libpng.patch +$(package)_patches+= fix_qpainter_non_determinism.patch # Update OSX_QT_TRANSLATIONS when this is updated $(package)_qttranslations_file_name=qttranslations-$($(package)_suffix) @@ -195,6 +196,7 @@ endef define $(package)_preprocess_cmds patch -p1 -i $($(package)_patch_dir)/freetype_back_compat.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_powerpc_libpng.patch && \ + patch -p1 -i $($(package)_patch_dir)/fix_qpainter_non_determinism.patch &&\ sed -i.old "s|updateqm.commands = \$$$$\$$$$LRELEASE|updateqm.commands = $($(package)_extract_dir)/qttools/bin/lrelease|" qttranslations/translations/translations.pro && \ patch -p1 -i $($(package)_patch_dir)/drop_lrelease_dependency.patch && \ patch -p1 -i $($(package)_patch_dir)/dont_hardcode_pwd.patch &&\ diff --git a/depends/patches/qt/fix_qpainter_non_determinism.patch b/depends/patches/qt/fix_qpainter_non_determinism.patch new file mode 100644 index 0000000000..3cfcc22f03 --- /dev/null +++ b/depends/patches/qt/fix_qpainter_non_determinism.patch @@ -0,0 +1,63 @@ +commit 2a8f7dc6ddfc414a66491522501c1574a1343ee1 +Author: Andrew Chow +Date: Sat Nov 21 01:11:04 2020 -0500 + + build: Fix determinism issue when building with Clang 8 + + When building Qt with LLVM/Clang 8 under -O3 (the default), we run into + a determinism issue in `qt_interset_spans`. The issue has been fixed for + LLVM/Clang 9, see + https://github.com/llvm/llvm-project/commit/db101864bdc938deb1d63fe4f7da761bd38e5cae + and https://reviews.llvm.org/D64601, however this fix was not backported + to 8.x. Once LLVM/Clang 9 is used, this patch can be dropped. + + The particular issue appears to be an optimization done by -O3 which + adds a temporary variable for `spans->y` in `qt_intersect_spans`. When + it does this, sometimes it chooses to use a 32-bit movs instruction + (movswl), and other times it chooses a 64-bit movs instruction (movswq). + By patching `qt_intersect_spans` to always make a temporary variable for + `spans->y`, we are able to sidestep this problem. + +diff --git a/qtbase/src/gui/painting/qpaintengine_raster.cpp b/qtbase/src/gui/painting/qpaintengine_raster.cpp +index 92ab6e8375..f018009e0b 100644 +--- a/qtbase/src/gui/painting/qpaintengine_raster.cpp ++++ b/qtbase/src/gui/painting/qpaintengine_raster.cpp +@@ -3971,22 +3971,23 @@ static const QSpan *qt_intersect_spans(const QClipData *clip, int *currentClip, + const QSpan *clipEnd = clip->m_spans + clip->count; + + while (available && spans < end ) { ++ const short spans_y = spans->y; + if (clipSpans >= clipEnd) { + spans = end; + break; + } +- if (clipSpans->y > spans->y) { ++ if (clipSpans->y > spans_y) { + ++spans; + continue; + } +- if (spans->y != clipSpans->y) { +- if (spans->y < clip->count && clip->m_clipLines[spans->y].spans) +- clipSpans = clip->m_clipLines[spans->y].spans; ++ if (spans_y != clipSpans->y) { ++ if (spans_y < clip->count && clip->m_clipLines[spans_y].spans) ++ clipSpans = clip->m_clipLines[spans_y].spans; + else + ++clipSpans; + continue; + } +- Q_ASSERT(spans->y == clipSpans->y); ++ Q_ASSERT(spans_y == clipSpans->y); + + int sx1 = spans->x; + int sx2 = sx1 + spans->len; +@@ -4005,7 +4006,7 @@ static const QSpan *qt_intersect_spans(const QClipData *clip, int *currentClip, + if (len) { + out->x = qMax(sx1, cx1); + out->len = qMin(sx2, cx2) - out->x; +- out->y = spans->y; ++ out->y = spans_y; + out->coverage = qt_div_255(spans->coverage * clipSpans->coverage); + ++out; + --available; + From 029b6799d16cf467e295016e7ff022fa1fe88faf Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 23 Nov 2020 09:27:29 +0100 Subject: [PATCH 04/84] test: Fix intermittent issue in mempool_compatibility (cherry picked from commit fa05d19bd6ba619bb3f9aabc05c439cd18d34544) --- test/functional/mempool_compatibility.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/functional/mempool_compatibility.py b/test/functional/mempool_compatibility.py index 7168cb4ab2..8ac91bd008 100755 --- a/test/functional/mempool_compatibility.py +++ b/test/functional/mempool_compatibility.py @@ -29,7 +29,7 @@ class MempoolCompatibilityTest(BitcoinTestFramework): def setup_network(self): self.add_nodes(self.num_nodes, versions=[ - 150200, # oldest version supported by the test framework + 190100, # oldest version with getmempoolinfo.loaded (used to avoid intermittent issues) None, ]) self.start_nodes() @@ -72,5 +72,6 @@ class MempoolCompatibilityTest(BitcoinTestFramework): assert old_tx_hash in old_node.getrawmempool() assert unbroadcasted_tx_hash in old_node.getrawmempool() + if __name__ == "__main__": MempoolCompatibilityTest().main() From 2fe52979ea62cc832e1aff7faada79ee93d66b09 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 17 Nov 2020 20:22:01 +0100 Subject: [PATCH 05/84] refactor: Change pointer to reference because it can not be null (cherry picked from commit fac4e136fa3d0fab7fde900a6be921313e16e7a6) --- src/wallet/rpcwallet.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index b961d70355..53e01f666a 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -221,7 +221,7 @@ static std::string LabelFromValue(const UniValue& value) /** * Update coin control with fee estimation based on the given parameters * - * @param[in] pwallet Wallet pointer + * @param[in] wallet Wallet reference * @param[in,out] cc Coin control to be updated * @param[in] conf_target UniValue integer; confirmation target in blocks, values between 1 and 1008 are valid per policy/fees.h; * if a fee_rate is present, 0 is allowed here as a no-op positional placeholder @@ -233,7 +233,7 @@ static std::string LabelFromValue(const UniValue& value) * verify only that fee_rate is greater than 0 * @throws a JSONRPCError if conf_target, estimate_mode, or fee_rate contain invalid values or are in conflict */ -static void SetFeeEstimateMode(const CWallet* pwallet, CCoinControl& cc, const UniValue& conf_target, const UniValue& estimate_mode, const UniValue& fee_rate, bool override_min_fee) +static void SetFeeEstimateMode(const CWallet& wallet, CCoinControl& cc, const UniValue& conf_target, const UniValue& estimate_mode, const UniValue& fee_rate, bool override_min_fee) { if (!fee_rate.isNull()) { if (!conf_target.isNull() && conf_target.get_int() > 0) { @@ -258,7 +258,7 @@ static void SetFeeEstimateMode(const CWallet* pwallet, CCoinControl& cc, const U throw JSONRPCError(RPC_INVALID_PARAMETER, InvalidEstimateModeErrorMessage()); } if (!conf_target.isNull()) { - cc.m_confirm_target = ParseConfirmTarget(conf_target, pwallet->chain().estimateMaxBlocks()); + cc.m_confirm_target = ParseConfirmTarget(conf_target, wallet.chain().estimateMaxBlocks()); } } @@ -578,7 +578,7 @@ static RPCHelpMan sendtoaddress() ignore_blind_fail = request.params[10].get_bool(); } - SetFeeEstimateMode(pwallet, coin_control, /* conf_target */ request.params[6], /* estimate_mode */ request.params[7], /* fee_rate */ request.params[11], /* override_min_fee */ false); + SetFeeEstimateMode(*pwallet, coin_control, /* conf_target */ request.params[6], /* estimate_mode */ request.params[7], /* fee_rate */ request.params[11], /* override_min_fee */ false); EnsureWalletIsUnlocked(pwallet); @@ -1045,7 +1045,7 @@ static RPCHelpMan sendmany() coin_control.m_signal_bip125_rbf = request.params[5].get_bool(); } - SetFeeEstimateMode(pwallet, coin_control, /* conf_target */ request.params[6], /* estimate_mode */ request.params[7], /* fee_rate */ request.params[10], /* override_min_fee */ false); + SetFeeEstimateMode(*pwallet, coin_control, /* conf_target */ request.params[6], /* estimate_mode */ request.params[7], /* fee_rate */ request.params[10], /* override_min_fee */ false); UniValue assets; if (!request.params[8].isNull()) { @@ -3393,7 +3393,7 @@ void FundTransaction(CWallet* const pwallet, CMutableTransaction& tx, CAmount& f if (options.exists("replaceable")) { coinControl.m_signal_bip125_rbf = options["replaceable"].get_bool(); } - SetFeeEstimateMode(pwallet, coinControl, options["conf_target"], options["estimate_mode"], options["fee_rate"], override_min_fee); + SetFeeEstimateMode(*pwallet, coinControl, options["conf_target"], options["estimate_mode"], options["fee_rate"], override_min_fee); } } else { // if options is null and not a bool @@ -3802,7 +3802,7 @@ static RPCHelpMan bumpfee_helper(std::string method_name) if (options.exists("replaceable")) { coin_control.m_signal_bip125_rbf = options["replaceable"].get_bool(); } - SetFeeEstimateMode(pwallet, coin_control, conf_target, options["estimate_mode"], options["fee_rate"], /* override_min_fee */ false); + SetFeeEstimateMode(*pwallet, coin_control, conf_target, options["estimate_mode"], options["fee_rate"], /* override_min_fee */ false); } // Make sure the results are valid at least up to the most recent block From ae26ff27a99a3a36de600f95f01dfe5318ddb5c0 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 17 Nov 2020 20:08:30 +0100 Subject: [PATCH 06/84] wallet: Do not treat default constructed types as None-type (cherry picked from commit fa69c2c78455fd0dc436018fece9ff7fc83a180d) --- src/wallet/rpcwallet.cpp | 18 ++++++++---------- test/functional/wallet_basic.py | 6 ++---- test/functional/wallet_send.py | 9 ++++----- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 53e01f666a..744738c642 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -224,11 +224,9 @@ static std::string LabelFromValue(const UniValue& value) * @param[in] wallet Wallet reference * @param[in,out] cc Coin control to be updated * @param[in] conf_target UniValue integer; confirmation target in blocks, values between 1 and 1008 are valid per policy/fees.h; - * if a fee_rate is present, 0 is allowed here as a no-op positional placeholder * @param[in] estimate_mode UniValue string; fee estimation mode, valid values are "unset", "economical" or "conservative"; - * if a fee_rate is present, "" is allowed here as a no-op positional placeholder * @param[in] fee_rate UniValue real; fee rate in sat/vB; - * if a fee_rate is present, both conf_target and estimate_mode must either be null, or no-op + * if present, both conf_target and estimate_mode must either be null, or "unset" * @param[in] override_min_fee bool; whether to set fOverrideFeeRate to true to disable minimum fee rate checks and instead * verify only that fee_rate is greater than 0 * @throws a JSONRPCError if conf_target, estimate_mode, or fee_rate contain invalid values or are in conflict @@ -236,10 +234,10 @@ static std::string LabelFromValue(const UniValue& value) static void SetFeeEstimateMode(const CWallet& wallet, CCoinControl& cc, const UniValue& conf_target, const UniValue& estimate_mode, const UniValue& fee_rate, bool override_min_fee) { if (!fee_rate.isNull()) { - if (!conf_target.isNull() && conf_target.get_int() > 0) { + if (!conf_target.isNull()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both conf_target and fee_rate. Please provide either a confirmation target in blocks for automatic fee estimation, or an explicit fee rate."); } - if (!estimate_mode.isNull() && !estimate_mode.get_str().empty()) { + if (!estimate_mode.isNull() && estimate_mode.get_str() != "unset") { throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both estimate_mode and fee_rate"); } CFeeRate fee_rate_in_sat_vb{CFeeRate(AmountFromValue(fee_rate), COIN)}; @@ -523,8 +521,8 @@ static RPCHelpMan sendtoaddress() + HelpExampleCli("sendtoaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 0.1") + "\nSend 0.1 BTC with a confirmation target of 6 blocks in economical fee estimate mode using positional arguments\n" + HelpExampleCli("sendtoaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 0.1 \"donation\" \"sean's outpost\" false true 6 economical") + - "\nSend 0.1 BTC with a fee rate of 1 " + CURRENCY_ATOM + "/vB, subtract fee from amount, BIP125-replaceable, using positional arguments\n" - + HelpExampleCli("sendtoaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 0.1 \"drinks\" \"room77\" true true 0 \"\" 1") + + "\nSend 0.1 BTC with a fee rate of 1.1 " + CURRENCY_ATOM + "/vB, subtract fee from amount, BIP125-replaceable, using positional arguments\n" + + HelpExampleCli("sendtoaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 0.1 \"drinks\" \"room77\" true true null \"unset\" null 1.1") + "\nSend 0.2 BTC with a confirmation target of 6 blocks in economical fee estimate mode using named arguments\n" + HelpExampleCli("-named sendtoaddress", "address=\"" + EXAMPLE_ADDRESS[0] + "\" amount=0.2 conf_target=6 estimate_mode=\"economical\"") + "\nSend 0.5 BTC with a fee rate of 25 " + CURRENCY_ATOM + "/vB using named arguments\n" @@ -4488,10 +4486,10 @@ static RPCHelpMan send() RPCExamples{"" "\nSend 0.1 BTC with a confirmation target of 6 blocks in economical fee estimate mode\n" + HelpExampleCli("send", "'{\"" + EXAMPLE_ADDRESS[0] + "\": 0.1}' 6 economical\n") + - "Send 0.2 BTC with a fee rate of 1 " + CURRENCY_ATOM + "/vB using positional arguments\n" - + HelpExampleCli("send", "'{\"" + EXAMPLE_ADDRESS[0] + "\": 0.2}' 0 \"\" 1\n") + + "Send 0.2 BTC with a fee rate of 1.1 " + CURRENCY_ATOM + "/vB using positional arguments\n" + + HelpExampleCli("send", "'{\"" + EXAMPLE_ADDRESS[0] + "\": 0.2}' null \"unset\" 1.1\n") + "Send 0.2 BTC with a fee rate of 1 " + CURRENCY_ATOM + "/vB using the options argument\n" - + HelpExampleCli("send", "'{\"" + EXAMPLE_ADDRESS[0] + "\": 0.2}' '{\"fee_rate\": 1}'\n") + + + HelpExampleCli("send", "'{\"" + EXAMPLE_ADDRESS[0] + "\": 0.2}' null \"unset\" null '{\"fee_rate\": 1}'\n") + "Send 0.3 BTC with a fee rate of 25 " + CURRENCY_ATOM + "/vB using named arguments\n" + HelpExampleCli("-named send", "outputs='{\"" + EXAMPLE_ADDRESS[0] + "\": 0.3}' fee_rate=25\n") + "Create a transaction that should confirm the next block, with a specific input, and return result without adding to wallet or broadcasting to the network\n" diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py index 6a31d9e82e..9355ceb3ca 100755 --- a/test/functional/wallet_basic.py +++ b/test/functional/wallet_basic.py @@ -234,8 +234,7 @@ class WalletTest(BitcoinTestFramework): fee_rate_btc_kvb = fee_rate_sat_vb * 1e3 / 1e8 explicit_fee_rate_btc_kvb = Decimal(fee_rate_btc_kvb) / 1000 - # Passing conf_target 0, estimate_mode "" as placeholder arguments should allow fee_rate to apply. - txid = self.nodes[2].sendmany(amounts={address: 10}, conf_target=0, estimate_mode="", fee_rate=fee_rate_sat_vb) + txid = self.nodes[2].sendmany(amounts={address: 10}, fee_rate=fee_rate_sat_vb) self.nodes[2].generate(1) self.sync_all(self.nodes[0:3]) balance = self.nodes[2].getbalance()['bitcoin'] @@ -408,8 +407,7 @@ class WalletTest(BitcoinTestFramework): fee_rate_sat_vb = 2 fee_rate_btc_kvb = fee_rate_sat_vb * 1e3 / 1e8 - # Passing conf_target 0, estimate_mode "" as placeholder arguments should allow fee_rate to apply. - txid = self.nodes[2].sendtoaddress(address=address, amount=amount, conf_target=0, estimate_mode="", fee_rate=fee_rate_sat_vb) + txid = self.nodes[2].sendtoaddress(address=address, amount=amount, fee_rate=fee_rate_sat_vb) tx_size = self.get_vsize(self.nodes[2].gettransaction(txid)['hex']) self.nodes[0].generate(1) self.sync_all(self.nodes[0:3]) diff --git a/test/functional/wallet_send.py b/test/functional/wallet_send.py index 37757a3116..305795f0dc 100755 --- a/test/functional/wallet_send.py +++ b/test/functional/wallet_send.py @@ -265,17 +265,16 @@ class WalletSendTest(BitcoinTestFramework): #res2 = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, fee_rate=1, add_to_wallet=False) #assert_equal(self.nodes[1].decodepsbt(res1["psbt"])["fee"], self.nodes[1].decodepsbt(res2["psbt"])["fee"]) - # Passing conf_target 0, estimate_mode "" as placeholder arguments should allow fee_rate to apply. - res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, conf_target=0, estimate_mode="", fee_rate=7, add_to_wallet=False) + res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, fee_rate=7, add_to_wallet=False) #fee = self.nodes[1].decodepsbt(res["psbt"])["fee"] #assert_fee_amount(fee, Decimal(len(res["hex"]) / 2), Decimal("0.00007")) - res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, fee_rate=2, add_to_wallet=False) + # "unset" and None are treated the same for estimate_mode + res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, fee_rate=2, estimate_mode="unset", add_to_wallet=False) #fee = self.nodes[1].decodepsbt(res["psbt"])["fee"] #assert_fee_amount(fee, Decimal(len(res["hex"]) / 2), Decimal("0.00002")) - # Passing conf_target 0, estimate_mode "" as placeholder arguments should allow fee_rate to apply. - res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, arg_conf_target=0, arg_estimate_mode="", arg_fee_rate=4.531, add_to_wallet=False) + res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, arg_fee_rate=4.531, add_to_wallet=False) #fee = self.nodes[1].decodepsbt(res["psbt"])["fee"] #assert_fee_amount(fee, Decimal(len(res["hex"]) / 2), Decimal("0.00004531")) From 9c3df80c4027d053e3d34ddb8133546a64f6dd10 Mon Sep 17 00:00:00 2001 From: Jon Atack Date: Mon, 16 Nov 2020 18:55:32 +0100 Subject: [PATCH 07/84] wallet: refactor GetClosestWalletFeature() (cherry picked from commit c46c18b788cb0862aafbb116fd37936cbed6a431) --- src/wallet/walletutil.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/wallet/walletutil.cpp b/src/wallet/walletutil.cpp index 2301328db1..7a12028600 100644 --- a/src/wallet/walletutil.cpp +++ b/src/wallet/walletutil.cpp @@ -87,13 +87,9 @@ bool IsFeatureSupported(int wallet_version, int feature_version) WalletFeature GetClosestWalletFeature(int version) { - if (version >= FEATURE_LATEST) return FEATURE_LATEST; - if (version >= FEATURE_PRE_SPLIT_KEYPOOL) return FEATURE_PRE_SPLIT_KEYPOOL; - if (version >= FEATURE_NO_DEFAULT_KEY) return FEATURE_NO_DEFAULT_KEY; - if (version >= FEATURE_HD_SPLIT) return FEATURE_HD_SPLIT; - if (version >= FEATURE_HD) return FEATURE_HD; - if (version >= FEATURE_COMPRPUBKEY) return FEATURE_COMPRPUBKEY; - if (version >= FEATURE_WALLETCRYPT) return FEATURE_WALLETCRYPT; - if (version >= FEATURE_BASE) return FEATURE_BASE; + const std::array wallet_features{{FEATURE_LATEST, FEATURE_PRE_SPLIT_KEYPOOL, FEATURE_NO_DEFAULT_KEY, FEATURE_HD_SPLIT, FEATURE_HD, FEATURE_COMPRPUBKEY, FEATURE_WALLETCRYPT, FEATURE_BASE}}; + for (const WalletFeature& wf : wallet_features) { + if (version >= wf) return wf; + } return static_cast(0); } From 92251542e56458414f3be7af2377ad0c7068e932 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Wed, 18 Nov 2020 13:14:19 -0500 Subject: [PATCH 08/84] Don't upgrade to HD split if it is already supported It is unnecessary to upgrade to FEATURE_HD_SPLIT if this feature is already supported by the wallet. Because upgrading to FEATURE_HD_SPLIT actually requires upgrading to FEATURE_PRE_SPLIT_KEYPOOL, users would accidentally be upgraded to FEATURE_PRE_SPLIT_KEYPOOL instead of nothing being done. Fixes the issue described at https://github.com/bitcoin/bitcoin/pull/20403#discussion_r526063920 (cherry picked from commit 2498b04ce88696a3216fc38b7d393906b733e8b1) --- src/wallet/scriptpubkeyman.cpp | 2 +- test/functional/wallet_upgradewallet.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp index b33e3d5179..752a0c3e45 100644 --- a/src/wallet/scriptpubkeyman.cpp +++ b/src/wallet/scriptpubkeyman.cpp @@ -460,7 +460,7 @@ bool LegacyScriptPubKeyMan::Upgrade(int prev_version, int new_version, bilingual hd_upgrade = true; } // Upgrade to HD chain split if necessary - if (IsFeatureSupported(new_version, FEATURE_HD_SPLIT)) { + if (!IsFeatureSupported(prev_version, FEATURE_HD_SPLIT) && IsFeatureSupported(new_version, FEATURE_HD_SPLIT)) { WalletLogPrintf("Upgrading wallet to use HD chain split\n"); m_storage.SetMinVersion(FEATURE_PRE_SPLIT_KEYPOOL); split_upgrade = FEATURE_HD_SPLIT > prev_version; diff --git a/test/functional/wallet_upgradewallet.py b/test/functional/wallet_upgradewallet.py index 8ab4b3f76c..8d3cd16ffc 100755 --- a/test/functional/wallet_upgradewallet.py +++ b/test/functional/wallet_upgradewallet.py @@ -338,6 +338,7 @@ class UpgradeWalletTest(BitcoinTestFramework): new_kvs = dump_bdb_kv(node_master_wallet) up_defaultkey = new_kvs[b'\x0adefaultkey'] assert_equal(defaultkey, up_defaultkey) + assert_equal(wallet.getwalletinfo()["walletversion"], 159900) # 0.16.3 doesn't have a default key v16_3_kvs = dump_bdb_kv(v16_3_wallet) assert b'\x0adefaultkey' not in v16_3_kvs From 77627d8efd47a59a2347e1a13c036eb1c9d41809 Mon Sep 17 00:00:00 2001 From: Jon Atack Date: Mon, 16 Nov 2020 18:23:10 +0100 Subject: [PATCH 09/84] wallet: fix and improve upgradewallet result responses (cherry picked from commit 99d56e357159c7154f69f28cb5587c5ca20d6594) --- src/wallet/rpcwallet.cpp | 28 +++++++++++-- test/functional/wallet_upgradewallet.py | 55 ++++++++++++------------- 2 files changed, 51 insertions(+), 32 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 744738c642..085c750b9d 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4646,7 +4646,7 @@ static RPCHelpMan sethdseed() // Do not do anything to non-HD wallets if (!pwallet->CanSupportFeature(FEATURE_HD)) { - throw JSONRPCError(RPC_WALLET_ERROR, "Cannot set a HD seed on a non-HD wallet. Use the upgradewallet RPC in order to upgrade a non-HD wallet to HD"); + throw JSONRPCError(RPC_WALLET_ERROR, "Cannot set an HD seed on a non-HD wallet. Use the upgradewallet RPC in order to upgrade a non-HD wallet to HD"); } EnsureWalletIsUnlocked(pwallet); @@ -5024,14 +5024,18 @@ static RPCHelpMan walletcreatefundedpsbt() static RPCHelpMan upgradewallet() { return RPCHelpMan{"upgradewallet", - "\nUpgrade the wallet. Upgrades to the latest version if no version number is specified\n" + "\nUpgrade the wallet. Upgrades to the latest version if no version number is specified.\n" "New keys may be generated and a new wallet backup will need to be made.", { - {"version", RPCArg::Type::NUM, /* default */ strprintf("%d", FEATURE_LATEST), "The version number to upgrade to. Default is the latest wallet version"} + {"version", RPCArg::Type::NUM, /* default */ strprintf("%d", FEATURE_LATEST), "The version number to upgrade to. Default is the latest wallet version."} }, RPCResult{ RPCResult::Type::OBJ, "", "", { + {RPCResult::Type::STR, "wallet_name", "Name of wallet this operation was performed on"}, + {RPCResult::Type::NUM, "previous_version", "Version of wallet before this operation"}, + {RPCResult::Type::NUM, "current_version", "Version of wallet after this operation"}, + {RPCResult::Type::STR, "result", /* optional */ true, "Description of result, if no error"}, {RPCResult::Type::STR, "error", /* optional */ true, "Error message (if there is one)"} }, }, @@ -5054,10 +5058,26 @@ static RPCHelpMan upgradewallet() version = request.params[0].get_int(); } bilingual_str error; - if (!pwallet->UpgradeWallet(version, error)) { + const int previous_version{pwallet->GetVersion()}; + const bool wallet_upgraded{pwallet->UpgradeWallet(version, error)}; + const int current_version{pwallet->GetVersion()}; + std::string result; + + if (!wallet_upgraded) { throw JSONRPCError(RPC_WALLET_ERROR, error.original); + } else if (previous_version == current_version) { + result = "Already at latest version. Wallet version unchanged."; + } else { + result = strprintf("Wallet upgraded successfully from version %i to version %i.", previous_version, current_version); } + UniValue obj(UniValue::VOBJ); + obj.pushKV("wallet_name", pwallet->GetName()); + obj.pushKV("previous_version", previous_version); + obj.pushKV("current_version", current_version); + if (!result.empty()) { + obj.pushKV("result", result); + } if (!error.empty()) { obj.pushKV("error", error.original); } diff --git a/test/functional/wallet_upgradewallet.py b/test/functional/wallet_upgradewallet.py index 8d3cd16ffc..bcfa1a93f4 100755 --- a/test/functional/wallet_upgradewallet.py +++ b/test/functional/wallet_upgradewallet.py @@ -22,7 +22,6 @@ from test_framework.messages import deser_compact_size, deser_string from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, - assert_greater_than, assert_is_hex_string, assert_raises_rpc_error, sha256sum_file, @@ -92,6 +91,20 @@ class UpgradeWalletTest(BitcoinTestFramework): v16_3_node.submitblock(b) assert_equal(v16_3_node.getblockcount(), to_height) + def test_upgradewallet(self, wallet, previous_version, requested_version=None, expected_version=None): + unchanged = expected_version == previous_version + new_version = previous_version if unchanged else expected_version if expected_version else requested_version + assert_equal(wallet.getwalletinfo()["walletversion"], previous_version) + assert_equal(wallet.upgradewallet(requested_version), + { + "wallet_name": "", + "previous_version": previous_version, + "current_version": new_version, + "result": "Already at latest version. Wallet version unchanged." if unchanged else "Wallet upgraded successfully from version {} to version {}.".format(previous_version, new_version), + } + ) + assert_equal(wallet.getwalletinfo()["walletversion"], new_version) + def run_test(self): self.nodes[0].generatetoaddress(101, self.nodes[0].getnewaddress()) self.dumb_sync_blocks() @@ -158,14 +171,8 @@ class UpgradeWalletTest(BitcoinTestFramework): self.restart_node(0) copy_v16() wallet = node_master.get_wallet_rpc(self.default_wallet_name) - old_version = wallet.getwalletinfo()["walletversion"] - - # calling upgradewallet without version arguments - # should return nothing if successful - assert_equal(wallet.upgradewallet(), {}) - new_version = wallet.getwalletinfo()["walletversion"] - # upgraded wallet version should be greater than older one - assert_greater_than(new_version, old_version) + self.log.info("Test upgradewallet without a version argument") + self.test_upgradewallet(wallet, previous_version=159900, expected_version=169900) # wallet should still contain the same balance assert_equal(wallet.getbalance(), v16_3_balance) @@ -173,25 +180,20 @@ class UpgradeWalletTest(BitcoinTestFramework): wallet = node_master.get_wallet_rpc(self.default_wallet_name) # should have no master key hash before conversion assert_equal('hdseedid' in wallet.getwalletinfo(), False) - # calling upgradewallet with explicit version number - # should return nothing if successful - assert_equal(wallet.upgradewallet(169900), {}) - new_version = wallet.getwalletinfo()["walletversion"] - # upgraded wallet should have version 169900 - assert_equal(new_version, 169900) + self.log.info("Test upgradewallet with explicit version number") + self.test_upgradewallet(wallet, previous_version=60000, requested_version=169900) # after conversion master key hash should be present assert_is_hex_string(wallet.getwalletinfo()['hdseedid']) - self.log.info('Intermediary versions don\'t effect anything') + self.log.info("Intermediary versions don't effect anything") copy_non_hd() # Wallet starts with 60000 assert_equal(60000, wallet.getwalletinfo()['walletversion']) wallet.unloadwallet() before_checksum = sha256sum_file(node_master_wallet) node_master.loadwallet('') - # Can "upgrade" to 129999 which should have no effect on the wallet - wallet.upgradewallet(129999) - assert_equal(60000, wallet.getwalletinfo()['walletversion']) + # Test an "upgrade" from 60000 to 129999 has no effect, as the next version is 130000 + self.test_upgradewallet(wallet, previous_version=60000, requested_version=129999, expected_version=60000) wallet.unloadwallet() assert_equal(before_checksum, sha256sum_file(node_master_wallet)) node_master.loadwallet('') @@ -208,8 +210,7 @@ class UpgradeWalletTest(BitcoinTestFramework): orig_kvs = dump_bdb_kv(node_master_wallet) assert b'\x07hdchain' not in orig_kvs # Upgrade to HD, no split - wallet.upgradewallet(130000) - assert_equal(130000, wallet.getwalletinfo()['walletversion']) + self.test_upgradewallet(wallet, previous_version=60000, requested_version=130000) # Check that there is now a hd chain and it is version 1, no internal chain counter new_kvs = dump_bdb_kv(node_master_wallet) assert b'\x07hdchain' in new_kvs @@ -244,8 +245,7 @@ class UpgradeWalletTest(BitcoinTestFramework): assert_equal(130000, wallet.getwalletinfo()['walletversion']) self.log.info('Upgrade HD to HD chain split') - wallet.upgradewallet(169900) - assert_equal(169900, wallet.getwalletinfo()['walletversion']) + self.test_upgradewallet(wallet, previous_version=130000, requested_version=169900) # Check that the hdchain updated correctly new_kvs = dump_bdb_kv(node_master_wallet) hd_chain = new_kvs[b'\x07hdchain'] @@ -271,8 +271,7 @@ class UpgradeWalletTest(BitcoinTestFramework): self.log.info('Upgrade non-HD to HD chain split') copy_non_hd() - wallet.upgradewallet(169900) - assert_equal(169900, wallet.getwalletinfo()['walletversion']) + self.test_upgradewallet(wallet, previous_version=60000, requested_version=169900) # Check that the hdchain updated correctly new_kvs = dump_bdb_kv(node_master_wallet) hd_chain = new_kvs[b'\x07hdchain'] @@ -333,15 +332,15 @@ class UpgradeWalletTest(BitcoinTestFramework): # Check the wallet has a default key initially old_kvs = dump_bdb_kv(node_master_wallet) defaultkey = old_kvs[b'\x0adefaultkey'] - # Upgrade the wallet. Should still have the same default key - wallet.upgradewallet(159900) + self.log.info("Upgrade the wallet. Should still have the same default key.") + self.test_upgradewallet(wallet, previous_version=139900, requested_version=159900) new_kvs = dump_bdb_kv(node_master_wallet) up_defaultkey = new_kvs[b'\x0adefaultkey'] assert_equal(defaultkey, up_defaultkey) - assert_equal(wallet.getwalletinfo()["walletversion"], 159900) # 0.16.3 doesn't have a default key v16_3_kvs = dump_bdb_kv(v16_3_wallet) assert b'\x0adefaultkey' not in v16_3_kvs + if __name__ == '__main__': UpgradeWalletTest().main() From df1bd79314c4bc2700c4a2b92b296e7c1d0dce4e Mon Sep 17 00:00:00 2001 From: Jon Atack Date: Tue, 17 Nov 2020 15:57:14 +0100 Subject: [PATCH 10/84] wallet: fix and improve upgradewallet error responses (cherry picked from commit ca8cd893bb56bf5d455154b0498b1f58f77d20ed) --- src/wallet/rpcwallet.cpp | 16 ++++++++-------- test/functional/wallet_upgradewallet.py | 24 ++++++++++++++++-------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 085c750b9d..bad38a83ff 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5063,12 +5063,12 @@ static RPCHelpMan upgradewallet() const int current_version{pwallet->GetVersion()}; std::string result; - if (!wallet_upgraded) { - throw JSONRPCError(RPC_WALLET_ERROR, error.original); - } else if (previous_version == current_version) { - result = "Already at latest version. Wallet version unchanged."; - } else { - result = strprintf("Wallet upgraded successfully from version %i to version %i.", previous_version, current_version); + if (wallet_upgraded) { + if (previous_version == current_version) { + result = "Already at latest version. Wallet version unchanged."; + } else { + result = strprintf("Wallet upgraded successfully from version %i to version %i.", previous_version, current_version); + } } UniValue obj(UniValue::VOBJ); @@ -5077,8 +5077,8 @@ static RPCHelpMan upgradewallet() obj.pushKV("current_version", current_version); if (!result.empty()) { obj.pushKV("result", result); - } - if (!error.empty()) { + } else { + CHECK_NONFATAL(!error.empty()); obj.pushKV("error", error.original); } return obj; diff --git a/test/functional/wallet_upgradewallet.py b/test/functional/wallet_upgradewallet.py index bcfa1a93f4..9b8410e0d5 100755 --- a/test/functional/wallet_upgradewallet.py +++ b/test/functional/wallet_upgradewallet.py @@ -23,7 +23,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, assert_is_hex_string, - assert_raises_rpc_error, sha256sum_file, ) @@ -105,6 +104,18 @@ class UpgradeWalletTest(BitcoinTestFramework): ) assert_equal(wallet.getwalletinfo()["walletversion"], new_version) + def test_upgradewallet_error(self, wallet, previous_version, requested_version, msg): + assert_equal(wallet.getwalletinfo()["walletversion"], previous_version) + assert_equal(wallet.upgradewallet(requested_version), + { + "wallet_name": "", + "previous_version": previous_version, + "current_version": previous_version, + "error": msg, + } + ) + assert_equal(wallet.getwalletinfo()["walletversion"], previous_version) + def run_test(self): self.nodes[0].generatetoaddress(101, self.nodes[0].getnewaddress()) self.dumb_sync_blocks() @@ -200,7 +211,7 @@ class UpgradeWalletTest(BitcoinTestFramework): self.log.info('Wallets cannot be downgraded') copy_non_hd() - assert_raises_rpc_error(-4, 'Cannot downgrade wallet', wallet.upgradewallet, 40000) + self.test_upgradewallet_error(wallet, previous_version=60000, requested_version=40000, msg="Cannot downgrade wallet") wallet.unloadwallet() assert_equal(before_checksum, sha256sum_file(node_master_wallet)) node_master.loadwallet('') @@ -237,12 +248,9 @@ class UpgradeWalletTest(BitcoinTestFramework): assert_equal('m/0\'/0\'/1\'', info['hdkeypath']) self.log.info('Cannot upgrade to HD Split, needs Pre Split Keypool') - assert_raises_rpc_error(-4, 'Cannot upgrade a non HD split wallet without upgrading to support pre split keypool', wallet.upgradewallet, 139900) - assert_equal(130000, wallet.getwalletinfo()['walletversion']) - assert_raises_rpc_error(-4, 'Cannot upgrade a non HD split wallet without upgrading to support pre split keypool', wallet.upgradewallet, 159900) - assert_equal(130000, wallet.getwalletinfo()['walletversion']) - assert_raises_rpc_error(-4, 'Cannot upgrade a non HD split wallet without upgrading to support pre split keypool', wallet.upgradewallet, 169899) - assert_equal(130000, wallet.getwalletinfo()['walletversion']) + for version in [139900, 159900, 169899]: + self.test_upgradewallet_error(wallet, previous_version=130000, requested_version=version, + msg="Cannot upgrade a non HD split wallet without upgrading to support pre split keypool. Please use version 169900 or no version specified.") self.log.info('Upgrade HD to HD chain split') self.test_upgradewallet(wallet, previous_version=130000, requested_version=169900) From 2ca3943fdf1288e75ea022628b958a6e3adb11fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20G=C3=B6gge?= Date: Mon, 23 Nov 2020 23:31:13 +0100 Subject: [PATCH 11/84] build: Avoid secp256k1.h include from system GitHub-Pull: #20469 Rebase-From: e95aaefe2540cb76969818fcc2ff77d33448ed5a (cherry picked from commit 01b647b1a20bbf1de2f5f4624c34b554ad3790f2) --- src/Makefile.am | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index a29a52eb0d..aa31ac8ba2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,9 +20,8 @@ else LIBUNIVALUE = $(UNIVALUE_LIBS) endif -BITCOIN_INCLUDES=-I$(builddir) $(BDB_CPPFLAGS) $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) +BITCOIN_INCLUDES=-I$(builddir) -I$(srcdir)/secp256k1/include $(BDB_CPPFLAGS) $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) -BITCOIN_INCLUDES += -I$(srcdir)/secp256k1/include BITCOIN_INCLUDES += $(UNIVALUE_CFLAGS) LIBBITCOIN_SERVER=libbitcoin_server.a From 765c2b4d17e82d6a1971a7b12d949a104689c2b8 Mon Sep 17 00:00:00 2001 From: Jon Atack Date: Thu, 19 Nov 2020 18:38:00 +0100 Subject: [PATCH 12/84] Allow zero-fee fundrawtxn and walletcreatefundedpsbt calls A check to raise an error on zero-fee txns was mistakenly extended in commit a0d4957 from the bumpfee and send{toaddress, many} RPCs to also include fundrawtransaction and walletcreatefundedpsbt. This commit overrides zero fee rate checking for these two RPCs, not only for the feeRate (BTC/kvB) arg to return to previous behavior, but also for the new fee_rate (sat/vB) arg. Github-Pull: #20426 Rebased-From: 1b3d7009280595108eb22ac1188bc43678 (cherry picked from commit 54e1edcc2bca76f783170768e65bf0850b036b81) --- src/wallet/rpcwallet.cpp | 16 +++------------- test/functional/rpc_fundrawtransaction.py | 16 +++++++++------- test/functional/rpc_psbt.py | 15 ++++++++------- test/functional/wallet_send.py | 8 +++++++- 4 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index bad38a83ff..e2bdfee159 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -240,14 +240,8 @@ static void SetFeeEstimateMode(const CWallet& wallet, CCoinControl& cc, const Un if (!estimate_mode.isNull() && estimate_mode.get_str() != "unset") { throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both estimate_mode and fee_rate"); } - CFeeRate fee_rate_in_sat_vb{CFeeRate(AmountFromValue(fee_rate), COIN)}; - if (override_min_fee) { - if (fee_rate_in_sat_vb <= CFeeRate(0)) { - throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid fee_rate %s (must be greater than 0)", fee_rate_in_sat_vb.ToString(FeeEstimateMode::SAT_VB))); - } - cc.fOverrideFeeRate = true; - } - cc.m_feerate = fee_rate_in_sat_vb; + cc.m_feerate = CFeeRate(AmountFromValue(fee_rate), COIN); + if (override_min_fee) cc.fOverrideFeeRate = true; // Default RBF to true for explicit fee_rate, if unset. if (cc.m_signal_bip125_rbf == nullopt) cc.m_signal_bip125_rbf = true; return; @@ -3377,11 +3371,7 @@ void FundTransaction(CWallet* const pwallet, CMutableTransaction& tx, CAmount& f if (options.exists("estimate_mode")) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both estimate_mode and feeRate"); } - CFeeRate fee_rate(AmountFromValue(options["feeRate"])); - if (fee_rate <= CFeeRate(0)) { - throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid feeRate %s (must be greater than 0)", fee_rate.ToString(FeeEstimateMode::BTC_KVB))); - } - coinControl.m_feerate = fee_rate; + coinControl.m_feerate = CFeeRate(AmountFromValue(options["feeRate"])); coinControl.fOverrideFeeRate = true; } diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py index be0f00eb3e..8a31812a58 100755 --- a/test/functional/rpc_fundrawtransaction.py +++ b/test/functional/rpc_fundrawtransaction.py @@ -762,11 +762,17 @@ class RawTransactionsTest(BitcoinTestFramework): result2 = node.fundrawtransaction(rawtx, {"feeRate": 2 * self.min_relay_tx_fee}) result3 = node.fundrawtransaction(rawtx, {"fee_rate": 10 * btc_kvb_to_sat_vb * self.min_relay_tx_fee}) result4 = node.fundrawtransaction(rawtx, {"feeRate": 10 * self.min_relay_tx_fee}) + # Test that funding non-standard "zero-fee" transactions is valid. + result5 = self.nodes[3].fundrawtransaction(rawtx, {"fee_rate": 0}) + result6 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 0}) + result_fee_rate = result['fee'] * 1000 / count_bytes(result['hex']) assert_fee_amount(result1['fee'], count_bytes(result2['hex']), 2 * result_fee_rate) assert_fee_amount(result2['fee'], count_bytes(result2['hex']), 2 * result_fee_rate) assert_fee_amount(result3['fee'], count_bytes(result3['hex']), 10 * result_fee_rate) assert_fee_amount(result4['fee'], count_bytes(result3['hex']), 10 * result_fee_rate) + assert_fee_amount(result5['fee'], count_bytes(result5['hex']), 0) + assert_fee_amount(result6['fee'], count_bytes(result6['hex']), 0) # With no arguments passed, expect fee of 141 satoshis. assert_approx(node.fundrawtransaction(rawtx)["fee"], vexp=0.00002491, vspan=0.00000001) @@ -793,19 +799,15 @@ class RawTransactionsTest(BitcoinTestFramework): node.fundrawtransaction, rawtx, {"estimate_mode": mode, "conf_target": n, "add_inputs": True}) self.log.info("Test invalid fee rate settings") - assert_raises_rpc_error(-8, "Invalid fee_rate 0.000 sat/vB (must be greater than 0)", - node.fundrawtransaction, rawtx, {"fee_rate": 0, "add_inputs": True}) - assert_raises_rpc_error(-8, "Invalid feeRate 0.00000000 BTC/kvB (must be greater than 0)", - node.fundrawtransaction, rawtx, {"feeRate": 0, "add_inputs": True}) for param, value in {("fee_rate", 100000), ("feeRate", 1.000)}: assert_raises_rpc_error(-4, "Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)", node.fundrawtransaction, rawtx, {param: value, "add_inputs": True}) assert_raises_rpc_error(-3, "Amount out of range", - node.fundrawtransaction, rawtx, {"fee_rate": -1, "add_inputs": True}) + node.fundrawtransaction, rawtx, {param: -1, "add_inputs": True}) assert_raises_rpc_error(-3, "Amount is not a number or string", - node.fundrawtransaction, rawtx, {"fee_rate": {"foo": "bar"}, "add_inputs": True}) + node.fundrawtransaction, rawtx, {param: {"foo": "bar"}, "add_inputs": True}) assert_raises_rpc_error(-3, "Invalid amount", - node.fundrawtransaction, rawtx, {"fee_rate": "", "add_inputs": True}) + node.fundrawtransaction, rawtx, {param: "", "add_inputs": True}) self.log.info("Test min fee rate checks are bypassed with fundrawtxn, e.g. a fee_rate under 1 sat/vB is allowed") node.fundrawtransaction(rawtx, {"fee_rate": 0.99999999, "add_inputs": True}) diff --git a/test/functional/rpc_psbt.py b/test/functional/rpc_psbt.py index ec25408a41..d98bad26d4 100755 --- a/test/functional/rpc_psbt.py +++ b/test/functional/rpc_psbt.py @@ -249,6 +249,7 @@ class PSBTTest(BitcoinTestFramework): #res2 = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"feeRate": fee_rate_sb / 100000.0, "add_inputs": True}) #assert_approx(res2["fee"], 0.055, 0.005) # ELEMENTS: no "fee" field + self.log.info("Test min fee rate checks with walletcreatefundedpsbt are bypassed, e.g. a fee_rate under 1 sat/vB is allowed") #res3 = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"fee_rate": 0.99999999, "add_inputs": True}) @@ -257,20 +258,20 @@ class PSBTTest(BitcoinTestFramework): self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"feeRate": 0.00000999, "add_inputs": True}) #assert_approx(res4["fee"], 0.00000381, 0.0000001) # ELEMENTS: no "fee" field + self.log.info("Test min fee rate checks with walletcreatefundedpsbt are bypassed and that funding non-standard 'zero-fee' transactions is valid") + for param in ["fee_rate", "feeRate"]: + assert_equal(self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {param: 0, "add_inputs": True})["fee"], 0) + self.log.info("Test invalid fee rate settings") - assert_raises_rpc_error(-8, "Invalid fee_rate 0.000 sat/vB (must be greater than 0)", - self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"fee_rate": 0, "add_inputs": True}) - assert_raises_rpc_error(-8, "Invalid feeRate 0.00000000 BTC/kvB (must be greater than 0)", - self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"feeRate": 0, "add_inputs": True}) for param, value in {("fee_rate", 100000), ("feeRate", 1)}: assert_raises_rpc_error(-4, "Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)", self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {param: value, "add_inputs": True}) assert_raises_rpc_error(-3, "Amount out of range", - self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"fee_rate": -1, "add_inputs": True}) + self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {param: -1, "add_inputs": True}) assert_raises_rpc_error(-3, "Amount is not a number or string", - self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"fee_rate": {"foo": "bar"}, "add_inputs": True}) + self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {param: {"foo": "bar"}, "add_inputs": True}) assert_raises_rpc_error(-3, "Invalid amount", - self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"fee_rate": "", "add_inputs": True}) + self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {param: "", "add_inputs": True}) self.log.info("- raises RPC error if both feeRate and fee_rate are passed") assert_raises_rpc_error(-8, "Cannot specify both fee_rate (sat/vB) and feeRate (BTC/kvB)", diff --git a/test/functional/wallet_send.py b/test/functional/wallet_send.py index 305795f0dc..d9ea376a3a 100755 --- a/test/functional/wallet_send.py +++ b/test/functional/wallet_send.py @@ -307,10 +307,16 @@ class WalletSendTest(BitcoinTestFramework): self.test_send(from_wallet=w0, to_wallet=w1, amount=1, conf_target=v, estimate_mode=mode, expect_error=(-3, "Expected type number for conf_target, got {}".format(k))) - # Test setting explicit fee rate just below the minimum. + # Test setting explicit fee rate just below the minimum and at zero. self.log.info("Explicit fee rate raises RPC error 'fee rate too low' if fee_rate of 0.99999999 is passed") self.test_send(from_wallet=w0, to_wallet=w1, amount=1, fee_rate=0.99999999, expect_error=(-4, "Fee rate (0.999 sat/vB) is lower than the minimum fee rate setting (1.000 sat/vB)")) + self.test_send(from_wallet=w0, to_wallet=w1, amount=1, arg_fee_rate=0.99999999, + expect_error=(-4, "Fee rate (0.999 sat/vB) is lower than the minimum fee rate setting (1.000 sat/vB)")) + self.test_send(from_wallet=w0, to_wallet=w1, amount=1, fee_rate=0, + expect_error=(-4, "Fee rate (0.000 sat/vB) is lower than the minimum fee rate setting (1.000 sat/vB)")) + self.test_send(from_wallet=w0, to_wallet=w1, amount=1, arg_fee_rate=0, + expect_error=(-4, "Fee rate (0.000 sat/vB) is lower than the minimum fee rate setting (1.000 sat/vB)")) # TODO: Return hex if fee rate is below -maxmempool # res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, conf_target=0.1, estimate_mode="sat/b", add_to_wallet=False) From d635fc743a37d0f4112c01acf8128c0f236c26e0 Mon Sep 17 00:00:00 2001 From: Jon Atack Date: Thu, 19 Nov 2020 18:47:24 +0100 Subject: [PATCH 13/84] Update feeRate (BTC/kvB) to fee_rate (sat/vB) in wallet_bumpfee as the feeRate argument should soon be deprecated. Also loosen one test (and a similar one) that caused a one-off CI failure with: expected message 'Insufficient total fee 0.00000141, must be at least 0.00001704 (oldFee 0.00000999 + incrementalFee 0.00000705)' actual message 'Insufficient total fee 0.00000141, must be at least 0.00001712 (oldFee 0.00001007 + incrementalFee 0.00000705)' Github-Pull: #20426 Rebased-From: 3f1e10b2b1cd11f7112fbad6355464bd4adbbc5c (cherry picked from commit 6e4969f76f58518d47ce2f2cdfc4e3ef1f2228bd) --- test/functional/wallet_bumpfee.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/test/functional/wallet_bumpfee.py b/test/functional/wallet_bumpfee.py index 762e244753..9b63574a5e 100755 --- a/test/functional/wallet_bumpfee.py +++ b/test/functional/wallet_bumpfee.py @@ -109,12 +109,10 @@ class BumpFeeTest(BitcoinTestFramework): assert_raises_rpc_error(-3, "Unexpected key {}".format(key), rbf_node.bumpfee, rbfid, {key: NORMAL}) # Bumping to just above minrelay should fail to increase the total fee enough. - assert_raises_rpc_error(-8, "Insufficient total fee 0.00000257, must be at least 0.00002284 (oldFee 0.00000999 + incrementalFee 0.00001285)", - rbf_node.bumpfee, rbfid, {"fee_rate": INSUFFICIENT}) + assert_raises_rpc_error(-8, "Insufficient total fee 0.00000257", rbf_node.bumpfee, rbfid, {"fee_rate": INSUFFICIENT}) self.log.info("Test invalid fee rate settings") - assert_raises_rpc_error(-8, "Insufficient total fee 0.00, must be at least 0.00002284 (oldFee 0.00000999 + incrementalFee 0.00001285)", - rbf_node.bumpfee, rbfid, {"fee_rate": 0}) + assert_raises_rpc_error(-8, "Insufficient total fee 0.00", rbf_node.bumpfee, rbfid, {"fee_rate": 0}) assert_raises_rpc_error(-4, "Specified or calculated fee 0.257 is too high (cannot be higher than -maxtxfee 0.10", rbf_node.bumpfee, rbfid, {"fee_rate": TOO_HIGH}) assert_raises_rpc_error(-3, "Amount out of range", rbf_node.bumpfee, rbfid, {"fee_rate": -1}) @@ -429,7 +427,7 @@ def test_watchonly_psbt(self, peer_node, rbf_node, dest_address): self.sync_all() # Create single-input PSBT for transaction to be bumped - psbt = watcher.walletcreatefundedpsbt([], [{dest_address: 0.0005}], 0, {"feeRate": 0.00001}, True)['psbt'] + psbt = watcher.walletcreatefundedpsbt([], [{dest_address: 0.0005}], 0, {"fee_rate": 1}, True)['psbt'] psbt_signed = signer.walletprocesspsbt(psbt=psbt, sign=True, sighashtype="ALL", bip32derivs=True) psbt_final = watcher.finalizepsbt(psbt_signed["psbt"]) original_txid = watcher.sendrawtransaction(psbt_final["hex"]) From a97c53172aeb2f87cced1095f7a97709e9f89518 Mon Sep 17 00:00:00 2001 From: Jon Atack Date: Thu, 19 Nov 2020 17:31:07 +0100 Subject: [PATCH 14/84] Use the correct incremental fee constant in bumpfee help and remove redundant units ("Must be at least 1.000 sat/vB sat/vB" -> "1.00 sat vB") Github-Pull: #20426 Rebased-From: 9f08780dd7946b63476e9736745131db8e7f4e93 (cherry picked from commit 6313362553d91bddb75a43f62dffbec16065e4d6) --- src/wallet/rpcwallet.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index e2bdfee159..b888aca20c 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3691,7 +3691,7 @@ RPCHelpMan signrawtransactionwithwallet() static RPCHelpMan bumpfee_helper(std::string method_name) { bool want_psbt = method_name == "psbtbumpfee"; - const std::string incremental_fee{CFeeRate(DEFAULT_MIN_RELAY_TX_FEE).ToString(FeeEstimateMode::SAT_VB)}; + const std::string incremental_fee{CFeeRate(DEFAULT_INCREMENTAL_RELAY_FEE).ToString(FeeEstimateMode::SAT_VB)}; return RPCHelpMan{method_name, "\nBumps the fee of an opt-in-RBF transaction T, replacing it with a new transaction B.\n" @@ -3714,7 +3714,7 @@ static RPCHelpMan bumpfee_helper(std::string method_name) {"conf_target", RPCArg::Type::NUM, /* default */ "wallet -txconfirmtarget", "Confirmation target in blocks\n"}, {"fee_rate", RPCArg::Type::AMOUNT, /* default */ "not set, fall back to wallet fee estimation", "\nSpecify a fee rate in " + CURRENCY_ATOM + "/vB instead of relying on the built-in fee estimator.\n" - "Must be at least " + incremental_fee + " " + CURRENCY_ATOM + "/vB higher than the current transaction fee rate.\n" + "Must be at least " + incremental_fee + " higher than the current transaction fee rate.\n" "WARNING: before version 0.21, fee_rate was in " + CURRENCY_UNIT + "/kvB. As of 0.21, fee_rate is in " + CURRENCY_ATOM + "/vB.\n"}, {"replaceable", RPCArg::Type::BOOL, /* default */ "true", "Whether the new transaction should still be\n" "marked bip-125 replaceable. If true, the sequence numbers in the transaction will\n" From c117c6c125361054eab98a2209a34494019e63e8 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 3 Dec 2020 14:59:27 -0800 Subject: [PATCH 15/84] Don't send 'sendaddrv2' to pre-70016 software Github-Pull: #20564 Rebased-From: c5a89196602e43ebb1cdc9cd4f08d153419c13e1 (cherry picked from commit 9e806887a8f9ef63431b28d7dfd0470aa663dd02) --- src/net_processing.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/net_processing.cpp b/src/net_processing.cpp index c649cf7757..44f6f5d6b6 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -2367,7 +2367,13 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat m_connman.PushMessage(&pfrom, msg_maker.Make(NetMsgType::VERACK)); // Signal ADDRv2 support (BIP155). - m_connman.PushMessage(&pfrom, msg_maker.Make(NetMsgType::SENDADDRV2)); + if (greatest_common_version >= 70016) { + // BIP155 defines addrv2 and sendaddrv2 for all protocol versions, but some + // implementations reject messages they don't know. As a courtesy, don't send + // it to nodes with a version before 70016, as no software is known to support + // BIP155 that doesn't announce at least that protocol version number. + m_connman.PushMessage(&pfrom, msg_maker.Make(NetMsgType::SENDADDRV2)); + } pfrom.nServices = nServices; pfrom.SetAddrLocal(addrMe); From f15c72cbd2ff702db5613eed3993e79d91105627 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 7 Dec 2020 09:12:37 -0800 Subject: [PATCH 16/84] Send and require SENDADDRV2 before VERACK See the corresponding BIP change: https://github.com/bitcoin/bips/pull/1043 Github-Pull: #20564 Rebased-From: 1583498fb6781c01ca2f33c09319ed793964c574 (cherry picked from commit bead93547067e4b62b44fba335f1d4697119c2d7) --- src/net_processing.cpp | 20 +++++++++++++------- test/functional/test_framework/p2p.py | 2 +- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 44f6f5d6b6..98e3d90c2d 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -2364,8 +2364,6 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat m_connman.PushMessage(&pfrom, msg_maker.Make(NetMsgType::WTXIDRELAY)); } - m_connman.PushMessage(&pfrom, msg_maker.Make(NetMsgType::VERACK)); - // Signal ADDRv2 support (BIP155). if (greatest_common_version >= 70016) { // BIP155 defines addrv2 and sendaddrv2 for all protocol versions, but some @@ -2375,6 +2373,8 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat m_connman.PushMessage(&pfrom, msg_maker.Make(NetMsgType::SENDADDRV2)); } + m_connman.PushMessage(&pfrom, msg_maker.Make(NetMsgType::VERACK)); + pfrom.nServices = nServices; pfrom.SetAddrLocal(addrMe); { @@ -2546,6 +2546,17 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat return; } + if (msg_type == NetMsgType::SENDADDRV2) { + if (pfrom.fSuccessfullyConnected) { + // Disconnect peers that send SENDADDRV2 message after VERACK; this + // must be negotiated between VERSION and VERACK. + pfrom.fDisconnect = true; + return; + } + pfrom.m_wants_addrv2 = true; + return; + } + if (!pfrom.fSuccessfullyConnected) { LogPrint(BCLog::NET, "Unsupported message \"%s\" prior to verack from peer=%d\n", SanitizeString(msg_type), pfrom.GetId()); return; @@ -2613,11 +2624,6 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat return; } - if (msg_type == NetMsgType::SENDADDRV2) { - pfrom.m_wants_addrv2 = true; - return; - } - if (msg_type == NetMsgType::SENDHEADERS) { LOCK(cs_main); State(pfrom.GetId())->fPreferHeaders = true; diff --git a/test/functional/test_framework/p2p.py b/test/functional/test_framework/p2p.py index ad88e10d49..c589e1b370 100755 --- a/test/functional/test_framework/p2p.py +++ b/test/functional/test_framework/p2p.py @@ -397,9 +397,9 @@ class P2PInterface(P2PConnection): assert message.nVersion >= MIN_VERSION_SUPPORTED, "Version {} received. Test framework only supports versions greater than {}".format(message.nVersion, MIN_VERSION_SUPPORTED) if message.nVersion >= 70016: self.send_message(msg_wtxidrelay()) - self.send_message(msg_verack()) if self.support_addrv2: self.send_message(msg_sendaddrv2()) + self.send_message(msg_verack()) self.nServices = message.nServices # Connection helper methods From b4eb953986961790801b89f2725764a1d27a2bf5 Mon Sep 17 00:00:00 2001 From: Jon Atack Date: Fri, 4 Dec 2020 11:20:39 +0100 Subject: [PATCH 17/84] wallet, bugfix: allow send to take string fee rate values Github-Pull: #20573 Rebased-From: ce207d6b93d35bc02fcd2dd28f1fd95869261d43 (cherry picked from commit 06c84232b310e6196c814894537ad935d773fe98) --- src/wallet/rpcwallet.cpp | 2 +- test/functional/wallet_send.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index b888aca20c..58f36dde23 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4491,7 +4491,7 @@ static RPCHelpMan send() UniValueType(), // outputs (ARR or OBJ, checked later) UniValue::VNUM, // conf_target UniValue::VSTR, // estimate_mode - UniValue::VNUM, // fee_rate + UniValueType(), // fee_rate, will be checked by AmountFromValue() in SetFeeEstimateMode() UniValue::VOBJ, // options }, true ); diff --git a/test/functional/wallet_send.py b/test/functional/wallet_send.py index d9ea376a3a..1f342f887a 100755 --- a/test/functional/wallet_send.py +++ b/test/functional/wallet_send.py @@ -261,8 +261,8 @@ class WalletSendTest(BitcoinTestFramework): # ELEMENTS: we do not have the "fee" field, several lines are commented out here that should # be revisited after #900 self.log.info("Test setting explicit fee rate") - #res1 = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, arg_fee_rate=1, add_to_wallet=False) - #res2 = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, fee_rate=1, add_to_wallet=False) + #res1 = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, arg_fee_rate="1", add_to_wallet=False) + #res2 = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, fee_rate="1", add_to_wallet=False) #assert_equal(self.nodes[1].decodepsbt(res1["psbt"])["fee"], self.nodes[1].decodepsbt(res2["psbt"])["fee"]) res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, fee_rate=7, add_to_wallet=False) From e48a9793b2cdf164d6083a7a913558741d13b718 Mon Sep 17 00:00:00 2001 From: Jon Atack Date: Fri, 4 Dec 2020 11:22:34 +0100 Subject: [PATCH 18/84] test: add coverage for passing fee rate as a string Github-Pull: #20573 Rebased-From: 6fa72ceb8021c3b5aea62f6cfe92665c29212923 (cherry picked from commit 0d3c140c4db051fb33c2935ad9536f0f4aa2a8c5) --- test/functional/rpc_fundrawtransaction.py | 4 ++-- test/functional/rpc_psbt.py | 2 +- test/functional/wallet_basic.py | 29 +++++++++++++++++++++-- test/functional/wallet_bumpfee.py | 2 +- 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py index 8a31812a58..caef486210 100755 --- a/test/functional/rpc_fundrawtransaction.py +++ b/test/functional/rpc_fundrawtransaction.py @@ -758,10 +758,10 @@ class RawTransactionsTest(BitcoinTestFramework): result = node.fundrawtransaction(rawtx) # uses self.min_relay_tx_fee (set by settxfee) btc_kvb_to_sat_vb = 100000 # (1e5) - result1 = node.fundrawtransaction(rawtx, {"fee_rate": 2 * btc_kvb_to_sat_vb * self.min_relay_tx_fee}) + result1 = node.fundrawtransaction(rawtx, {"fee_rate": str(2 * btc_kvb_to_sat_vb * self.min_relay_tx_fee)}) result2 = node.fundrawtransaction(rawtx, {"feeRate": 2 * self.min_relay_tx_fee}) result3 = node.fundrawtransaction(rawtx, {"fee_rate": 10 * btc_kvb_to_sat_vb * self.min_relay_tx_fee}) - result4 = node.fundrawtransaction(rawtx, {"feeRate": 10 * self.min_relay_tx_fee}) + result4 = node.fundrawtransaction(rawtx, {"feeRate": str(10 * self.min_relay_tx_fee)}) # Test that funding non-standard "zero-fee" transactions is valid. result5 = self.nodes[3].fundrawtransaction(rawtx, {"fee_rate": 0}) result6 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 0}) diff --git a/test/functional/rpc_psbt.py b/test/functional/rpc_psbt.py index d98bad26d4..94d3927dd0 100755 --- a/test/functional/rpc_psbt.py +++ b/test/functional/rpc_psbt.py @@ -252,7 +252,7 @@ class PSBTTest(BitcoinTestFramework): self.log.info("Test min fee rate checks with walletcreatefundedpsbt are bypassed, e.g. a fee_rate under 1 sat/vB is allowed") #res3 = - self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"fee_rate": 0.99999999, "add_inputs": True}) + self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"fee_rate": "0.99999999", "add_inputs": True}) #assert_approx(res3["fee"], 0.00000381, 0.0000001) # ELEMENTS: no "fee" field #res4 = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"feeRate": 0.00000999, "add_inputs": True}) diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py index 9355ceb3ca..3f2b89283b 100755 --- a/test/functional/wallet_basic.py +++ b/test/functional/wallet_basic.py @@ -234,7 +234,8 @@ class WalletTest(BitcoinTestFramework): fee_rate_btc_kvb = fee_rate_sat_vb * 1e3 / 1e8 explicit_fee_rate_btc_kvb = Decimal(fee_rate_btc_kvb) / 1000 - txid = self.nodes[2].sendmany(amounts={address: 10}, fee_rate=fee_rate_sat_vb) + # Test passing fee_rate as a string + txid = self.nodes[2].sendmany(amounts={address: 10}, fee_rate=str(fee_rate_sat_vb)) self.nodes[2].generate(1) self.sync_all(self.nodes[0:3]) balance = self.nodes[2].getbalance()['bitcoin'] @@ -243,6 +244,17 @@ class WalletTest(BitcoinTestFramework): node_0_bal += Decimal('10') assert_equal(self.nodes[0].getbalance()['bitcoin'], node_0_bal) + # Test passing fee_rate as an integer + amount = Decimal("0.0001") + txid = self.nodes[2].sendmany(amounts={address: amount}, fee_rate=fee_rate_sat_vb) + self.nodes[2].generate(1) + self.sync_all(self.nodes[0:3]) + balance = self.nodes[2].getbalance()['bitcoin'] + node_2_bal = self.check_fee_amount(balance, node_2_bal - amount, explicit_fee_rate_btc_kvb, self.get_vsize(self.nodes[2].gettransaction(txid)['hex'])) + assert_equal(balance, node_2_bal) + node_0_bal += amount + assert_equal(self.nodes[0].getbalance()['bitcoin'], node_0_bal) + for key in ["totalFee", "feeRate"]: assert_raises_rpc_error(-8, "Unknown named parameter key", self.nodes[2].sendtoaddress, address=address, amount=1, fee_rate=1, key=1) @@ -406,7 +418,7 @@ class WalletTest(BitcoinTestFramework): amount = 3 fee_rate_sat_vb = 2 fee_rate_btc_kvb = fee_rate_sat_vb * 1e3 / 1e8 - + # Test passing fee_rate as an integer txid = self.nodes[2].sendtoaddress(address=address, amount=amount, fee_rate=fee_rate_sat_vb) tx_size = self.get_vsize(self.nodes[2].gettransaction(txid)['hex']) self.nodes[0].generate(1) @@ -415,6 +427,19 @@ class WalletTest(BitcoinTestFramework): fee = prebalance - postbalance - Decimal(amount) assert_fee_amount(fee, tx_size, Decimal(fee_rate_btc_kvb)) + prebalance = self.nodes[2].getbalance()['bitcoin'] + amount = Decimal("0.001") + fee_rate_sat_vb = 1.23 + fee_rate_btc_kvb = fee_rate_sat_vb * 1e3 / 1e8 + # Test passing fee_rate as a string + txid = self.nodes[2].sendtoaddress(address=address, amount=amount, fee_rate=str(fee_rate_sat_vb)) + tx_size = self.get_vsize(self.nodes[2].gettransaction(txid)['hex']) + self.nodes[0].generate(1) + self.sync_all(self.nodes[0:3]) + postbalance = self.nodes[2].getbalance()['bitcoin'] + fee = prebalance - postbalance - amount + assert_fee_amount(fee, tx_size, Decimal(fee_rate_btc_kvb)) + for key in ["totalFee", "feeRate"]: assert_raises_rpc_error(-8, "Unknown named parameter key", self.nodes[2].sendtoaddress, address=address, amount=1, fee_rate=1, key=1) diff --git a/test/functional/wallet_bumpfee.py b/test/functional/wallet_bumpfee.py index 9b63574a5e..4206758f5b 100755 --- a/test/functional/wallet_bumpfee.py +++ b/test/functional/wallet_bumpfee.py @@ -151,7 +151,7 @@ def test_simple_bumpfee_succeeds(self, mode, rbf_node, peer_node, dest_address): self.sync_mempools((rbf_node, peer_node)) assert rbfid in rbf_node.getrawmempool() and rbfid in peer_node.getrawmempool() if mode == "fee_rate": - bumped_psbt = rbf_node.psbtbumpfee(rbfid, {"fee_rate": NORMAL}) + bumped_psbt = rbf_node.psbtbumpfee(rbfid, {"fee_rate": str(NORMAL)}) bumped_tx = rbf_node.bumpfee(rbfid, {"fee_rate": NORMAL}) else: bumped_psbt = rbf_node.psbtbumpfee(rbfid) From 3bfce85eaf81036a1b626b82b7e0957ea087bd89 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 7 Dec 2020 14:37:09 -0800 Subject: [PATCH 19/84] Improve heuristic hex transaction decoding Whenever both encodings are permitted, try both, and if only one succeeds, return that one. Otherwise prefer the one for which the heuristic sanity check passes. If that is the case for neither or for both, return the extended-permitting deserialization. Github-Pull: #20595 Rebased-From: 39c42c442044aef611d03ee7053d2dd6df63deb7 (cherry picked from commit 1caa32e3f2a74cd5700a4afe8ecf650f9020fb5c) --- src/core_read.cpp | 59 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/src/core_read.cpp b/src/core_read.cpp index d406a65a80..047730240c 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -119,31 +119,72 @@ static bool CheckTxScriptsSanity(const CMutableTransaction& tx) static bool DecodeTx(CMutableTransaction& tx, const std::vector& tx_data, bool try_no_witness, bool try_witness) { + // General strategy: + // - Decode both with extended serialization (which interprets the 0x0001 tag as a marker for + // the presense of witnesses) and with legacy serialization (which interprets the tag as a + // 0-input 1-output incomplete transaction). + // - Restricted by try_no_witness (which disables legacy if false) and try_witness (which + // disables extended if false). + // - Ignore serializations that do not fully consume the hex string. + // - If neither succeeds, fail. + // - If only one succeeds, return that one. + // - If both decode attempts succeed: + // - If only one passes the CheckTxScriptsSanity check, return that one. + // - If neither or both pass CheckTxScriptsSanity, return the extended one. + + CMutableTransaction tx_extended, tx_legacy; + bool ok_extended = false, ok_legacy = false; + + // Try decoding with extended serialization support, and remember if the result successfully + // consumes the entire input. if (try_witness) { CDataStream ssData(tx_data, SER_NETWORK, PROTOCOL_VERSION); try { - ssData >> tx; - // If transaction looks sane, we don't try other mode even if requested - if (ssData.empty() && (!try_no_witness || CheckTxScriptsSanity(tx))) { - return true; - } + ssData >> tx_extended; + if (ssData.empty()) ok_extended = true; } catch (const std::exception&) { // Fall through. } } + // Optimization: if extended decoding succeeded and the result passes CheckTxScriptsSanity, + // don't bother decoding the other way. + if (ok_extended && CheckTxScriptsSanity(tx_extended)) { + tx = std::move(tx_extended); + return true; + } + + // Try decoding with legacy serialization, and remember if the result successfully consumes the entire input. if (try_no_witness) { CDataStream ssData(tx_data, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS); try { - ssData >> tx; - if (ssData.empty()) { - return true; - } + ssData >> tx_legacy; + if (ssData.empty()) ok_legacy = true; } catch (const std::exception&) { // Fall through. } } + // If legacy decoding succeeded and passes CheckTxScriptsSanity, that's our answer, as we know + // at this point that extended decoding either failed or doesn't pass the sanity check. + if (ok_legacy && CheckTxScriptsSanity(tx_legacy)) { + tx = std::move(tx_legacy); + return true; + } + + // If extended decoding succeeded, and neither decoding passes sanity, return the extended one. + if (ok_extended) { + tx = std::move(tx_extended); + return true; + } + + // If legacy decoding succeeded and extended didn't, return the legacy one. + if (ok_legacy) { + tx = std::move(tx_legacy); + return true; + } + + // If none succeeded, we failed. return false; } From b52bac2c393f4d93eb3c45f153f3c89dd0a69682 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 24 Nov 2020 15:08:28 +0100 Subject: [PATCH 21/84] Don't set BDB flags when configuring without Github-Pull: #20478 Rebased-From: 982e548a9a78b1b0abad59b54c780b6b06570452 (cherry picked from commit 61e316e66168be593fcc90b90217062fa9d993dc) --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 090ca34178..d584fda914 100644 --- a/configure.ac +++ b/configure.ac @@ -658,7 +658,7 @@ case $host in bdb_prefix=$($BREW --prefix berkeley-db4 2>/dev/null) qt5_prefix=$($BREW --prefix qt5 2>/dev/null) - if test x$bdb_prefix != x && test "x$BDB_CFLAGS" = "x" && test "x$BDB_LIBS" = "x"; then + if test x$bdb_prefix != x && test "x$BDB_CFLAGS" = "x" && test "x$BDB_LIBS" = "x" && test "$use_bdb" != "no"; then dnl This must precede the call to BITCOIN_FIND_BDB48 below. BDB_CFLAGS="-I$bdb_prefix/include" BDB_LIBS="-L$bdb_prefix/lib -ldb_cxx-4.8" From 29b0796eb915933946d4f5fc870f2592dcab8763 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Thu, 3 Dec 2020 23:39:14 +0200 Subject: [PATCH 22/84] build: Check that Homebrew's berkeley-db4 package is actually installed Github-Pull: #20563 Rebased-From: d3ef947524a07f8d7fbad5b95781ab6cacb1cb49 (cherry picked from commit 96124a204193ed114ca9594df7d5151206990e91) --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index d584fda914..1454751147 100644 --- a/configure.ac +++ b/configure.ac @@ -656,9 +656,9 @@ case $host in dnl It's safe to add these paths even if the functionality is disabled by dnl the user (--without-wallet or --without-gui for example). - bdb_prefix=$($BREW --prefix berkeley-db4 2>/dev/null) qt5_prefix=$($BREW --prefix qt5 2>/dev/null) - if test x$bdb_prefix != x && test "x$BDB_CFLAGS" = "x" && test "x$BDB_LIBS" = "x" && test "$use_bdb" != "no"; then + if $BREW list --versions berkeley-db4 >/dev/null && test "x$BDB_CFLAGS" = "x" && test "x$BDB_LIBS" = "x" && test "$use_bdb" != "no"; then + bdb_prefix=$($BREW --prefix berkeley-db4 2>/dev/null) dnl This must precede the call to BITCOIN_FIND_BDB48 below. BDB_CFLAGS="-I$bdb_prefix/include" BDB_LIBS="-L$bdb_prefix/lib -ldb_cxx-4.8" From 92b1189afc2c48bbd062bad48a2ef64f5b1951f3 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Fri, 4 Dec 2020 13:02:08 +0200 Subject: [PATCH 23/84] build, refactor: Check that Homebrew's qt5 package is actually installed This change unifies Homebrew packages workflow, and does not change behavior. Github-Pull: #20527 Rebased-From: c96d1f65a552712f8476269ad64a415717ead50d (cherry picked from commit 48f8929aade118469cb0014e78a15b4e71fdd17d) --- configure.ac | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 1454751147..5e6f2565a4 100644 --- a/configure.ac +++ b/configure.ac @@ -656,16 +656,15 @@ case $host in dnl It's safe to add these paths even if the functionality is disabled by dnl the user (--without-wallet or --without-gui for example). - qt5_prefix=$($BREW --prefix qt5 2>/dev/null) if $BREW list --versions berkeley-db4 >/dev/null && test "x$BDB_CFLAGS" = "x" && test "x$BDB_LIBS" = "x" && test "$use_bdb" != "no"; then bdb_prefix=$($BREW --prefix berkeley-db4 2>/dev/null) dnl This must precede the call to BITCOIN_FIND_BDB48 below. BDB_CFLAGS="-I$bdb_prefix/include" BDB_LIBS="-L$bdb_prefix/lib -ldb_cxx-4.8" fi - if test x$qt5_prefix != x; then - PKG_CONFIG_PATH="$qt5_prefix/lib/pkgconfig:$PKG_CONFIG_PATH" - export PKG_CONFIG_PATH + + if $BREW list --versions qt5 >/dev/null; then + export PKG_CONFIG_PATH="$($BREW --prefix qt5 2>/dev/null)/lib/pkgconfig:$PKG_CONFIG_PATH" fi dnl On some versions of osx stack check is turned on by default and is broken AX_CHECK_COMPILE_FLAG([-fno-stack-check],[HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -fno-stack-check"]) From fdd69bf90224f2fc7ce044b52c3009dc13bbd3c3 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Fri, 4 Dec 2020 13:06:10 +0200 Subject: [PATCH 24/84] build: Use Homebrew's sqlite package if it is available Github-Pull: #20527 Rebased-From: ee7b84e63cbeadd5e680d69ff0548275581e9241 (cherry picked from commit f51e1cb2917bbd7b0966a7ad688e04fc3ce02ccf) --- configure.ac | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 5e6f2565a4..6bbdcaaee8 100644 --- a/configure.ac +++ b/configure.ac @@ -656,13 +656,17 @@ case $host in dnl It's safe to add these paths even if the functionality is disabled by dnl the user (--without-wallet or --without-gui for example). - if $BREW list --versions berkeley-db4 >/dev/null && test "x$BDB_CFLAGS" = "x" && test "x$BDB_LIBS" = "x" && test "$use_bdb" != "no"; then + if test "x$use_bdb" != xno && $BREW list --versions berkeley-db4 >/dev/null && test "x$BDB_CFLAGS" = "x" && test "x$BDB_LIBS" = "x"; then bdb_prefix=$($BREW --prefix berkeley-db4 2>/dev/null) dnl This must precede the call to BITCOIN_FIND_BDB48 below. BDB_CFLAGS="-I$bdb_prefix/include" BDB_LIBS="-L$bdb_prefix/lib -ldb_cxx-4.8" fi + if test "x$use_sqlite" != xno && $BREW list --versions sqlite3 >/dev/null; then + export PKG_CONFIG_PATH="$($BREW --prefix sqlite3 2>/dev/null)/lib/pkgconfig:$PKG_CONFIG_PATH" + fi + if $BREW list --versions qt5 >/dev/null; then export PKG_CONFIG_PATH="$($BREW --prefix qt5 2>/dev/null)/lib/pkgconfig:$PKG_CONFIG_PATH" fi From 09ca7bbf4e1eb45fac1af73e2e5321b3c38d2cf4 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Fri, 4 Dec 2020 13:14:37 +0200 Subject: [PATCH 25/84] doc: Update wallet database installation guide for macOS Github-Pull: #20527 Rebased-From: c932e0d67e4b369e4265267da6c8bebac2b6fb53 (cherry picked from commit 48134a09adef3b5302cdd6e95500db404c9ac961) --- doc/build-osx.md | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/doc/build-osx.md b/doc/build-osx.md index 9b1df8ed3b..fe468699ba 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -19,7 +19,7 @@ Then install [Homebrew](https://brew.sh). ## Dependencies ```shell -brew install automake berkeley-db4 libtool boost miniupnpc pkg-config python qt libevent qrencode sqlite +brew install automake libtool boost miniupnpc pkg-config python qt libevent qrencode ``` If you run into issues, check [Homebrew's troubleshooting page](https://docs.brew.sh/Troubleshooting). @@ -29,8 +29,22 @@ If you want to build the disk image with `make deploy` (.dmg / optional), you ne brew install librsvg libicns imagemagick -Berkeley DB ------------ +The wallet support requires one or both of the dependencies ([*SQLite*](#sqlite) and [*Berkeley DB*](#berkeley-db)) in the sections below. +To build Bitcoin Core without wallet, see [*Disable-wallet mode*](#disable-wallet-mode). + +#### SQLite + +Usually, macOS installation already has a suitable SQLite installation. +Also, the Homebrew package could be installed: + +```shell +brew install sqlite +``` + +In that case the Homebrew package will prevail. + +#### Berkeley DB + It is recommended to use Berkeley DB 4.8. If you have to build it yourself, you can use [this](/contrib/install_db4.sh) script to install it like so: @@ -41,7 +55,11 @@ like so: from the root of the repository. -**Note**: You only need Berkeley DB if the wallet is enabled (see [*Disable-wallet mode*](/doc/build-osx.md#disable-wallet-mode)). +Also, the Homebrew package could be installed: + +```shell +brew install berkeley-db4 +``` ## Build Bitcoin Core @@ -72,14 +90,14 @@ from the root of the repository. make deploy ``` -## `disable-wallet` mode +## Disable-wallet mode When the intention is to run only a P2P node without a wallet, Bitcoin Core may be -compiled in `disable-wallet` mode with: +compiled in disable-wallet mode with: ```shell ./configure --disable-wallet ``` -In this case there is no dependency on Berkeley DB 4.8 and SQLite. +In this case there is no dependency on [*Berkeley DB*](#berkeley-db) and [*SQLite*](#sqlite). Mining is also possible in disable-wallet mode using the `getblocktemplate` RPC call. From 14d7d20c68ddccb7535836d9296d7cf62e5dc9d7 Mon Sep 17 00:00:00 2001 From: Sjors Provoost Date: Tue, 15 Dec 2020 14:12:01 +0100 Subject: [PATCH 26/84] Move signet onion seed from v2 to v3 Github-Pull: #20660 Rebased-From: 3e6657a14d501c6315ab46ffe7d204684491c710 (cherry picked from commit 8273ea3b8db1449b65cf369e541a1253c4490f45) --- src/chainparams.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index f37b4bfcb8..353154cea4 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -332,7 +332,7 @@ public: bin = ParseHex("512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae"); vSeeds.emplace_back("178.128.221.177"); vSeeds.emplace_back("2a01:7c8:d005:390::5"); - vSeeds.emplace_back("ntv3mtqw5wt63red.onion:38333"); + vSeeds.emplace_back("v7ajjeirttkbnt32wpy3c6w3emwnfr3fkla7hpxcfokr3ysd3kqtzmqd.onion:38333"); consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000000000000019fd16269a"); consensus.defaultAssumeValid = uint256S("0x0000002a1de0f46379358c1fd09906f7ac59adf3712323ed90eb59e4c183c020"); // 9434 From 5e935dd6fe7b1fd3559e7ac3dd72f7308456e412 Mon Sep 17 00:00:00 2001 From: Aaron Clauson Date: Wed, 25 Nov 2020 11:07:10 +0000 Subject: [PATCH 27/84] This change to the appveyor CI config for msvc builds reverses a change introduced in #19960. It re-applies a setting to inform vcpkg to only build release vesions of the dependencies rather than the default of debug and release. It had been expected that the vcpkg manifest mechanism introduced in #19960 would do this automatically but it turns out not to be the case. Github-Pull: #20489 Rebased-From: fa18e7cbc5ea6aaba94dca4ebdc850c9db141f89 (cherry picked from commit e7b53d47218301790bfec44d50219561502922ad) --- .appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.appveyor.yml b/.appveyor.yml index 0d026748b5..bf93d7a990 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -24,6 +24,7 @@ install: git pull origin master > $null git -c advice.detachedHead=false checkout $env:VCPKG_COMMIT_ID .\bootstrap-vcpkg.bat > $null + Add-Content "C:\tools\vcpkg\triplets\$env:PLATFORM-windows-static.cmake" "set(VCPKG_BUILD_TYPE release)" cd "$env:APPVEYOR_BUILD_FOLDER" before_build: # Powershell block below is to download and extract the Qt static libraries. The pseudo code is: From 3acfb477e3f4ad645a9795b48ce4ff3a23fc7168 Mon Sep 17 00:00:00 2001 From: Aaron Clauson Date: Wed, 2 Dec 2020 11:37:32 +0000 Subject: [PATCH 28/84] Adjusted msvc compiler and linker settings to remove optimisations that are causing sporadic ABI issues on Visual Studio updates. Tidied up debug and release configuration blocks in common project file to avoid duplication. Updated appveyor config to use latest Visual Studio 2019 image. Changed appveyor config file hash to use a new version of Qt pre-compiled binaries built for Visual Studio 2019 v16.8.1. Bumped vcpkg version to tag '2020.11-1' for binary caching feature. See #20392 for related discussion. Github-Pull: #20506 Rebased-From: 8b99e609e7da5dd3601e9214d8f869e96108fffe (cherry picked from commit 249d61a382014c15025fe63025ac5f46d4721262) --- .appveyor.yml | 19 +++--- build_msvc/bitcoin-qt/bitcoin-qt.vcxproj | 2 +- build_msvc/common.init.vcxproj | 63 +++++++------------ build_msvc/common.vcxproj | 2 +- .../test_bitcoin-qt/test_bitcoin-qt.vcxproj | 4 +- 5 files changed, 35 insertions(+), 55 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index bf93d7a990..c21e7803a4 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,28 +1,29 @@ version: '{branch}.{build}' skip_tags: true -image: Previous Visual Studio 2019 +image: Visual Studio 2019 configuration: Release platform: x64 clone_depth: 5 environment: PATH: 'C:\Python37-x64;C:\Python37-x64\Scripts;%PATH%' PYTHONUTF8: 1 - QT_DOWNLOAD_URL: 'https://github.com/sipsorcery/qt_win_binary/releases/download/v1.6/Qt5.9.8_x64_static_vs2019.zip' - QT_DOWNLOAD_HASH: '9a8c6eb20967873785057fdcd329a657c7f922b0af08c5fde105cc597dd37e21' + QT_DOWNLOAD_URL: 'https://github.com/sipsorcery/qt_win_binary/releases/download/qt598x64_vs2019_v1681/qt598_x64_vs2019_1681.zip' + QT_DOWNLOAD_HASH: '00cf7327818c07d74e0b1a4464ffe987c2728b00d49d4bf333065892af0515c3' QT_LOCAL_PATH: 'C:\Qt5.9.8_x64_static_vs2019' - VCPKG_INSTALL_PATH: 'C:\tools\vcpkg\installed' - VCPKG_COMMIT_ID: '40230b8e3f6368dcb398d649331be878ca1e9007' + VCPKG_TAG: '2020.11-1' install: # Disable zmq test for now since python zmq library on Windows would cause Access violation sometimes. # - cmd: pip install zmq -# Powershell block below is to install the c++ dependencies via vcpkg. The pseudo code is: +# The powershell block below is to set up vcpkg to install the c++ dependencies. The pseudo code is: # a. Checkout the vcpkg source (including port files) for the specific checkout and build the vcpkg binary, -# b. Install the missing packages using the vcpkg manifest. +# b. Append a setting to the vcpkg cmake config file to only do release builds of dependencies (skipping deubg builds saves ~5 mins). +# Note originally this block also installed the dependencies using 'vcpkg install'. Dependencies are now installed +# as part of the msbuild command using vcpkg mainfests. - ps: | cd c:\tools\vcpkg $env:GIT_REDIRECT_STDERR = '2>&1' # git is writing non-errors to STDERR when doing git pull. Send to STDOUT instead. - git pull origin master > $null - git -c advice.detachedHead=false checkout $env:VCPKG_COMMIT_ID + git -c advice.detachedHead=false checkout $env:VCPKG_TAG + git pull origin $env:VCPKG_TAG .\bootstrap-vcpkg.bat > $null Add-Content "C:\tools\vcpkg\triplets\$env:PLATFORM-windows-static.cmake" "set(VCPKG_BUILD_TYPE release)" cd "$env:APPVEYOR_BUILD_FOLDER" diff --git a/build_msvc/bitcoin-qt/bitcoin-qt.vcxproj b/build_msvc/bitcoin-qt/bitcoin-qt.vcxproj index 17cd31a52e..65ce1ee9da 100644 --- a/build_msvc/bitcoin-qt/bitcoin-qt.vcxproj +++ b/build_msvc/bitcoin-qt/bitcoin-qt.vcxproj @@ -56,7 +56,7 @@ $(QtReleaseLibraries);%(AdditionalDependencies) - /ignore:4206 + /ignore:4206 /LTCG:OFF ..\..\src; diff --git a/build_msvc/common.init.vcxproj b/build_msvc/common.init.vcxproj index ed227519ae..9c589bccbc 100644 --- a/build_msvc/common.init.vcxproj +++ b/build_msvc/common.init.vcxproj @@ -4,8 +4,6 @@ 16.0 - x86-windows-static - x64-windows-static true @@ -16,6 +14,8 @@ true true $(Configuration) + x86-windows-static + x64-windows-static @@ -45,66 +45,46 @@ + + false + false + v142 + Unicode + No + $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + + true - false true v142 Unicode $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ $(Platform)\$(Configuration)\$(ProjectName)\ - - false - true - false - v142 - Unicode - $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ - $(Platform)\$(Configuration)\$(ProjectName)\ - - + - MaxSpeed + Disabled + false true true true MultiThreaded + None - true - true + false + false + /LTCG:OFF - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - true - MultiThreadedDebug - /bigobj %(AdditionalOptions) - - - - - - MaxSpeed - true - true - true - MultiThreaded - - - true - true - - - - + Disabled + false _DEBUG;%(PreprocessorDefinitions) true MultiThreadedDebug @@ -124,7 +104,6 @@ Console - true Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) diff --git a/build_msvc/common.vcxproj b/build_msvc/common.vcxproj index 4bbcc3767f..270c75e8a7 100644 --- a/build_msvc/common.vcxproj +++ b/build_msvc/common.vcxproj @@ -4,7 +4,7 @@ - + diff --git a/build_msvc/test_bitcoin-qt/test_bitcoin-qt.vcxproj b/build_msvc/test_bitcoin-qt/test_bitcoin-qt.vcxproj index 2095c0c321..1ddd62edf2 100644 --- a/build_msvc/test_bitcoin-qt/test_bitcoin-qt.vcxproj +++ b/build_msvc/test_bitcoin-qt/test_bitcoin-qt.vcxproj @@ -73,7 +73,7 @@ $(QtLibraryDir)\Qt5Test.lib;$(QtReleaseLibraries);%(AdditionalDependencies) - /ignore:4206 + /ignore:4206 /LTCG:OFF @@ -83,7 +83,7 @@ $(QtDebugLibraries);%(AdditionalDependencies) - /ignore:4206 + /ignore:4206 From a9bb81316d3150ed1dfe10c3b1ff83ccf704bca5 Mon Sep 17 00:00:00 2001 From: Aaron Clauson Date: Thu, 3 Dec 2020 09:23:22 +0000 Subject: [PATCH 29/84] Removed redundant git pull from appveyor config. Github-Pull: #20506 Rebased-From: 2c69381f3de5091e103cb8bef299aba321503e7c (cherry picked from commit 85dabd12494a0d82a8f5883cee1c1ff29fb81b27) --- .appveyor.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.appveyor.yml b/.appveyor.yml index c21e7803a4..7250d4ad94 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -23,7 +23,6 @@ install: cd c:\tools\vcpkg $env:GIT_REDIRECT_STDERR = '2>&1' # git is writing non-errors to STDERR when doing git pull. Send to STDOUT instead. git -c advice.detachedHead=false checkout $env:VCPKG_TAG - git pull origin $env:VCPKG_TAG .\bootstrap-vcpkg.bat > $null Add-Content "C:\tools\vcpkg\triplets\$env:PLATFORM-windows-static.cmake" "set(VCPKG_BUILD_TYPE release)" cd "$env:APPVEYOR_BUILD_FOLDER" From 24e35438d1c9ad5a7cc1eb75b4c1d17a40107979 Mon Sep 17 00:00:00 2001 From: Fabian Jahr Date: Fri, 22 May 2020 16:10:46 +0200 Subject: [PATCH 30/84] doc: Add warnings for http interfaces limitations Github-Pull: #19050 Rebased-From: 5c3eaf9983043db1b61a98c95d692a6958670b86 (cherry picked from commit e4440eb67b339fdacb2c1476f8f909a009c6a47f) --- doc/JSON-RPC-interface.md | 11 +++++++++++ doc/REST-interface.md | 12 ++++++++++++ 2 files changed, 23 insertions(+) diff --git a/doc/JSON-RPC-interface.md b/doc/JSON-RPC-interface.md index 40d8e330e2..c66e79af71 100644 --- a/doc/JSON-RPC-interface.md +++ b/doc/JSON-RPC-interface.md @@ -127,3 +127,14 @@ However, the wallet may not be up-to-date with the current state of the mempool or the state of the mempool by an RPC that returned before this RPC. For example, a wallet transaction that was BIP-125-replaced in the mempool prior to this RPC may not yet be reflected as such in this RPC response. + +## Limitations + +There is a known issue in the JSON-RPC interface that can cause a node to crash if +too many http connections are being opened at the same time because the system runs +out of available file descriptors. To prevent this from happening you might +want to increase the number of maximum allowed file descriptors in your system +and try to prevent opening too many connections to your JSON-RPC interface at the +same time if this is under your control. It is hard to give general advice +since this depends on your system but if you make several hundred requests at +once you are definitely at risk of encountering this issue. diff --git a/doc/REST-interface.md b/doc/REST-interface.md index 842a3964df..3b127703b7 100644 --- a/doc/REST-interface.md +++ b/doc/REST-interface.md @@ -12,6 +12,18 @@ REST Interface consistency guarantees The [same guarantees as for the RPC Interface](/doc/JSON-RPC-interface.md#rpc-consistency-guarantees) apply. +Limitations +----------- + +There is a known issue in the REST interface that can cause a node to crash if +too many http connections are being opened at the same time because the system runs +out of available file descriptors. To prevent this from happening you might +want to increase the number of maximum allowed file descriptors in your system +and try to prevent opening too many connections to your rest interface at the +same time if this is under your control. It is hard to give general advice +since this depends on your system but if you make several hundred requests at +once you are definitely at risk of encountering this issue. + Supported API ------------- From 6299124c9cf4b38e5c9ae91e1da2adbd46d61bf0 Mon Sep 17 00:00:00 2001 From: Adam Jonas Date: Tue, 15 Dec 2020 20:37:32 -0500 Subject: [PATCH 31/84] doc: warn that incoming conns are unlikely when not using default ports Github-Pull: #20668 Rebased-From: 010eed3ce03cf4fc622a48f40fc4d589383f7a44 (cherry picked from commit 84e8d5467fcec3b7c8ce950cd7a3e7e7b24452a3) --- src/init.cpp | 2 +- src/net.cpp | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index b55dc5819e..2032f97502 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -472,7 +472,7 @@ void SetupServerArgs(NodeContext& node) argsman.AddArg("-peerbloomfilters", strprintf("Support filtering of blocks and transaction with bloom filters (default: %u)", DEFAULT_PEERBLOOMFILTERS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-peerblockfilters", strprintf("Serve compact block filters to peers per BIP 157 (default: %u)", DEFAULT_PEERBLOCKFILTERS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-permitbaremultisig", strprintf("Relay non-P2SH multisig (default: %u)", DEFAULT_PERMIT_BAREMULTISIG), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); - argsman.AddArg("-port=", strprintf("Listen for connections on (default: %u, testnet: %u signet: %u, regtest: %u)", defaultChainParams->GetDefaultPort(), testnetChainParams->GetDefaultPort(), signetChainParams->GetDefaultPort(), regtestChainParams->GetDefaultPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION); + argsman.AddArg("-port=", strprintf("Listen for connections on . Nodes not using the default ports (default: %u, testnet: %u, signet: %u, regtest: %u) are unlikely to get incoming connections.", defaultChainParams->GetDefaultPort(), testnetChainParams->GetDefaultPort(), signetChainParams->GetDefaultPort(), regtestChainParams->GetDefaultPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION); argsman.AddArg("-proxy=", "Connect through SOCKS5 proxy, set -noproxy to disable (default: disabled)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-proxyrandomize", strprintf("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)", DEFAULT_PROXYRANDOMIZE), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-seednode=", "Connect to a node to retrieve peer addresses, and disconnect. This option can be specified multiple times to connect to multiple nodes.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); diff --git a/src/net.cpp b/src/net.cpp index cf987b6995..1fd913eb64 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2050,7 +2050,11 @@ void CConnman::ThreadOpenConnections(const std::vector connect) continue; } - // do not allow non-default ports, unless after 50 invalid addresses selected already + // Do not allow non-default ports, unless after 50 invalid + // addresses selected already. This is to prevent malicious peers + // from advertising themselves as a service on another host and + // port, causing a DoS attack as nodes around the network attempt + // to connect to it fruitlessly. if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50) continue; From ba3306519feb64b7b6132c7a3a44eb71cf81296b Mon Sep 17 00:00:00 2001 From: Jon Atack Date: Thu, 15 Oct 2020 12:00:56 +0200 Subject: [PATCH 32/84] doc: update tor.md address examples from onion v2 to v3 Github-Pull: #19961 Rebased-From: e1765d8b04fe1fb775f3750e0fa59f13a58eb176 (cherry picked from commit 0c1fa78af1c413c848359df76f4d55f819b9fad5) --- doc/tor.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/tor.md b/doc/tor.md index 12b5f70245..8fe87bdde6 100644 --- a/doc/tor.md +++ b/doc/tor.md @@ -72,7 +72,7 @@ should be equal to binding address and port for inbound Tor connections (127.0.0 In a typical situation, where you're only reachable via Tor, this should suffice: - ./bitcoind -proxy=127.0.0.1:9050 -externalip=57qr3yd1nyntf5k.onion -listen + ./bitcoind -proxy=127.0.0.1:9050 -externalip=7zvj7a2imdgkdbg4f2dryd5rgtrn7upivr5eeij4cicjh65pooxeshid.onion -listen (obviously, replace the .onion address with your own). It should be noted that you still listen on all devices and another node could establish a clearnet connection, when knowing @@ -90,7 +90,7 @@ and open port 8333 on your firewall (or use -upnp). If you only want to use Tor to reach .onion addresses, but not use it as a proxy for normal IPv4/IPv6 communication, use: - ./bitcoind -onion=127.0.0.1:9050 -externalip=57qr3yd1nyntf5k.onion -discover + ./bitcoind -onion=127.0.0.1:9050 -externalip=7zvj7a2imdgkdbg4f2dryd5rgtrn7upivr5eeij4cicjh65pooxeshid.onion -discover ## 3. Automatically listen on Tor From 9a18ee73d1ca6b3831e1d9e868ef4a42385109b5 Mon Sep 17 00:00:00 2001 From: Jon Atack Date: Thu, 15 Oct 2020 12:35:36 +0200 Subject: [PATCH 33/84] doc: add tor.md section on how to get tor info via bitcoind Github-Pull: #19961 Rebased-From: dc8a591222f249da81c7eef8aa5961f8d7dd1e23 (cherry picked from commit 2c8482d0a279d07a814eaaae231c90d3d2058e55) --- doc/tor.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/tor.md b/doc/tor.md index 8fe87bdde6..ccf8a226ee 100644 --- a/doc/tor.md +++ b/doc/tor.md @@ -5,6 +5,16 @@ It is possible to run Bitcoin Core as a Tor onion service, and connect to such s The following directions assume you have a Tor proxy running on port 9050. Many distributions default to having a SOCKS proxy listening on port 9050, but others may not. In particular, the Tor Browser Bundle defaults to listening on port 9150. See [Tor Project FAQ:TBBSocksPort](https://www.torproject.org/docs/faq.html.en#TBBSocksPort) for how to properly configure Tor. +## How to see information about your Tor configuration via Bitcoin Core + +There are several ways to see your local onion address in Bitcoin Core: +- in the debug log (grep for "tor:" or "AddLocal") +- in the output of RPC `getnetworkinfo` in the "localaddresses" section +- in the output of the CLI `-netinfo` peer connections dashboard + +You may set the `-debug=tor` config logging option to have additional +information in the debug log about your Tor configuration. + ## 1. Run Bitcoin Core behind a Tor proxy From 8db26435a00b1040546e890d186ee0ac97dce90e Mon Sep 17 00:00:00 2001 From: Jon Atack Date: Wed, 16 Sep 2020 08:43:26 +0200 Subject: [PATCH 34/84] doc: update -externalip documentation in tor.md Github-Pull: #19961 Rebased-From: a34eceb4cc054b4233e7321de927e8a7a2146301 (cherry picked from commit e70ccb0bc4b695cd331aeda6d7aa405fa6d8f2e7) --- doc/tor.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/doc/tor.md b/doc/tor.md index ccf8a226ee..34c5f1b5e7 100644 --- a/doc/tor.md +++ b/doc/tor.md @@ -62,14 +62,19 @@ The directory can be different of course, but virtual port numbers should be equ your bitcoind's P2P listen port (8333 by default), and target addresses and ports should be equal to binding address and port for inbound Tor connections (127.0.0.1:8334 by default). - -externalip=X You can tell bitcoin about its publicly reachable address using - this option, and this can be a .onion address. Given the above - configuration, you can find your .onion address in + -externalip=X You can tell bitcoin about its publicly reachable addresses using + this option, and this can be an onion address. Given the above + configuration, you can find your onion address in /var/lib/tor/bitcoin-service/hostname. For connections coming from unroutable addresses (such as 127.0.0.1, where the - Tor proxy typically runs), .onion addresses are given + Tor proxy typically runs), onion addresses are given preference for your node to advertise itself with. + You can set multiple local addresses with -externalip. The + one that will be rumoured to a particular peer is the most + compatible one and also using heuristics, e.g. the address + with the most incoming connections, etc. + -listen You'll need to enable listening for incoming connections, as this is off by default behind a proxy. From 4b1e64ac2fb12473487563f9e403c694811a4e10 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sun, 13 Dec 2020 11:36:22 -0800 Subject: [PATCH 35/84] Add patch to make codesign_allocate compatible with Apple's Github-Pull: #20644 Rebased-From: a4118c6e200e02e7560f8bc213697aa2909d95b1 (cherry picked from commit 35a10e4ebc9da916c470d2a9e5b68c3cfc3efd02) --- depends/packages/native_cctools.mk | 5 +++-- depends/patches/native_cctools/segalign.patch | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 depends/patches/native_cctools/segalign.patch diff --git a/depends/packages/native_cctools.mk b/depends/packages/native_cctools.mk index d56b636695..33f69375cc 100644 --- a/depends/packages/native_cctools.mk +++ b/depends/packages/native_cctools.mk @@ -4,7 +4,7 @@ $(package)_download_path=https://github.com/tpoechtrager/cctools-port/archive $(package)_file_name=$($(package)_version).tar.gz $(package)_sha256_hash=e51995a843533a3dac155dd0c71362dd471597a2d23f13dff194c6285362f875 $(package)_build_subdir=cctools -$(package)_patches=ld64_disable_threading.patch +$(package)_patches=ld64_disable_threading.patch segalign.patch ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) $(package)_clang_version=8.0.0 @@ -80,7 +80,8 @@ endef define $(package)_preprocess_cmds CC=$($(package)_cc) CXX=$($(package)_cxx) INSTALLPREFIX=$($(package)_extract_dir) ./libtapi/build.sh && \ CC=$($(package)_cc) CXX=$($(package)_cxx) INSTALLPREFIX=$($(package)_extract_dir) ./libtapi/install.sh && \ - patch -p1 < $($(package)_patch_dir)/ld64_disable_threading.patch + patch -p1 < $($(package)_patch_dir)/ld64_disable_threading.patch && \ + patch -p1 < $($(package)_patch_dir)/segalign.patch endef define $(package)_config_cmds diff --git a/depends/patches/native_cctools/segalign.patch b/depends/patches/native_cctools/segalign.patch new file mode 100644 index 0000000000..bcdbd67a6c --- /dev/null +++ b/depends/patches/native_cctools/segalign.patch @@ -0,0 +1,19 @@ +commit 7f2eb11ce6ebec7eb9b8e1429535e453054143e5 +Author: Pieter Wuille +Date: Sun Dec 13 11:34:21 2020 -0800 + + Make cctools_port's codesign_allocate compatible with Apple's + +diff --git a/cctools/libstuff/arch.c b/cctools/libstuff/arch.c +index 6f2332f..d85c25c 100644 +--- a/cctools/libstuff/arch.c ++++ b/cctools/libstuff/arch.c +@@ -134,7 +134,7 @@ static const struct cpu_entry cpu_entries[] = { + { CPU_TYPE_ARM, LITTLE_ENDIAN_BYTE_SEX, 0, 0x4000 }, + + /* desktop */ +- { CPU_TYPE_X86_64, LITTLE_ENDIAN_BYTE_SEX, 0x7fff5fc00000LL, 0x1000 }, ++ { CPU_TYPE_X86_64, LITTLE_ENDIAN_BYTE_SEX, 0x7fff5fc00000LL, 0x2000 /* Used to be 0x1000; changed to 0x2000 to match Apple's distributed codesign_allocate. */}, + { CPU_TYPE_I386, LITTLE_ENDIAN_BYTE_SEX, 0xc0000000, 0x1000 }, + { CPU_TYPE_POWERPC, BIG_ENDIAN_BYTE_SEX, 0xc0000000, 0x1000 }, + { CPU_TYPE_POWERPC64, BIG_ENDIAN_BYTE_SEX, 0x7ffff00000000LL, 0x1000 }, From 492ed0947f6d9700a4463f7e70d6292150229ee3 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Fri, 18 Dec 2020 01:31:33 +0200 Subject: [PATCH 36/84] qt: Align layout of checkboxes Github-Pull: bitcoin-core/gui#155 Rebased-From: e71b656f317f38ef0ba0874736f116dae39efc67 (cherry picked from commit ef7a155cf06bf54fff4ff9fda9b28207fcc9adfb) --- src/qt/forms/createwalletdialog.ui | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/qt/forms/createwalletdialog.ui b/src/qt/forms/createwalletdialog.ui index ea713e1abd..0b33c2cb8d 100644 --- a/src/qt/forms/createwalletdialog.ui +++ b/src/qt/forms/createwalletdialog.ui @@ -60,7 +60,7 @@ 20 50 - 171 + 220 22 @@ -79,7 +79,7 @@ 20 90 - 130 + 220 21 @@ -98,7 +98,7 @@ 20 115 - 171 + 220 22 @@ -130,7 +130,7 @@ 20 155 - 171 + 220 22 From 4bca4c28c26f740ded966e662415ff44a215b442 Mon Sep 17 00:00:00 2001 From: Ben Carman Date: Mon, 21 Dec 2020 09:57:06 -0600 Subject: [PATCH 37/84] rpc: Add missing description of vout in getrawtransaction help text Github-Pull: #20731 Rebased-From: b23349b8804fb60c6b3d7d0e2a95927a0d1b49b9 (cherry picked from commit 1fda7db64f0f30c23724f6db14f8a49d3975c716) --- 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 f60953eee0..0c7ea88ed8 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -121,7 +121,7 @@ static RPCHelpMan getrawtransaction() {RPCResult::Type::OBJ, "", "", { {RPCResult::Type::STR_HEX, "txid", "The transaction id"}, - {RPCResult::Type::STR, "vout", ""}, + {RPCResult::Type::NUM, "vout", "The output number"}, {RPCResult::Type::OBJ, "scriptSig", "The script", { {RPCResult::Type::STR, "asm", "asm"}, From 33d10b1f00e45548dfc6e753dccfbda2e04b3736 Mon Sep 17 00:00:00 2001 From: Amiti Uttarwar Date: Wed, 23 Dec 2020 11:38:59 -0800 Subject: [PATCH 38/84] [doc] Add permissions to the getpeerinfo help. This field was already being returned, but the RPCHelpMan did not indicate this. So, this PR updates the help text to match. Github-Pull: #20756 Rebased-From: 667d203687708390bc0f43f2dd3f4ab427b88338 (cherry picked from commit b1c0f97483f01f8836e5d83e98c881e44018cde5) --- src/rpc/net.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index f98ea63782..298529e4e7 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -141,6 +141,10 @@ static RPCHelpMan getpeerinfo() }}, {RPCResult::Type::BOOL, "whitelisted", /* optional */ true, "Whether the peer is whitelisted with default permissions\n" "(DEPRECATED, returned only if config option -deprecatedrpc=whitelisted is passed)"}, + {RPCResult::Type::ARR, "permissions", "Any special permissions that have been granted to this peer", + { + {RPCResult::Type::STR, "permission_type", Join(NET_PERMISSIONS_DOC, ",\n") + ".\n"}, + }}, {RPCResult::Type::NUM, "minfeefilter", "The minimum fee rate for transactions this peer accepts"}, {RPCResult::Type::OBJ_DYN, "bytessent_per_msg", "", { From 554445bc598b8c1f0473db29d3c52ea51f208280 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 4 Jan 2021 16:34:28 -0800 Subject: [PATCH 39/84] Revert "Add patch to make codesign_allocate compatible with Apple's" This reverts commit a4118c6e200e02e7560f8bc213697aa2909d95b1. Github-Pull: #20855 Rebased-From: a0eb4c551ebf8adfacb8c38c4ce56641fe379667 (cherry picked from commit 3308718a6b41f09e9dd3c7caa9986cd6cb8f2eeb) --- depends/packages/native_cctools.mk | 5 ++--- depends/patches/native_cctools/segalign.patch | 19 ------------------- 2 files changed, 2 insertions(+), 22 deletions(-) delete mode 100644 depends/patches/native_cctools/segalign.patch diff --git a/depends/packages/native_cctools.mk b/depends/packages/native_cctools.mk index 33f69375cc..d56b636695 100644 --- a/depends/packages/native_cctools.mk +++ b/depends/packages/native_cctools.mk @@ -4,7 +4,7 @@ $(package)_download_path=https://github.com/tpoechtrager/cctools-port/archive $(package)_file_name=$($(package)_version).tar.gz $(package)_sha256_hash=e51995a843533a3dac155dd0c71362dd471597a2d23f13dff194c6285362f875 $(package)_build_subdir=cctools -$(package)_patches=ld64_disable_threading.patch segalign.patch +$(package)_patches=ld64_disable_threading.patch ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) $(package)_clang_version=8.0.0 @@ -80,8 +80,7 @@ endef define $(package)_preprocess_cmds CC=$($(package)_cc) CXX=$($(package)_cxx) INSTALLPREFIX=$($(package)_extract_dir) ./libtapi/build.sh && \ CC=$($(package)_cc) CXX=$($(package)_cxx) INSTALLPREFIX=$($(package)_extract_dir) ./libtapi/install.sh && \ - patch -p1 < $($(package)_patch_dir)/ld64_disable_threading.patch && \ - patch -p1 < $($(package)_patch_dir)/segalign.patch + patch -p1 < $($(package)_patch_dir)/ld64_disable_threading.patch endef define $(package)_config_cmds diff --git a/depends/patches/native_cctools/segalign.patch b/depends/patches/native_cctools/segalign.patch deleted file mode 100644 index bcdbd67a6c..0000000000 --- a/depends/patches/native_cctools/segalign.patch +++ /dev/null @@ -1,19 +0,0 @@ -commit 7f2eb11ce6ebec7eb9b8e1429535e453054143e5 -Author: Pieter Wuille -Date: Sun Dec 13 11:34:21 2020 -0800 - - Make cctools_port's codesign_allocate compatible with Apple's - -diff --git a/cctools/libstuff/arch.c b/cctools/libstuff/arch.c -index 6f2332f..d85c25c 100644 ---- a/cctools/libstuff/arch.c -+++ b/cctools/libstuff/arch.c -@@ -134,7 +134,7 @@ static const struct cpu_entry cpu_entries[] = { - { CPU_TYPE_ARM, LITTLE_ENDIAN_BYTE_SEX, 0, 0x4000 }, - - /* desktop */ -- { CPU_TYPE_X86_64, LITTLE_ENDIAN_BYTE_SEX, 0x7fff5fc00000LL, 0x1000 }, -+ { CPU_TYPE_X86_64, LITTLE_ENDIAN_BYTE_SEX, 0x7fff5fc00000LL, 0x2000 /* Used to be 0x1000; changed to 0x2000 to match Apple's distributed codesign_allocate. */}, - { CPU_TYPE_I386, LITTLE_ENDIAN_BYTE_SEX, 0xc0000000, 0x1000 }, - { CPU_TYPE_POWERPC, BIG_ENDIAN_BYTE_SEX, 0xc0000000, 0x1000 }, - { CPU_TYPE_POWERPC64, BIG_ENDIAN_BYTE_SEX, 0x7ffff00000000LL, 0x1000 }, From c38b555adceeef3d283ca7fb94eed0d25fc0206a Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 13 Jan 2021 19:43:29 +0100 Subject: [PATCH 40/84] doc: Move 0.21.0 release notes from wiki (cherry picked from commit 66e6742a273796e9bdab37b4ad9e05cf18a99981) --- doc/release-notes.md | 994 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 922 insertions(+), 72 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 14cdeff1b1..af5cc46881 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,23 +1,9 @@ -*After branching off for a major version release of Bitcoin Core, use this -template to create the initial release notes draft.* +0.21.0 Release Notes +==================== -*The release notes draft is a temporary file that can be added to by anyone. See -[/doc/developer-notes.md#release-notes](/doc/developer-notes.md#release-notes) -for the process.* +Bitcoin Core version 0.21.0 is now available from: -*Create the draft, named* "*version* Release Notes Draft" -*(e.g. "0.20.0 Release Notes Draft"), as a collaborative wiki in:* - -https://github.com/bitcoin-core/bitcoin-devwiki/wiki/ - -*Before the final release, move the notes back to this git repository.* - -*version* Release Notes Draft -=============================== - -Bitcoin Core version *version* is now available from: - - + This release includes new features, various bug fixes and performance improvements, as well as updated translations. @@ -45,11 +31,6 @@ wallet versions of Bitcoin Core are generally supported. Compatibility ============== -During this release cycle, work has been done to ensure that the codebase is fully -compatible with C++17. The intention is to begin using C++17 features starting -with the 0.22.0 release. This means that a compiler that supports C++17 will be -required to compile 0.22.0. - Bitcoin Core is supported and extensively tested on operating systems using the Linux kernel, macOS 10.14+, and Windows 7 and newer. Bitcoin Core should also work on most other Unix-like systems but is not as @@ -66,7 +47,7 @@ accommodate the storage of Tor v3 and other BIP155 addresses. This means that if the file is modified by 0.21.0 or newer then older versions will not be able to read it. Those old versions, in the event of a downgrade, will log an error message "Incorrect keysize in addrman deserialization" and will continue normal -operation as if the file was missing, creating a new empty one. (#19954) +operation as if the file was missing, creating a new empty one. (#19954, #20284) Notable changes =============== @@ -90,6 +71,14 @@ P2P and network changes be enabled using the command line option `-whitelist=relay@127.0.0.1`. (#19988) +- This release adds support for Tor version 3 hidden services, and rumoring them + over the network to other peers using + [BIP155](https://github.com/bitcoin/bips/blob/master/bip-0155.mediawiki). + Version 2 hidden services are still fully supported by Bitcoin Core, but the + Tor network will start + [deprecating](https://blog.torproject.org/v2-deprecation-timeline) them in the + coming months. (#19954) + - The Tor onion service that is automatically created by setting the `-listenonion` configuration parameter will now be created as a Tor v3 service instead of Tor v2. The private key that was used for Tor v2 (if any) will be @@ -97,15 +86,49 @@ P2P and network changes `-datadir`) and can be removed if not needed. Bitcoin Core will no longer attempt to read it. The private key for the Tor v3 service will be saved in a file named `onion_v3_private_key`. To use the deprecated Tor v2 service (not - recommended), then `onion_private_key` can be copied over + recommended), the `onion_private_key` can be copied over `onion_v3_private_key`, e.g. `cp -f onion_private_key onion_v3_private_key`. (#19954) +- The client writes a file (`anchors.dat`) at shutdown with the network addresses + of the node’s two outbound block-relay-only peers (so called "anchors"). The + next time the node starts, it reads this file and attempts to reconnect to those + same two peers. This prevents an attacker from using node restarts to trigger a + complete change in peers, which would be something they could use as part of an + eclipse attack. (#17428) + +- This release adds support for serving + [BIP157](https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki) compact + filters to peers on the network when enabled using + `-blockfilterindex=1 -peercfilters=1`. (#16442) + +- This release adds support for signets + ([BIP325](https://github.com/bitcoin/bips/blob/master/bip-0325.mediawiki)) in + addition to the existing mainnet, testnet, and regtest networks. Signets are + centrally-controlled test networks, allowing them to be more predictable + test environments than the older testnet. One public signet is maintained, and + selectable using `-signet`. It is also possible to create personal signets. + (#18267). + +- This release implements + [BIP339](https://github.com/bitcoin/bips/blob/master/bip-0339.mediawiki) + wtxid relay. When negotiated, transactions are announced using their wtxid + instead of their txid. (#18044). + +- This release implements the proposed Taproot consensus rules + ([BIP341](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki) and + [BIP342](https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki)), + without activation on mainnet. Experimentation with Taproot can be done on + signet, where its rules are already active. (#19553) + Updated RPCs ------------ +- The `getpeerinfo` RPC has a new `network` field that provides the type of + network ("ipv4", "ipv6", or "onion") that the peer connected through. (#20002) + - The `getpeerinfo` RPC now has additional `last_block` and `last_transaction` - fields that return the UNIX epoch time of the last block and the last valid + fields that return the UNIX epoch time of the last block and the last *valid* transaction received from each peer. (#19731) - `getnetworkinfo` now returns two new fields, `connections_in` and @@ -117,7 +140,7 @@ Updated RPCs integers instead of signed 32-bit integers. This matches their treatment in consensus logic. Versions greater than 2 continue to be non-standard (matching previous behavior of smaller than 1 or greater than 2 being - non-standard). Note that this includes the joinpsbt command, which combines + non-standard). Note that this includes the `joinpsbt` command, which combines partially-signed transactions by selecting the highest version number. (#16525) @@ -131,17 +154,6 @@ Updated RPCs whether initial broadcast of the transaction has been acknowledged by a peer. `getmempoolancestors` and `getmempooldescendants` are also updated. -- The `bumpfee`, `fundrawtransaction`, `sendmany`, `sendtoaddress`, and `walletcreatefundedpsbt` -RPC commands have been updated to include two new fee estimation methods "BTC/kB" and "sat/B". -The target is the fee expressed explicitly in the given form. Note that use of this feature -will trigger BIP 125 (replace-by-fee) opt-in. (#11413) - -- In addition, the `estimate_mode` parameter is now case insensitive for all of - the above RPC commands. (#11413) - -- The `bumpfee` command now uses `conf_target` rather than `confTarget` in the - options. (#11413) - - The `getpeerinfo` RPC no longer returns the `banscore` field unless the configuration option `-deprecatedrpc=banscore` is used. The `banscore` field will be fully removed in the next major release. (#19469) @@ -160,6 +172,12 @@ will trigger BIP 125 (replace-by-fee) opt-in. (#11413) it is recommended to instead use the `connection_type` field (it will return `manual` when addnode is true). (#19725) +- The `getpeerinfo` RPC no longer returns the `whitelisted` field by default. + This field will be fully removed in the next major release. It can be accessed + with the configuration option `-deprecatedrpc=getpeerinfo_whitelisted`. However, + it is recommended to instead use the `permissions` field to understand if specific + privileges have been granted to the peer. (#19770) + - The `walletcreatefundedpsbt` RPC call will now fail with `Insufficient funds` when inputs are manually selected but are not enough to cover the outputs and fee. Additional inputs can automatically be added through the @@ -175,7 +193,7 @@ New RPCs - The `getindexinfo` RPC returns the actively running indices of the node, including their current sync status and height. It also accepts an `index_name` - to specify returning only the status of that index. (#19550) + to specify returning the status of that index only. (#19550) Build System ------------ @@ -206,24 +224,31 @@ Updated settings according to RFC 4632. Netmasks are used in the `-rpcallowip` and `-whitelist` configuration options and in the `setban` RPC. (#19628) -Changes to Wallet or GUI related settings can be found in the GUI or Wallet section below. +- The `-blocksonly` setting now completely disables fee estimation. (#18766) + +Changes to Wallet or GUI related settings can be found in the GUI or Wallet section below. Tools and Utilities ------------------- -- The `connections` field of `bitcoin-cli -getinfo` is expanded to return a JSON - object with `in`, `out` and `total` numbers of peer connections. It previously - returned a single integer value for the total number of peer connections. (#19405) +- A new `bitcoin-cli -netinfo` command provides a network peer connections + dashboard that displays data from the `getpeerinfo` and `getnetworkinfo` RPCs + in a human-readable format. An optional integer argument from `0` to `4` may + be passed to see increasing levels of detail. (#19643) - A new `bitcoin-cli -generate` command, equivalent to RPC `generatenewaddress` followed by `generatetoaddress`, can generate blocks for command line testing - purposes. This is a client-side version of the - former `generate` RPC. See the help for details. (#19133) + purposes. This is a client-side version of the former `generate` RPC. See the + help for details. (#19133) - The `bitcoin-cli -getinfo` command now displays the wallet name and balance for each of the loaded wallets when more than one is loaded (e.g. in multiwallet mode) and a wallet is not specified with `-rpcwallet`. (#18594) +- The `connections` field of `bitcoin-cli -getinfo` is now expanded to return a JSON + object with `in`, `out` and `total` numbers of peer connections. It previously + returned a single integer value for the total number of peer connections. (#19405) + New settings ------------ @@ -273,10 +298,15 @@ Wallet methods remain backwards compatible. (#15937) - A new `send` RPC with similar syntax to `walletcreatefundedpsbt`, including - support for coin selection and a custom fee rate. The `send` RPC is - experimental and may change in subsequent releases. Using it is encouraged - once it's no longer experimental: `sendmany` and `sendtoaddress` may be - deprecated in a future release. (#16378) + support for coin selection and a custom fee rate, is added. The `send` RPC is + experimental and may change in subsequent releases. (#16378) + +- The `estimate_mode` parameter is now case-insensitive in the `bumpfee`, + `fundrawtransaction`, `sendmany`, `sendtoaddress`, `send` and + `walletcreatefundedpsbt` RPCs. (#11413) + +- The `bumpfee` RPC now uses `conf_target` rather than `confTarget` in the + options. (#11413) - `fundrawtransaction` and `walletcreatefundedpsbt` when used with the `lockUnspents` argument now lock manually selected coins, in addition to @@ -285,8 +315,9 @@ Wallet - The `-zapwallettxes` startup option has been removed and its functionality removed from the wallet. This option was originally intended to allow for - the fee bumping of transactions that did not signal RBF. This functionality - has been superseded with the abandon transaction feature. (#19671) + rescuing wallets which were affected by a malleability attack. More recently, + it has been used in the fee bumping of transactions that did not signal RBF. + This functionality has been superseded with the abandon transaction feature. (#19671) - The error code when no wallet is loaded, but a wallet RPC is called, has been changed from `-32601` (method not found) to `-18` (wallet not found). @@ -303,7 +334,7 @@ new keys and addresses like previous releases did. New wallets can be created through the GUI (which has a more prominent create wallet option), through the `bitcoin-cli createwallet` or `bitcoin-wallet -create` commands, or the `createwallet` RPC. (#15454) +create` commands, or the `createwallet` RPC. (#15454, #20186) ### Experimental Descriptor Wallets @@ -312,8 +343,8 @@ is available. Additionally there may be some bugs and current functions may chan Bugs and missing functionality can be reported to the [issue tracker](https://github.com/bitcoin/bitcoin/issues). 0.21 introduces a new type of wallet - Descriptor Wallets. Descriptor Wallets store -scriptPubKey information using descriptors. This is in contrast to the Legacy Wallet -structure where keys are used to generate scriptPubKeys and addresses. Because of this +scriptPubKey information using output descriptors. This is in contrast to the Legacy Wallet +structure where keys are used to implicitly generate scriptPubKeys and addresses. Because of this shift to being script based instead of key based, many of the confusing things that Legacy Wallets do are not possible with Descriptor Wallets. Descriptor Wallets use a definition of "mine" for scripts which is simpler and more intuitive than that used by Legacy Wallets. @@ -321,7 +352,7 @@ Descriptor Wallets also uses different semantics for watch-only things and impor As Descriptor Wallets are a new type of wallet, their introduction does not affect existing wallets. Users who already have a Bitcoin Core wallet can continue to use it as they did before without -any change in behavior. Newly created Legacy Wallets (which is the default type of wallet) will +any change in behavior. Newly created Legacy Wallets (which remains the default type of wallet) will behave as they did in previous versions of Bitcoin Core. The differences between Descriptor Wallets and Legacy Wallets are largely limited to non user facing @@ -330,15 +361,13 @@ as described below. #### Creating Descriptor Wallets -Descriptor Wallets are not created by default. They must be explicitly created using the -`createwallet` RPC or via the GUI. A `descriptors` option has been added to `createwallet`. -Setting `descriptors` to `true` will create a Descriptor Wallet instead of a Legacy Wallet. +Descriptor wallets are not the default type of wallet. In the GUI, a checkbox has been added to the Create Wallet Dialog to indicate that a -Descriptor Wallet should be created. +Descriptor Wallet should be created. And a `descriptors` option has been added to `createwallet` RPC. +Setting `descriptors` to `true` will create a Descriptor Wallet instead of a Legacy Wallet. -Without those options being set, a Legacy Wallet will be created instead. Additionally the -Default Wallet created upon first startup of Bitcoin Core will be a Legacy Wallet. +Without those options being set, a Legacy Wallet will be created instead. #### `IsMine` Semantics @@ -354,7 +383,7 @@ what scripts the wallet will consider to belong to it. Additionally the implemen in Descriptor Wallets is far simpler than for Legacy Wallets. Notably, in Legacy Wallets, `IsMine` allowed for users to take one type of address (e.g. P2PKH), mutate it into another address type (e.g. P2WPKH), and the wallet would still detect outputs sending to the new address type -even without that address being requested from the wallet. Descriptor Wallets does not +even without that address being requested from the wallet. Descriptor Wallets do not allow for this and will only watch for the addresses that were explicitly requested from the wallet. These changes to `IsMine` will make it easier to reason about what scripts the wallet will @@ -382,15 +411,15 @@ New export RPCs for Descriptor Wallets have not yet been added. The following RPCs are disabled for Descriptor Wallets: -* importprivkey -* importpubkey -* importaddress -* importwallet -* dumpprivkey -* dumpwallet -* importmulti -* addmultisigaddress -* sethdseed +* `importprivkey` +* `importpubkey` +* `importaddress` +* `importwallet` +* `dumpprivkey` +* `dumpwallet` +* `importmulti` +* `addmultisigaddress` +* `sethdseed` #### Watchonly Wallets @@ -410,7 +439,7 @@ workflow but the typical GUI Send, `sendtoaddress`, etc. workflows would still b non-functional. This issue is worsened if the wallet contains both single key (e.g. `wpkh(...)`) descriptors and such -multiple key descriptors as some transactions could be signed and broadast and others not. This is +multiple key descriptors as some transactions could be signed and broadcast and others not. This is due to some transactions containing only single key inputs, while others would contain both single key and multiple key inputs, depending on which are available and how the coin selection algorithm selects inputs. However this is not considered to be a supported use case; multisigs @@ -423,14 +452,42 @@ The change to using descriptors changes the default derivation paths used by Bit to adhere to BIP 44/49/84. Descriptors with different derivation paths can be imported without issue. +#### SQLite Database Backend + +Descriptor wallets use SQLite for the wallet file instead of the Berkeley DB used in legacy wallets. +This will break compatibility with any existing tooling that operates on wallets, however compatibility +was already being broken by the move to descriptors. + ### Wallet RPC changes - The `upgradewallet` RPC replaces the `-upgradewallet` command line option. (#15761) + - The `settxfee` RPC will fail if the fee was set higher than the `-maxtxfee` command line setting. The wallet will already fail to create transactions with fees higher than `-maxtxfee`. (#18467) +- A new `fee_rate` parameter/option denominated in satoshis per vbyte (sat/vB) + is introduced to the `sendtoaddress`, `sendmany`, `fundrawtransaction` and + `walletcreatefundedpsbt` RPCs as well as to the experimental new `send` + RPC. The legacy `feeRate` option in `fundrawtransaction` and + `walletcreatefundedpsbt` still exists for setting a fee rate in BTC per 1,000 + vbytes (BTC/kvB), but it is expected to be deprecated soon to avoid + confusion. For these RPCs, the fee rate error message is updated from BTC/kB + to sat/vB and the help documentation in BTC/kB is updated to BTC/kvB. The + `send` and `sendtoaddress` RPC examples are updated to aid users in creating + transactions with explicit fee rates. (#20305, #11413) + +- The `bumpfee` RPC `fee_rate` option is changed from BTC/kvB to sat/vB and the + help documentation is updated. Users are warned that this is a breaking API + change, but it should be relatively benign: the large (100,000 times) + difference between BTC/kvB and sat/vB units means that a transaction with a + fee rate mistakenly calculated in BTC/kvB rather than sat/vB should raise an + error due to the fee rate being set too low. In the worst case, the + transaction may send at 1 sat/vB, but as Replace-by-Fee (BIP125 RBF) is active + by default when an explicit fee rate is used, the transaction fee can be + bumped. (#20305) + GUI changes ----------- @@ -476,11 +533,804 @@ Tests setting. The settings `-signetchallenge` and `-signetseednode` allow enabling a custom signet. +- The `generateblock` RPC allows testers using regtest mode to + generate blocks that consist of a custom set of transactions. (#17693) + +0.21.0 change log +================= + +### Consensus +- #18267 BIP-325: Signet (kallewoof) +- #20016 uint256: 1 is a constant (ajtowns) +- #20006 Fix misleading error message: Clean stack rule (sanket1729) +- #19953 Implement BIP 340-342 validation (Schnorr/taproot/tapscript) (sipa) +- #20169 Taproot follow-up: Make ComputeEntrySchnorr and ComputeEntryECDSA const to clarify contract (practicalswift) + +### Policy +- #18766 Disable fee estimation in blocksonly mode (darosior) +- #19630 Cleanup fee estimation code (darosior) +- #20165 Only relay Taproot spends if next block has it active (sipa) + +### Mining +- #17946 Fix GBT: Restore "!segwit" and "csv" to "rules" key (luke-jr) + +### Privacy +- #16432 Add privacy to the Overview page (hebasto) +- #18861 Do not answer GETDATA for to-be-announced tx (sipa) +- #18038 Mempool tracks locally submitted transactions to improve wallet privacy (amitiuttarwar) +- #19109 Only allow getdata of recently announced invs (sipa) + +### Block and transaction handling +- #17737 Add ChainstateManager, remove BlockManager global (jamesob) +- #18960 indexes: Add compact block filter headers cache (jnewbery) +- #13204 Faster sigcache nonce (JeremyRubin) +- #19088 Use std::chrono throughout some validation functions (fanquake) +- #19142 Make VerifyDB level 4 interruptible (MarcoFalke) +- #17994 Flush undo files after last block write (kallewoof) +- #18990 log: Properly log txs rejected from mempool (MarcoFalke) +- #18984 Remove unnecessary input blockfile SetPos (dgenr8) +- #19526 log: Avoid treating remote misbehvior as local system error (MarcoFalke) +- #18044 Use wtxid for transaction relay (sdaftuar) +- #18637 coins: allow cache resize after init (jamesob) +- #19854 Avoid locking CTxMemPool::cs recursively in simple cases (hebasto) +- #19478 Remove CTxMempool::mapLinks data structure member (JeremyRubin) +- #19927 Reduce direct `g_chainman` usage (dongcarl) +- #19898 log: print unexpected version warning in validation log category (n-thumann) +- #20036 signet: Add assumed values for default signet (MarcoFalke) +- #20048 chainparams: do not log signet startup messages for other chains (jonatack) +- #19339 re-delegate absurd fee checking from mempool to clients (glozow) +- #20035 signet: Fix uninitialized read in validation (MarcoFalke) +- #20157 Bugfix: chainparams: Add missing (always enabled) Taproot deployment for Signet (luke-jr) +- #20263 Update assumed chain params (MarcoFalke) +- #20372 Avoid signed integer overflow when loading a mempool.dat file with a malformed time field (practicalswift) +- #18621 script: Disallow silent bool -> cscript conversion (MarcoFalke) +- #18612, #18732 script: Remove undocumented and unused operator+ (MarcoFalke) +- #19317 Add a left-justified width field to `log2_work` component for a uniform debug.log output (jamesgmorgan) + +### P2P protocol and network code +- #18544 Limit BIP37 filter lifespan (active between `filterload`..`filterclear`) (theStack) +- #18806 Remove is{Empty,Full} flags from CBloomFilter, clarify CVE fix (theStack) +- #18512 Improve asmap checks and add sanity check (sipa) +- #18877 Serve cfcheckpt requests (jnewbery) +- #18895 Unbroadcast followups: rpcs, nLastResend, mempool sanity check (gzhao408) +- #19010 net processing: Add support for `getcfheaders` (jnewbery) +- #16939 Delay querying DNS seeds (ajtowns) +- #18807 Unbroadcast follow-ups (amitiuttarwar) +- #19044 Add support for getcfilters (jnewbery) +- #19084 improve code documentation for dns seed behaviour (ajtowns) +- #19260 disconnect peers that send filterclear + update existing filter msg disconnect logic (gzhao408) +- #19284 Add seed.bitcoin.wiz.biz to DNS seeds (wiz) +- #19322 split PushInventory() (jnewbery) +- #19204 Reduce inv traffic during IBD (MarcoFalke) +- #19470 banlist: log post-swept banlist size at startup (fanquake) +- #19191 Extract download permission from noban (MarcoFalke) +- #14033 Drop `CADDR_TIME_VERSION` checks now that `MIN_PEER_PROTO_VERSION` is greater (Empact) +- #19464 net, rpc: remove -banscore option, deprecate banscore in getpeerinfo (jonatack) +- #19514 [net/net processing] check banman pointer before dereferencing (jnewbery) +- #19512 banscore updates to gui, tests, release notes (jonatack) +- #19360 improve encapsulation of CNetAddr (vasild) +- #19217 disambiguate block-relay-only variable names from blocksonly variables (glowang) +- #19473 Add -networkactive option (hebasto) +- #19472 [net processing] Reduce `cs_main` scope in MaybeDiscourageAndDisconnect() (jnewbery) +- #19583 clean up Misbehaving() (jnewbery) +- #19534 save the network type explicitly in CNetAddr (vasild) +- #19569 Enable fetching of orphan parents from wtxid peers (sipa) +- #18991 Cache responses to GETADDR to prevent topology leaks (naumenkogs) +- #19596 Deduplicate parent txid loop of requested transactions and missing parents of orphan transactions (sdaftuar) +- #19316 Cleanup logic around connection types (amitiuttarwar) +- #19070 Signal support for compact block filters with `NODE_COMPACT_FILTERS` (jnewbery) +- #19705 Shrink CAddress from 48 to 40 bytes on x64 (vasild) +- #19704 Move ProcessMessage() to PeerLogicValidation (jnewbery) +- #19628 Change CNetAddr::ip to have flexible size (vasild) +- #19797 Remove old check for 3-byte shifted IP addresses from pre-0.2.9 nodes (#19797) +- #19607 Add Peer struct for per-peer data in net processing (jnewbery) +- #19857 improve nLastBlockTime and nLastTXTime documentation (jonatack) +- #19724 Cleanup connection types- followups (amitiuttarwar) +- #19670 Protect localhost and block-relay-only peers from eviction (sdaftuar) +- #19728 Increase the ip address relay branching factor for unreachable networks (sipa) +- #19879 Miscellaneous wtxid followups (amitiuttarwar) +- #19697 Improvements on ADDR caching (naumenkogs) +- #17785 Unify Send and Receive protocol versions (hebasto) +- #19845 CNetAddr: add support to (un)serialize as ADDRv2 (vasild) +- #19107 Move all header verification into the network layer, extend logging (troygiorshev) +- #20003 Exit with error message if -proxy is specified without arguments (instead of continuing without proxy server) (practicalswift) +- #19991 Use alternative port for incoming Tor connections (hebasto) +- #19723 Ignore unknown messages before VERACK (sdaftuar) +- #19954 Complete the BIP155 implementation and upgrade to TORv3 (vasild) +- #20119 BIP155 follow-ups (sipa) +- #19988 Overhaul transaction request logic (sipa) +- #17428 Try to preserve outbound block-relay-only connections during restart (hebasto) +- #19911 Guard `vRecvGetData` with `cs_vRecv` and `orphan_work_set` with `g_cs_orphans` (narula) +- #19753 Don't add AlreadyHave transactions to recentRejects (troygiorshev) +- #20187 Test-before-evict bugfix and improvements for block-relay-only peers (sdaftuar) +- #20237 Hardcoded seeds update for 0.21 (laanwj) +- #20212 Fix output of peer address in version message (vasild) +- #20284 Ensure old versions don't parse peers.dat (vasild) +- #20405 Avoid calculating onion address checksum when version is not 3 (lontivero) +- #20564 Don't send 'sendaddrv2' to pre-70016 software, and send before 'verack' (sipa) +- #20660 Move signet onion seed from v2 to v3 (Sjors) + +### Wallet +- #18262 Exit selection when `best_waste` is 0 (achow101) +- #17824 Prefer full destination groups in coin selection (fjahr) +- #17219 Allow transaction without change if keypool is empty (Sjors) +- #15761 Replace -upgradewallet startup option with upgradewallet RPC (achow101) +- #18671 Add BlockUntilSyncedToCurrentChain to dumpwallet (MarcoFalke) +- #16528 Native Descriptor Wallets using DescriptorScriptPubKeyMan (achow101) +- #18777 Recommend absolute path for dumpwallet (MarcoFalke) +- #16426 Reverse `cs_main`, `cs_wallet` lock order and reduce `cs_main` locking (ariard) +- #18699 Avoid translating RPC errors (MarcoFalke) +- #18782 Make sure no DescriptorScriptPubKeyMan or WalletDescriptor members are left uninitialized after construction (practicalswift) +- #9381 Remove CWalletTx merging logic from AddToWallet (ryanofsky) +- #16946 Include a checksum of encrypted private keys (achow101) +- #17681 Keep inactive seeds after sethdseed and derive keys from them as needed (achow101) +- #18918 Move salvagewallet into wallettool (achow101) +- #14988 Fix for confirmed column in csv export for payment to self transactions (benthecarman) +- #18275 Error if an explicit fee rate was given but the needed fee rate differed (kallewoof) +- #19054 Skip hdKeypath of 'm' when determining inactive hd seeds (achow101) +- #17938 Disallow automatic conversion between disparate hash types (Empact) +- #19237 Check size after unserializing a pubkey (elichai) +- #11413 sendtoaddress/sendmany: Add explicit feerate option (kallewoof) +- #18850 Fix ZapSelectTx to sync wallet spends (bvbfan) +- #18923 Never schedule MaybeCompactWalletDB when `-flushwallet` is off (MarcoFalke) +- #19441 walletdb: Don't reinitialize desc cache with multiple cache entries (achow101) +- #18907 walletdb: Don't remove database transaction logs and instead error (achow101) +- #19334 Introduce WalletDatabase abstract class (achow101) +- #19335 Cleanup and separate BerkeleyDatabase and BerkeleyBatch (achow101) +- #19102 Introduce and use DummyDatabase instead of dummy BerkeleyDatabase (achow101) +- #19568 Wallet should not override signing errors (fjahr) +- #17204 Do not turn `OP_1NEGATE` in scriptSig into `0x0181` in signing code (sipa) (meshcollider) +- #19457 Cleanup wallettool salvage and walletdb extraneous declarations (achow101) +- #15937 Add loadwallet and createwallet `load_on_startup` options (ryanofsky) +- #16841 Replace GetScriptForWitness with GetScriptForDestination (meshcollider) +- #14582 always do avoid partial spends if fees are within a specified range (kallewoof) +- #19743 -maxapsfee follow-up (kallewoof) +- #19289 GetWalletTx and IsMine require `cs_wallet` lock (promag) +- #19671 Remove -zapwallettxes (achow101) +- #19805 Avoid deserializing unused records when salvaging (achow101) +- #19754 wallet, gui: Reload previously loaded wallets on startup (achow101) +- #19738 Avoid multiple BerkeleyBatch in DelAddressBook (promag) +- #19919 bugfix: make LoadWallet assigns status always (AkioNak) +- #16378 The ultimate send RPC (Sjors) +- #15454 Remove the automatic creation and loading of the default wallet (achow101) +- #19501 `send*` RPCs in the wallet returns the "fee reason" (stackman27) +- #20130 Remove db mode string (S3RK) +- #19077 Add sqlite as an alternative wallet database and use it for new descriptor wallets (achow101) +- #20125 Expose database format in getwalletinfo (promag) +- #20198 Show name, format and if uses descriptors in bitcoin-wallet tool (jonasschnelli) +- #20216 Fix buffer over-read in SQLite file magic check (theStack) +- #20186 Make -wallet setting not create wallets (ryanofsky) +- #20230 Fix bug when just created encrypted wallet cannot get address (hebasto) +- #20282 Change `upgradewallet` return type to be an object (jnewbery) +- #20220 Explicit fee rate follow-ups/fixes for 0.21 (jonatack) +- #20199 Ignore (but warn) on duplicate -wallet parameters (jonasschnelli) +- #20324 Set DatabaseStatus::SUCCESS in MakeSQLiteDatabase (MarcoFalke) +- #20266 Fix change detection of imported internal descriptors (achow101) +- #20153 Do not import a descriptor with hardened derivations into a watch-only wallet (S3RK) +- #20344 Fix scanning progress calculation for single block range (theStack) +- #19502 Bugfix: Wallet: Soft-fail exceptions within ListWalletDir file checks (luke-jr) +- #20378 Fix potential division by 0 in WalletLogPrintf (jonasschnelli) +- #18836 Upgradewallet fixes and additional tests (achow101) +- #20139 Do not return warnings from UpgradeWallet() (stackman27) +- #20305 Introduce `fee_rate` sat/vB param/option (jonatack) +- #20426 Allow zero-fee fundrawtransaction/walletcreatefundedpsbt and other fixes (jonatack) +- #20573 wallet, bugfix: allow send with string `fee_rate` amounts (jonatack) + +### RPC and other APIs +- #18574 cli: Call getbalances.ismine.trusted instead of getwalletinfo.balance (jonatack) +- #17693 Add `generateblock` to mine a custom set of transactions (andrewtoth) +- #18495 Remove deprecated migration code (vasild) +- #18493 Remove deprecated "size" from mempool txs (vasild) +- #18467 Improve documentation and return value of settxfee (fjahr) +- #18607 Fix named arguments in documentation (MarcoFalke) +- #17831 doc: Fix and extend getblockstats examples (asoltys) +- #18785 Prevent valgrind false positive in `rest_blockhash_by_height` (ryanofsky) +- #18999 log: Remove "No rpcpassword set" from logs (MarcoFalke) +- #19006 Avoid crash when `g_thread_http` was never started (MarcoFalke) +- #18594 cli: Display multiwallet balances in -getinfo (jonatack) +- #19056 Make gettxoutsetinfo/GetUTXOStats interruptible (MarcoFalke) +- #19112 Remove special case for unknown service flags (MarcoFalke) +- #18826 Expose txinwitness for coinbase in JSON form from RPC (rvagg) +- #19282 Rephrase generatetoaddress help, and use `PACKAGE_NAME` (luke-jr) +- #16377 don't automatically append inputs in walletcreatefundedpsbt (Sjors) +- #19200 Remove deprecated getaddressinfo fields (jonatack) +- #19133 rpc, cli, test: add bitcoin-cli -generate command (jonatack) +- #19469 Deprecate banscore field in getpeerinfo (jonatack) +- #16525 Dump transaction version as an unsigned integer in RPC/TxToUniv (TheBlueMatt) +- #19555 Deduplicate WriteHDKeypath() used in decodepsbt (theStack) +- #19589 Avoid useless mempool query in gettxoutproof (MarcoFalke) +- #19585 RPCResult Type of MempoolEntryDescription should be OBJ (stylesuxx) +- #19634 Document getwalletinfo's `unlocked_until` field as optional (justinmoon) +- #19658 Allow RPC to fetch all addrman records and add records to addrman (jnewbery) +- #19696 Fix addnode remove command error (fjahr) +- #18654 Separate bumpfee's psbt creation function into psbtbumpfee (achow101) +- #19655 Catch listsinceblock `target_confirmations` exceeding block count (adaminsky) +- #19644 Document returned error fields as optional if applicable (theStack) +- #19455 rpc generate: print useful help and error message (jonatack) +- #19550 Add listindices RPC (fjahr) +- #19169 Validate provided keys for `query_options` parameter in listunspent (PastaPastaPasta) +- #18244 fundrawtransaction and walletcreatefundedpsbt also lock manually selected coins (Sjors) +- #14687 zmq: Enable TCP keepalive (mruddy) +- #19405 Add network in/out connections to `getnetworkinfo` and `-getinfo` (jonatack) +- #19878 rawtransaction: Fix argument in combinerawtransaction help message (pinheadmz) +- #19940 Return fee and vsize from testmempoolaccept (gzhao408) +- #13686 zmq: Small cleanups in the ZMQ code (domob1812) +- #19386, #19528, #19717, #19849, #19994 Assert that RPCArg names are equal to CRPCCommand ones (MarcoFalke) +- #19725 Add connection type to getpeerinfo, improve logs (amitiuttarwar) +- #19969 Send RPC bug fix and touch-ups (Sjors) +- #18309 zmq: Add support to listen on multiple interfaces (n-thumann) +- #20055 Set HTTP Content-Type in bitcoin-cli (laanwj) +- #19956 Improve invalid vout value rpc error message (n1rna) +- #20101 Change no wallet loaded message to be clearer (achow101) +- #19998 Add `via_tor` to `getpeerinfo` output (hebasto) +- #19770 getpeerinfo: Deprecate "whitelisted" field (replaced by "permissions") (luke-jr) +- #20120 net, rpc, test, bugfix: update GetNetworkName, GetNetworksInfo, regression tests (jonatack) +- #20595 Improve heuristic hex transaction decoding (sipa) +- #20731 Add missing description of vout in getrawtransaction help text (benthecarman) +- #19328 Add gettxoutsetinfo `hash_type` option (fjahr) +- #19731 Expose nLastBlockTime/nLastTXTime as last `block/last_transaction` in getpeerinfo (jonatack) +- #19572 zmq: Create "sequence" notifier, enabling client-side mempool tracking (instagibbs) +- #20002 Expose peer network in getpeerinfo; simplify/improve -netinfo (jonatack) + +### GUI +- #17905 Avoid redundant tx status updates (ryanofsky) +- #18646 Use `PACKAGE_NAME` in exception message (fanquake) +- #17509 Save and load PSBT (Sjors) +- #18769 Remove bug fix for Qt < 5.5 (10xcryptodev) +- #15768 Add close window shortcut (IPGlider) +- #16224 Bilingual GUI error messages (hebasto) +- #18922 Do not translate InitWarning messages in debug.log (hebasto) +- #18152 Use NotificationStatus enum for signals to GUI (hebasto) +- #18587 Avoid wallet tryGetBalances calls in WalletModel::pollBalanceChanged (ryanofsky) +- #17597 Fix height of QR-less ReceiveRequestDialog (hebasto) +- #17918 Hide non PKHash-Addresses in signing address book (emilengler) +- #17956 Disable unavailable context menu items in transactions tab (kristapsk) +- #17968 Ensure that ModalOverlay is resized properly (hebasto) +- #17993 Balance/TxStatus polling update based on last block hash (furszy) +- #18424 Use parent-child relation to manage lifetime of OptionsModel object (hebasto) +- #18452 Fix shutdown when `waitfor*` cmds are called from RPC console (hebasto) +- #15202 Add Close All Wallets action (promag) +- #19132 lock `cs_main`, `m_cached_tip_mutex` in that order (vasild) +- #18898 Display warnings as rich text (hebasto) +- #19231 add missing translation.h include to fix build (fanquake) +- #18027 "PSBT Operations" dialog (gwillen) +- #19256 Change combiner for signals to `optional_last_value` (fanquake) +- #18896 Reset toolbar after all wallets are closed (hebasto) +- #18993 increase console command max length (10xcryptodev) +- #19323 Fix regression in *txoutset* in GUI console (hebasto) +- #19210 Get rid of cursor in out-of-focus labels (hebasto) +- #19011 Reduce `cs_main` lock accumulation during GUI startup (jonasschnelli) +- #19844 Remove usage of boost::bind (fanquake) +- #20479 Fix QPainter non-determinism on macOS (0.21 backport) (laanwj) +- gui#6 Do not truncate node flag strings in debugwindow peers details tab (Saibato) +- gui#8 Fix regression in TransactionTableModel (hebasto) +- gui#17 doc: Remove outdated comment in TransactionTablePriv (MarcoFalke) +- gui#20 Wrap tooltips in the intro window (hebasto) +- gui#30 Disable the main window toolbar when the modal overlay is shown (hebasto) +- gui#34 Show permissions instead of whitelisted (laanwj) +- gui#35 Parse params directly instead of through node (ryanofsky) +- gui#39 Add visual accenting for the 'Create new receiving address' button (hebasto) +- gui#40 Clarify block height label (hebasto) +- gui#43 bugfix: Call setWalletActionsEnabled(true) only for the first wallet (hebasto) +- gui#97 Relax GUI freezes during IBD (jonasschnelli) +- gui#71 Fix visual quality of text in QR image (hebasto) +- gui#96 Slight improve create wallet dialog (Sjors) +- gui#102 Fix SplashScreen crash when run with -disablewallet (hebasto) +- gui#116 Fix unreasonable default size of the main window without loaded wallets (hebasto) +- gui#120 Fix multiwallet transaction notifications (promag) + +### Build system +- #18504 Drop bitcoin-tx and bitcoin-wallet dependencies on libevent (ryanofsky) +- #18586 Bump gitian descriptors to 0.21 (laanwj) +- #17595 guix: Enable building for `x86_64-w64-mingw32` target (dongcarl) +- #17929 add linker optimisation flags to gitian & guix (Linux) (fanquake) +- #18556 Drop make dist in gitian builds (hebasto) +- #18088 ensure we aren't using GNU extensions (fanquake) +- #18741 guix: Make source tarball using git-archive (dongcarl) +- #18843 warn on potentially uninitialized reads (vasild) +- #17874 make linker checks more robust (fanquake) +- #18535 remove -Qunused-arguments workaround for clang + ccache (fanquake) +- #18743 Add --sysroot option to mac os native compile flags (ryanofsky) +- #18216 test, build: Enable -Werror=sign-compare (Empact) +- #18928 don't pass -w when building for Windows (fanquake) +- #16710 Enable -Wsuggest-override if available (hebasto) +- #18738 Suppress -Wdeprecated-copy warnings (hebasto) +- #18862 Remove fdelt_chk back-compat code and sanity check (fanquake) +- #18887 enable -Werror=gnu (vasild) +- #18956 enforce minimum required Windows version (7) (fanquake) +- #18958 guix: Make V=1 more powerful for debugging (dongcarl) +- #18677 Multiprocess build support (ryanofsky) +- #19094 Only allow ASCII identifiers (laanwj) +- #18820 Propagate well-known vars into depends (dongcarl) +- #19173 turn on --enable-c++17 by --enable-fuzz (vasild) +- #18297 Use pkg-config in BITCOIN_QT_CONFIGURE for all hosts including Windows (hebasto) +- #19301 don't warn when doxygen isn't found (fanquake) +- #19240 macOS toolchain simplification and bump (dongcarl) +- #19356 Fix search for brew-installed BDB 4 on OS X (gwillen) +- #19394 Remove unused `RES_IMAGES` (Bushstar) +- #19403 improve `__builtin_clz*` detection (fanquake) +- #19375 target Windows 7 when building libevent and fix ipv6 usage (fanquake) +- #19331 Do not include server symbols in wallet (MarcoFalke) +- #19257 remove BIP70 configure option (fanquake) +- #18288 Add MemorySanitizer (MSan) in Travis to detect use of uninitialized memory (practicalswift) +- #18307 Require pkg-config for all of the hosts (hebasto) +- #19445 Update msvc build to use ISO standard C++17 (sipsorcery) +- #18882 fix -Wformat-security check when compiling with GCC (fanquake) +- #17919 Allow building with system clang (dongcarl) +- #19553 pass -fcommon when building genisoimage (fanquake) +- #19565 call `AC_PATH_TOOL` for dsymutil in macOS cross-compile (fanquake) +- #19530 build LTO support into Apple's ld64 (theuni) +- #19525 add -Wl,-z,separate-code to hardening flags (fanquake) +- #19667 set minimum required Boost to 1.58.0 (fanquake) +- #19672 make clean removes .gcda and .gcno files from fuzz directory (Crypt-iQ) +- #19622 Drop ancient hack in gitian-linux descriptor (hebasto) +- #19688 Add support for llvm-cov (hebasto) +- #19718 Add missed gcov files to 'make clean' (hebasto) +- #19719 Add Werror=range-loop-analysis (MarcoFalke) +- #19015 Enable some commonly enabled compiler diagnostics (practicalswift) +- #19689 build, qt: Add Qt version checking (hebasto) +- #17396 modest Android improvements (icota) +- #18405 Drop all of the ZeroMQ patches (hebasto) +- #15704 Move Win32 defines to configure.ac to ensure they are globally defined (luke-jr) +- #19761 improve sed robustness by not using sed (fanquake) +- #19758 Drop deprecated and unused `GUARDED_VAR` and `PT_GUARDED_VAR` annotations (hebasto) +- #18921 add stack-clash and control-flow protection options to hardening flags (fanquake) +- #19803 Bugfix: Define and use `HAVE_FDATASYNC` correctly outside LevelDB (luke-jr) +- #19685 CMake invocation cleanup (dongcarl) +- #19861 add /usr/local/ to `LCOV_FILTER_PATTERN` for macOS builds (Crypt-iQ) +- #19916 allow user to specify `DIR_FUZZ_SEED_CORPUS` for `cov_fuzz` (Crypt-iQ) +- #19944 Update secp256k1 subtree (including BIP340 support) (sipa) +- #19558 Split pthread flags out of ldflags and dont use when building libconsensus (fanquake) +- #19959 patch qt libpng to fix powerpc build (fanquake) +- #19868 Fix target name (hebasto) +- #19960 The vcpkg tool has introduced a proper way to use manifests (sipsorcery) +- #20065 fuzz: Configure check for main function (MarcoFalke) +- #18750 Optionally skip external warnings (vasild) +- #20147 Update libsecp256k1 (endomorphism, test improvements) (sipa) +- #20156 Make sqlite support optional (compile-time) (luke-jr) +- #20318 Ensure source tarball has leading directory name (MarcoFalke) +- #20447 Patch `qt_intersect_spans` to avoid non-deterministic behavior in LLVM 8 (achow101) +- #20505 Avoid secp256k1.h include from system (dergoegge) +- #20527 Do not ignore Homebrew's SQLite on macOS (hebasto) +- #20478 Don't set BDB flags when configuring without (jonasschnelli) +- #20563 Check that Homebrew's berkeley-db4 package is actually installed (hebasto) +- #19493 Fix clang build on Mac (bvbfan) + +### Tests and QA +- #18593 Complete impl. of `msg_merkleblock` and `wait_for_merkleblock` (theStack) +- #18609 Remove REJECT message code (hebasto) +- #18584 Check that the version message does not leak the local address (MarcoFalke) +- #18597 Extend `wallet_dump` test to cover comments (MarcoFalke) +- #18596 Try once more when RPC connection fails on Windows (MarcoFalke) +- #18451 shift coverage from getunconfirmedbalance to getbalances (jonatack) +- #18631 appveyor: Disable functional tests for now (MarcoFalke) +- #18628 Add various low-level p2p tests (MarcoFalke) +- #18615 Avoid accessing free'd memory in `validation_chainstatemanager_tests` (MarcoFalke) +- #18571 fuzz: Disable debug log file (MarcoFalke) +- #18653 add coverage for bitcoin-cli -rpcwait (jonatack) +- #18660 Verify findCommonAncestor always initializes outputs (ryanofsky) +- #17669 Have coins simulation test also use CCoinsViewDB (jamesob) +- #18662 Replace gArgs with local argsman in bench (MarcoFalke) +- #18641 Create cached blocks not in the future (MarcoFalke) +- #18682 fuzz: `http_request` workaround for libevent < 2.1.1 (theStack) +- #18692 Bump timeout in `wallet_import_rescan` (MarcoFalke) +- #18695 Replace boost::mutex with std::mutex (hebasto) +- #18633 Properly raise FailedToStartError when rpc shutdown before warmup finished (MarcoFalke) +- #18675 Don't initialize PrecomputedTransactionData in txvalidationcache tests (jnewbery) +- #18691 Add `wait_for_cookie_credentials()` to framework for rpcwait tests (jonatack) +- #18672 Add further BIP37 size limit checks to `p2p_filter.py` (theStack) +- #18721 Fix linter issue (hebasto) +- #18384 More specific `feature_segwit` test error messages and fixing incorrect comments (gzhao408) +- #18575 bench: Remove requirement that all benches use same testing setup (MarcoFalke) +- #18690 Check object hashes in `wait_for_getdata` (robot-visions) +- #18712 display command line options passed to `send_cli()` in debug log (jonatack) +- #18745 Check submitblock return values (MarcoFalke) +- #18756 Use `wait_for_getdata()` in `p2p_compactblocks.py` (theStack) +- #18724 Add coverage for -rpcwallet cli option (jonatack) +- #18754 bench: Add caddrman benchmarks (vasild) +- #18585 Use zero-argument super() shortcut (Python 3.0+) (theStack) +- #18688 fuzz: Run in parallel (MarcoFalke) +- #18770 Remove raw-tx byte juggling in `mempool_reorg` (MarcoFalke) +- #18805 Add missing `sync_all` to `wallet_importdescriptors.py` (achow101) +- #18759 bench: Start nodes with -nodebuglogfile (MarcoFalke) +- #18774 Added test for upgradewallet RPC (brakmic) +- #18485 Add `mempool_updatefromblock.py` (hebasto) +- #18727 Add CreateWalletFromFile test (ryanofsky) +- #18726 Check misbehavior more independently in `p2p_filter.py` (robot-visions) +- #18825 Fix message for `ECC_InitSanityCheck` test (fanquake) +- #18576 Use unittest for `test_framework` unit testing (gzhao408) +- #18828 Strip down previous releases boilerplate (MarcoFalke) +- #18617 Add factor option to adjust test timeouts (brakmic) +- #18855 `feature_backwards_compatibility.py` test downgrade after upgrade (achow101) +- #18864 Add v0.16.3 backwards compatibility test, bump v0.19.0.1 to v0.19.1 (Sjors) +- #18917 fuzz: Fix vector size problem in system fuzzer (brakmic) +- #18901 fuzz: use std::optional for `sep_pos_opt` variable (brakmic) +- #18888 Remove RPCOverloadWrapper boilerplate (MarcoFalke) +- #18952 Avoid os-dependent path (fametrano) +- #18938 Fill fuzzing coverage gaps for functions in consensus/validation.h, primitives/block.h and util/translation.h (practicalswift) +- #18986 Add capability to disable RPC timeout in functional tests (rajarshimaitra) +- #18530 Add test for -blocksonly and -whitelistforcerelay param interaction (glowang) +- #19014 Replace `TEST_PREVIOUS_RELEASES` env var with `test_framework` option (MarcoFalke) +- #19052 Don't limit fuzzing inputs to 1 MB for afl-fuzz (now: ∞ ∀ fuzzers) (practicalswift) +- #19060 Remove global `wait_until` from `p2p_getdata` (MarcoFalke) +- #18926 Pass ArgsManager into `getarg_tests` (glowang) +- #19110 Explain that a bug should be filed when the tests fail (MarcoFalke) +- #18965 Implement `base58_decode` (10xcryptodev) +- #16564 Always define the `raii_event_tests` test suite (candrews) +- #19122 Add missing `sync_blocks` to `wallet_hd` (MarcoFalke) +- #18875 fuzz: Stop nodes in `process_message*` fuzzers (MarcoFalke) +- #18974 Check that invalid witness destinations can not be imported (MarcoFalke) +- #18210 Type hints in Python tests (kiminuo) +- #19159 Make valgrind.supp work on aarch64 (MarcoFalke) +- #19082 Moved the CScriptNum asserts into the unit test in script.py (gillichu) +- #19172 Do not swallow flake8 exit code (hebasto) +- #19188 Avoid overwriting the NodeContext member of the testing setup [-Wshadow-field] (MarcoFalke) +- #18890 `disconnect_nodes` should warn if nodes were already disconnected (robot-visions) +- #19227 change blacklist to blocklist (TrentZ) +- #19230 Move base58 to own module to break circular dependency (sipa) +- #19083 `msg_mempool`, `fRelay`, and other bloomfilter tests (gzhao408) +- #16756 Connection eviction logic tests (mzumsande) +- #19177 Fix and clean `p2p_invalid_messages` functional tests (troygiorshev) +- #19264 Don't import asyncio to test magic bytes (jnewbery) +- #19178 Make `mininode_lock` non-reentrant (jnewbery) +- #19153 Mempool compatibility test (S3RK) +- #18434 Add a test-security target and run it in CI (fanquake) +- #19252 Wait for disconnect in `disconnect_p2ps` + bloomfilter test followups (gzhao408) +- #19298 Add missing `sync_blocks` (MarcoFalke) +- #19304 Check that message sends successfully when header is split across two buffers (troygiorshev) +- #19208 move `sync_blocks` and `sync_mempool` functions to `test_framework.py` (ycshao) +- #19198 Check that peers with forcerelay permission are not asked to feefilter (MarcoFalke) +- #19351 add two edge case tests for CSubNet (vasild) +- #19272 net, test: invalid p2p messages and test framework improvements (jonatack) +- #19348 Bump linter versions (duncandean) +- #19366 Provide main(…) function in fuzzer. Allow building uninstrumented harnesses with --enable-fuzz (practicalswift) +- #19412 move `TEST_RUNNER_EXTRA` into native tsan setup (fanquake) +- #19368 Improve functional tests compatibility with BSD/macOS (S3RK) +- #19028 Set -logthreadnames in unit tests (MarcoFalke) +- #18649 Add std::locale::global to list of locale dependent functions (practicalswift) +- #19140 Avoid fuzzer-specific nullptr dereference in libevent when handling PROXY requests (practicalswift) +- #19214 Auto-detect SHA256 implementation in benchmarks (sipa) +- #19353 Fix mistakenly swapped "previous" and "current" lock orders (hebasto) +- #19533 Remove unnecessary `cs_mains` in `denialofservice_tests` (jnewbery) +- #19423 add functional test for txrelay during and after IBD (gzhao408) +- #16878 Fix non-deterministic coverage of test `DoS_mapOrphans` (davereikher) +- #19548 fuzz: add missing overrides to `signature_checker` (jonatack) +- #19562 Fix fuzzer compilation on macOS (freenancial) +- #19370 Static asserts for consistency of fee defaults (domob1812) +- #19599 clean `message_count` and `last_message` (troygiorshev) +- #19597 test decodepsbt fee calculation (count input value only once per UTXO) (theStack) +- #18011 Replace current benchmarking framework with nanobench (martinus) +- #19489 Fail `wait_until` early if connection is lost (MarcoFalke) +- #19340 Preserve the `LockData` initial state if "potential deadlock detected" exception thrown (hebasto) +- #19632 Catch decimal.InvalidOperation from `TestNodeCLI#send_cli` (Empact) +- #19098 Remove duplicate NodeContext hacks (ryanofsky) +- #19649 Restore test case for p2p transaction blinding (instagibbs) +- #19657 Wait until `is_connected` in `add_p2p_connection` (MarcoFalke) +- #19631 Wait for 'cmpctblock' in `p2p_compactblocks` when it is expected (Empact) +- #19674 use throwaway _ variable for unused loop counters (theStack) +- #19709 Fix 'make cov' with clang (hebasto) +- #19564 `p2p_feefilter` improvements (logging, refactoring, speedup) (theStack) +- #19756 add `sync_all` to fix race condition in wallet groups test (kallewoof) +- #19727 Removing unused classes from `p2p_leak.py` (dhruv) +- #19722 Add test for getblockheader verboseness (torhte) +- #19659 Add a seed corpus generation option to the fuzzing `test_runner` (darosior) +- #19775 Activate segwit in TestChain100Setup (MarcoFalke) +- #19760 Remove confusing mininode terminology (jnewbery) +- #19752 Update `wait_until` usage in tests not to use the one from utils (slmtpz) +- #19839 Set appveyor VM version to previous Visual Studio 2019 release (sipsorcery) +- #19830 Add tsan supp for leveldb::DBImpl::DeleteObsoleteFiles (MarcoFalke) +- #19710 bench: Prevent thread oversubscription and decreases the variance of result values (hebasto) +- #19842 Update the vcpkg checkout commit ID in appveyor config (sipsorcery) +- #19507 Expand functional zmq transaction tests (instagibbs) +- #19816 Rename wait until helper to `wait_until_helper` (MarcoFalke) +- #19859 Fixes failing functional test by changing version (n-thumann) +- #19887 Fix flaky `wallet_basic` test (fjahr) +- #19897 Change `FILE_CHAR_BLOCKLIST` to `FILE_CHARS_DISALLOWED` (verretor) +- #19800 Mockwallet (MarcoFalke) +- #19922 Run `rpc_txoutproof.py` even with wallet disabled (MarcoFalke) +- #19936 batch rpc with params (instagibbs) +- #19971 create default wallet in extended tests (Sjors) +- #19781 add parameterized constructor for `msg_sendcmpct()` (theStack) +- #19963 Clarify blocksonly whitelistforcerelay test (t-bast) +- #20022 Use explicit p2p objects where available (guggero) +- #20028 Check that invalid peer traffic is accounted for (MarcoFalke) +- #20004 Add signet witness commitment section parse tests (MarcoFalke) +- #20034 Get rid of default wallet hacks (ryanofsky) +- #20069 Mention commit id in scripted diff error (laanwj) +- #19947 Cover `change_type` option of "walletcreatefundedpsbt" RPC (guggero) +- #20126 `p2p_leak_tx.py` improvements (use MiniWallet, add `p2p_lock` acquires) (theStack) +- #20129 Don't export `in6addr_loopback` (vasild) +- #20131 Remove unused nVersion=1 in p2p tests (MarcoFalke) +- #20161 Minor Taproot follow-ups (sipa) +- #19401 Use GBT to get block versions correct (luke-jr) +- #20159 `mining_getblocktemplate_longpoll.py` improvements (use MiniWallet, add logging) (theStack) +- #20039 Convert amounts from float to decimal (prayank23) +- #20112 Speed up `wallet_resendwallettransactions` with mockscheduler RPC (MarcoFalke) +- #20247 fuzz: Check for addrv1 compatibility before using addrv1 serializer. Fuzz addrv2 serialization (practicalswift) +- #20167 Add test for -blockversion (MarcoFalke) +- #19877 Clarify `rpc_net` & `p2p_disconnect_ban functional` tests (amitiuttarwar) +- #20258 Remove getnettotals/getpeerinfo consistency test (jnewbery) +- #20242 fuzz: Properly initialize PrecomputedTransactionData (MarcoFalke) +- #20262 Skip --descriptor tests if sqlite is not compiled (achow101) +- #18788 Update more tests to work with descriptor wallets (achow101) +- #20289 fuzz: Check for addrv1 compatibility before using addrv1 serializer/deserializer on CService (practicalswift) +- #20290 fuzz: Fix DecodeHexTx fuzzing harness issue (practicalswift) +- #20245 Run `script_assets_test` even if built --with-libs=no (MarcoFalke) +- #20300 fuzz: Add missing `ECC_Start` to `descriptor_parse` test (S3RK) +- #20283 Only try witness deser when checking for witness deser failure (MarcoFalke) +- #20303 fuzz: Assert expected DecodeHexTx behaviour when using legacy decoding (practicalswift) +- #20316 Fix `wallet_multiwallet` test issue on Windows (MarcoFalke) +- #20326 Fix `ecdsa_verify` in test framework (stepansnigirev) +- #20328 cirrus: Skip tasks on the gui repo main branch (MarcoFalke) +- #20355 fuzz: Check for addrv1 compatibility before using addrv1 serializer/deserializer on CSubNet (practicalswift) +- #20332 Mock IBD in `net_processing` fuzzers (MarcoFalke) +- #20218 Suppress `epoll_ctl` data race (MarcoFalke) +- #20375 fuzz: Improve coverage for CPartialMerkleTree fuzzing harness (practicalswift) +- #19669 contrib: Fixup valgrind suppressions file (MarcoFalke) +- #18879 valgrind: remove outdated suppressions (fanquake) +- #19226 Add BerkeleyDatabase tsan suppression (MarcoFalke) +- #20379 Remove no longer needed UBSan suppression (float divide-by-zero in validation.cpp) (practicalswift) +- #18190, #18736, #18744, #18775, #18783, #18867, #18994, #19065, + #19067, #19143, #19222, #19247, #19286, #19296, #19379, #19934, + #20188, #20395 Add fuzzing harnessses (practicalswift) +- #18638 Use mockable time for ping/pong, add tests (MarcoFalke) +- #19951 CNetAddr scoped ipv6 test coverage, rename scopeId to `m_scope_id` (jonatack) +- #20027 Use mockable time everywhere in `net_processing` (sipa) +- #19105 Add Muhash3072 implementation in Python (fjahr) +- #18704, #18752, #18753, #18765, #18839, #18866, #18873, #19022, + #19023, #19429, #19552, #19778, #20176, #20179, #20214, #20292, + #20299, #20322 Fix intermittent test issues (MarcoFalke) +- #20390 CI/Cirrus: Skip `merge_base` step for non-PRs (luke-jr) +- #18634 ci: Add fuzzbuzz integration configuration file (practicalswift) +- #18591 Add C++17 build to Travis (sipa) +- #18581, #18667, #18798, #19495, #19519, #19538 CI improvements (hebasto) +- #18683, #18705, #18735, #18778, #18799, #18829, #18912, #18929, + #19008, #19041, #19164, #19201, #19267, #19276, #19321, #19371, + #19427, #19730, #19746, #19881, #20294, #20339, #20368 CI improvements (MarcoFalke) +- #20489, #20506 MSVC CI improvements (sipsorcery) + +### Miscellaneous +- #18713 scripts: Add macho stack canary check to security-check.py (fanquake) +- #18629 scripts: Add pe .reloc section check to security-check.py (fanquake) +- #18437 util: `Detect posix_fallocate()` instead of assuming (vasild) +- #18413 script: Prevent ub when computing abs value for num opcode serialize (pierreN) +- #18443 lockedpool: avoid sensitive data in core files (FreeBSD) (vasild) +- #18885 contrib: Move optimize-pngs.py script to the maintainer repo (MarcoFalke) +- #18317 Serialization improvements step 6 (all except wallet/gui) (sipa) +- #16127 More thread safety annotation coverage (ajtowns) +- #19228 Update libsecp256k1 subtree (sipa) +- #19277 util: Add assert identity function (MarcoFalke) +- #19491 util: Make assert work with any value (MarcoFalke) +- #19205 script: `previous_release.sh` rewritten in python (bliotti) +- #15935 Add /settings.json persistent settings storage (ryanofsky) +- #19439 script: Linter to check commit message formatting (Ghorbanian) +- #19654 lint: Improve commit message linter in travis (fjahr) +- #15382 util: Add runcommandparsejson (Sjors) +- #19614 util: Use `have_fdatasync` to determine fdatasync() use (fanquake) +- #19813 util, ci: Hard code previous release tarball checksums (hebasto) +- #19841 Implement Keccak and `SHA3_256` (sipa) +- #19643 Add -netinfo peer connections dashboard (jonatack) +- #15367 feature: Added ability for users to add a startup command (benthecarman) +- #19984 log: Remove static log message "Initializing chainstate Chainstate [ibd] @ height -1 (null)" (practicalswift) +- #20092 util: Do not use gargs global in argsmanager member functions (hebasto) +- #20168 contrib: Fix `gen_key_io_test_vectors.py` imports (MarcoFalke) +- #19624 Warn on unknown `rw_settings` (MarcoFalke) +- #20257 Update secp256k1 subtree to latest master (sipa) +- #20346 script: Modify security-check.py to use "==" instead of "is" for literal comparison (tylerchambers) +- #18881 Prevent UB in DeleteLock() function (hebasto) +- #19180, #19189, #19190, #19220, #19399 Replace RecursiveMutex with Mutex (hebasto) +- #19347 Make `cs_inventory` nonrecursive (jnewbery) +- #19773 Avoid recursive lock in IsTrusted (promag) +- #18790 Improve thread naming (hebasto) +- #20140 Restore compatibility with old CSubNet serialization (sipa) +- #17775 DecodeHexTx: Try case where txn has inputs first (instagibbs) + +### Documentation +- #18502 Update docs for getbalance (default minconf should be 0) (uzyn) +- #18632 Fix macos comments in release-notes (MarcoFalke) +- #18645 Update thread information in developer docs (jnewbery) +- #18709 Note why we can't use `thread_local` with glibc back compat (fanquake) +- #18410 Improve commenting for coins.cpp|h (jnewbery) +- #18157 fixing init.md documentation to not require rpcpassword (jkcd) +- #18739 Document how to fuzz Bitcoin Core using Honggfuzz (practicalswift) +- #18779 Better explain GNU ld's dislike of ld64's options (fanquake) +- #18663 Mention build docs in README.md (saahilshangle) +- #18810 Update rest info on block size and json (chrisabrams) +- #18939 Add c++17-enable flag to fuzzing instructions (mzumsande) +- #18957 Add a link from ZMQ doc to ZMQ example in contrib/ (meeDamian) +- #19058 Drop protobuf stuff (hebasto) +- #19061 Add link to Visual Studio build readme (maitrebitcoin) +- #19072 Expand section on Getting Started (MarcoFalke) +- #18968 noban precludes maxuploadtarget disconnects (MarcoFalke) +- #19005 Add documentation for 'checklevel' argument in 'verifychain' RPC… (kcalvinalvin) +- #19192 Extract net permissions doc (MarcoFalke) +- #19071 Separate repository for the gui (MarcoFalke) +- #19018 fixing description of the field sequence in walletcreatefundedpsbt RPC method (limpbrains) +- #19367 Span pitfalls (sipa) +- #19408 Windows WSL build recommendation to temporarily disable Win32 PE support (sipsorcery) +- #19407 explain why passing -mlinker-version is required when cross-compiling (fanquake) +- #19452 afl fuzzing comment about afl-gcc and afl-g++ (Crypt-iQ) +- #19258 improve subtree check instructions (Sjors) +- #19474 Use precise permission flags where possible (MarcoFalke) +- #19494 CONTRIBUTING.md improvements (jonatack) +- #19268 Add non-thread-safe note to FeeFilterRounder::round() (hebasto) +- #19547 Update macOS cross compilation dependencies for Focal (hebasto) +- #19617 Clang 8 or later is required with `FORCE_USE_SYSTEM_CLANG` (fanquake) +- #19639 Remove Reference Links #19582 (RobertHosking) +- #19605 Set `CC_FOR_BUILD` when building on OpenBSD (fanquake) +- #19765 Fix getmempoolancestors RPC result doc (MarcoFalke) +- #19786 Remove label from good first issue template (MarcoFalke) +- #19646 Updated outdated help command for getblocktemplate (jakeleventhal) +- #18817 Document differences in bitcoind and bitcoin-qt locale handling (practicalswift) +- #19870 update PyZMQ install instructions, fix `zmq_sub.py` file permissions (jonatack) +- #19903 Update build-openbsd.md with GUI support (grubles) +- #19241 help: Generate checkpoint height from chainparams (luke-jr) +- #18949 Add CODEOWNERS file to automatically nominate PR reviewers (adamjonas) +- #20014 Mention signet in -help output (hebasto) +- #20015 Added default signet config for linearize script (gr0kchain) +- #19958 Better document features of feelers (naumenkogs) +- #19871 Clarify scope of eviction protection of outbound block-relay peers (ariard) +- #20076 Update and improve files.md (hebasto) +- #20107 Collect release-notes snippets (MarcoFalke) +- #20109 Release notes and followups from 19339 (glozow) +- #20090 Tiny followups to new getpeerinfo connection type field (amitiuttarwar) +- #20152 Update wallet files in files.md (hebasto) +- #19124 Document `ALLOW_HOST_PACKAGES` dependency option (skmcontrib) +- #20271 Document that wallet salvage is experimental (MarcoFalke) +- #20281 Correct getblockstats documentation for `(sw)total_weight` (shesek) +- #20279 release process updates/fixups (jonatack) +- #20238 Missing comments for signet parameters (decryp2kanon) +- #20756 Add missing field (permissions) to the getpeerinfo help (amitiuttarwar) +- #20668 warn that incoming conns are unlikely when not using default ports (adamjonas) +- #19961 tor.md updates (jonatack) +- #19050 Add warning for rest interface limitation (fjahr) +- #19390 doc/REST-interface: Remove stale info (luke-jr) +- #19344 docs: update testgen usage example (Bushstar) + Credits ======= Thanks to everyone who directly contributed to this release: +- 10xcryptodev +- Aaron Clauson +- Aaron Hook +- Adam Jonas +- Adam Soltys +- Adam Stein +- Akio Nakamura +- Alex Willmer +- Amir Ghorbanian +- Amiti Uttarwar +- Andrew Chow +- Andrew Toth +- Anthony Fieroni +- Anthony Towns +- Antoine Poinsot +- Antoine Riard +- Ben Carman +- Ben Woosley +- Benoit Verret +- Brian Liotti +- Bushstar +- Calvin Kim +- Carl Dong +- Chris Abrams +- Chris L +- Christopher Coverdale +- codeShark149 +- Cory Fields +- Craig Andrews +- Damian Mee +- Daniel Kraft +- Danny Lee +- David Reikher +- DesWurstes +- Dhruv Mehta +- Duncan Dean +- Elichai Turkel +- Elliott Jin +- Emil Engler +- Ethan Heilman +- eugene +- Fabian Jahr +- fanquake +- Ferdinando M. Ametrano +- freenancial +- furszy +- Gillian Chu +- Gleb Naumenko +- Glenn Willen +- Gloria Zhao +- glowang +- gr0kchain +- Gregory Sanders +- grubles +- gzhao408 +- Harris +- Hennadii Stepanov +- Hugo Nguyen +- Igor Cota +- Ivan Metlushko +- Ivan Vershigora +- Jake Leventhal +- James O'Beirne +- Jeremy Rubin +- jgmorgan +- Jim Posen +- “jkcd” +- jmorgan +- John Newbery +- Johnson Lau +- Jon Atack +- Jonas Schnelli +- Jonathan Schoeller +- João Barbosa +- Justin Moon +- kanon +- Karl-Johan Alm +- Kiminuo +- Kristaps Kaupe +- lontivero +- Luke Dashjr +- Marcin Jachymiak +- MarcoFalke +- Martin Ankerl +- Martin Zumsande +- maskoficarus +- Matt Corallo +- Matthew Zipkin +- MeshCollider +- Miguel Herranz +- MIZUTA Takeshi +- mruddy +- Nadav Ivgi +- Neha Narula +- Nicolas Thumann +- Niklas Gögge +- Nima Yazdanmehr +- nsa +- nthumann +- Oliver Gugger +- pad +- pasta +- Peter Bushnell +- pierrenn +- Pieter Wuille +- practicalswift +- Prayank +- Raúl Martínez (RME) +- RandyMcMillan +- Rene Pickhardt +- Riccardo Masutti +- Robert +- Rod Vagg +- Roy Shao +- Russell Yanofsky +- Saahil Shangle +- sachinkm77 +- saibato +- Samuel Dobson +- sanket1729 +- Sebastian Falbesoner +- Seleme Topuz +- Sishir Giri +- Sjors Provoost +- skmcontrib +- Stepan Snigirev +- Stephan Oeste +- Suhas Daftuar +- t-bast +- Tom Harding +- Torhte Butler +- TrentZ +- Troy Giorshev +- tryphe +- Tyler Chambers +- U-Zyn Chua +- Vasil Dimov +- wiz +- Wladimir J. van der Laan As well as to everyone that helped with translations on [Transifex](https://www.transifex.com/bitcoin/bitcoin/). From 010ba4e6e6028971febf5a682dfc8e7b17fa0b79 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Thu, 14 Jan 2021 10:51:15 +0100 Subject: [PATCH 41/84] doc: Archive release notes, Add template for minor release (cherry picked from commit b6d35029932ef245e040723dc924be2db4928666) --- doc/release-notes.md | 1284 +------------------- doc/release-notes/release-notes-0.21.0.md | 1336 +++++++++++++++++++++ 2 files changed, 1341 insertions(+), 1279 deletions(-) create mode 100644 doc/release-notes/release-notes-0.21.0.md diff --git a/doc/release-notes.md b/doc/release-notes.md index af5cc46881..9abf25eda8 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,11 +1,11 @@ -0.21.0 Release Notes +0.21.1 Release Notes ==================== -Bitcoin Core version 0.21.0 is now available from: +Bitcoin Core version 0.21.1 is now available from: - + -This release includes new features, various bug fixes and performance +This minor release includes various bug fixes and performance improvements, as well as updated translations. Please report bugs using the issue tracker at GitHub: @@ -41,1296 +41,22 @@ From Bitcoin Core 0.22.0 onwards, macOS versions earlier than 10.14 are no longer supported. Additionally, Bitcoin Core does not yet change appearance when macOS "dark mode" is activated. -The node's known peers are persisted to disk in a file called `peers.dat`. The -format of this file has been changed in a backwards-incompatible way in order to -accommodate the storage of Tor v3 and other BIP155 addresses. This means that if -the file is modified by 0.21.0 or newer then older versions will not be able to -read it. Those old versions, in the event of a downgrade, will log an error -message "Incorrect keysize in addrman deserialization" and will continue normal -operation as if the file was missing, creating a new empty one. (#19954, #20284) - Notable changes =============== -P2P and network changes ------------------------ - -- The mempool now tracks whether transactions submitted via the wallet or RPCs - have been successfully broadcast. Every 10-15 minutes, the node will try to - announce unbroadcast transactions until a peer requests it via a `getdata` - message or the transaction is removed from the mempool for other reasons. - The node will not track the broadcast status of transactions submitted to the - node using P2P relay. This version reduces the initial broadcast guarantees - for wallet transactions submitted via P2P to a node running the wallet. (#18038) - -- The size of the set of transactions that peers have announced and we consider - for requests has been reduced from 100000 to 5000 (per peer), and further - announcements will be ignored when that limit is reached. If you need to dump - (very) large batches of transactions, exceptions can be made for trusted - peers using the "relay" network permission. For localhost for example it can - be enabled using the command line option `-whitelist=relay@127.0.0.1`. - (#19988) - -- This release adds support for Tor version 3 hidden services, and rumoring them - over the network to other peers using - [BIP155](https://github.com/bitcoin/bips/blob/master/bip-0155.mediawiki). - Version 2 hidden services are still fully supported by Bitcoin Core, but the - Tor network will start - [deprecating](https://blog.torproject.org/v2-deprecation-timeline) them in the - coming months. (#19954) - -- The Tor onion service that is automatically created by setting the - `-listenonion` configuration parameter will now be created as a Tor v3 service - instead of Tor v2. The private key that was used for Tor v2 (if any) will be - left untouched in the `onion_private_key` file in the data directory (see - `-datadir`) and can be removed if not needed. Bitcoin Core will no longer - attempt to read it. The private key for the Tor v3 service will be saved in a - file named `onion_v3_private_key`. To use the deprecated Tor v2 service (not - recommended), the `onion_private_key` can be copied over - `onion_v3_private_key`, e.g. - `cp -f onion_private_key onion_v3_private_key`. (#19954) - -- The client writes a file (`anchors.dat`) at shutdown with the network addresses - of the node’s two outbound block-relay-only peers (so called "anchors"). The - next time the node starts, it reads this file and attempts to reconnect to those - same two peers. This prevents an attacker from using node restarts to trigger a - complete change in peers, which would be something they could use as part of an - eclipse attack. (#17428) - -- This release adds support for serving - [BIP157](https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki) compact - filters to peers on the network when enabled using - `-blockfilterindex=1 -peercfilters=1`. (#16442) - -- This release adds support for signets - ([BIP325](https://github.com/bitcoin/bips/blob/master/bip-0325.mediawiki)) in - addition to the existing mainnet, testnet, and regtest networks. Signets are - centrally-controlled test networks, allowing them to be more predictable - test environments than the older testnet. One public signet is maintained, and - selectable using `-signet`. It is also possible to create personal signets. - (#18267). - -- This release implements - [BIP339](https://github.com/bitcoin/bips/blob/master/bip-0339.mediawiki) - wtxid relay. When negotiated, transactions are announced using their wtxid - instead of their txid. (#18044). - -- This release implements the proposed Taproot consensus rules - ([BIP341](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki) and - [BIP342](https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki)), - without activation on mainnet. Experimentation with Taproot can be done on - signet, where its rules are already active. (#19553) - -Updated RPCs ------------- - -- The `getpeerinfo` RPC has a new `network` field that provides the type of - network ("ipv4", "ipv6", or "onion") that the peer connected through. (#20002) - -- The `getpeerinfo` RPC now has additional `last_block` and `last_transaction` - fields that return the UNIX epoch time of the last block and the last *valid* - transaction received from each peer. (#19731) - -- `getnetworkinfo` now returns two new fields, `connections_in` and - `connections_out`, that provide the number of inbound and outbound peer - connections. These new fields are in addition to the existing `connections` - field, which returns the total number of peer connections. (#19405) - -- Exposed transaction version numbers are now treated as unsigned 32-bit - integers instead of signed 32-bit integers. This matches their treatment in - consensus logic. Versions greater than 2 continue to be non-standard - (matching previous behavior of smaller than 1 or greater than 2 being - non-standard). Note that this includes the `joinpsbt` command, which combines - partially-signed transactions by selecting the highest version number. - (#16525) - -- `getmempoolinfo` now returns an additional `unbroadcastcount` field. The - mempool tracks locally submitted transactions until their initial broadcast - is acknowledged by a peer. This field returns the count of transactions - waiting for acknowledgement. - -- Mempool RPCs such as `getmempoolentry` and `getrawmempool` with - `verbose=true` now return an additional `unbroadcast` field. This indicates - whether initial broadcast of the transaction has been acknowledged by a - peer. `getmempoolancestors` and `getmempooldescendants` are also updated. - -- The `getpeerinfo` RPC no longer returns the `banscore` field unless the configuration - option `-deprecatedrpc=banscore` is used. The `banscore` field will be fully - removed in the next major release. (#19469) - -- The `testmempoolaccept` RPC returns `vsize` and a `fees` object with the `base` fee - if the transaction would pass validation. (#19940) - -- The `getpeerinfo` RPC now returns a `connection_type` field. This indicates - the type of connection established with the peer. It will return one of six - options. For more information, see the `getpeerinfo` help documentation. - (#19725) - -- The `getpeerinfo` RPC no longer returns the `addnode` field by default. This - field will be fully removed in the next major release. It can be accessed - with the configuration option `-deprecatedrpc=getpeerinfo_addnode`. However, - it is recommended to instead use the `connection_type` field (it will return - `manual` when addnode is true). (#19725) - -- The `getpeerinfo` RPC no longer returns the `whitelisted` field by default. - This field will be fully removed in the next major release. It can be accessed - with the configuration option `-deprecatedrpc=getpeerinfo_whitelisted`. However, - it is recommended to instead use the `permissions` field to understand if specific - privileges have been granted to the peer. (#19770) - -- The `walletcreatefundedpsbt` RPC call will now fail with - `Insufficient funds` when inputs are manually selected but are not enough to cover - the outputs and fee. Additional inputs can automatically be added through the - new `add_inputs` option. (#16377) - -- The `fundrawtransaction` RPC now supports `add_inputs` option that when `false` - prevents adding more inputs if necessary and consequently the RPC fails. - -Changes to Wallet or GUI related RPCs can be found in the GUI or Wallet section below. - -New RPCs --------- - -- The `getindexinfo` RPC returns the actively running indices of the node, - including their current sync status and height. It also accepts an `index_name` - to specify returning the status of that index only. (#19550) - -Build System ------------- - -Updated settings ----------------- - -- The same ZeroMQ notification (e.g. `-zmqpubhashtx=address`) can now be - specified multiple times to publish the same notification to different ZeroMQ - sockets. (#18309) - -- The `-banscore` configuration option, which modified the default threshold for - disconnecting and discouraging misbehaving peers, has been removed as part of - changes in 0.20.1 and in this release to the handling of misbehaving peers. - Refer to "Changes regarding misbehaving peers" in the 0.20.1 release notes for - details. (#19464) - -- The `-debug=db` logging category, which was deprecated in 0.20 and replaced by - `-debug=walletdb` to distinguish it from `coindb`, has been removed. (#19202) - -- A `download` permission has been extracted from the `noban` permission. For - compatibility, `noban` implies the `download` permission, but this may change - in future releases. Refer to the help of the affected settings `-whitebind` - and `-whitelist` for more details. (#19191) - -- Netmasks that contain 1-bits after 0-bits (the 1-bits are not contiguous on - the left side, e.g. 255.0.255.255) are no longer accepted. They are invalid - according to RFC 4632. Netmasks are used in the `-rpcallowip` and `-whitelist` - configuration options and in the `setban` RPC. (#19628) - -- The `-blocksonly` setting now completely disables fee estimation. (#18766) - -Changes to Wallet or GUI related settings can be found in the GUI or Wallet section below. - -Tools and Utilities -------------------- - -- A new `bitcoin-cli -netinfo` command provides a network peer connections - dashboard that displays data from the `getpeerinfo` and `getnetworkinfo` RPCs - in a human-readable format. An optional integer argument from `0` to `4` may - be passed to see increasing levels of detail. (#19643) - -- A new `bitcoin-cli -generate` command, equivalent to RPC `generatenewaddress` - followed by `generatetoaddress`, can generate blocks for command line testing - purposes. This is a client-side version of the former `generate` RPC. See the - help for details. (#19133) - -- The `bitcoin-cli -getinfo` command now displays the wallet name and balance for - each of the loaded wallets when more than one is loaded (e.g. in multiwallet - mode) and a wallet is not specified with `-rpcwallet`. (#18594) - -- The `connections` field of `bitcoin-cli -getinfo` is now expanded to return a JSON - object with `in`, `out` and `total` numbers of peer connections. It previously - returned a single integer value for the total number of peer connections. (#19405) - -New settings ------------- - -- The `startupnotify` option is used to specify a command to - execute when Bitcoin Core has finished with its startup - sequence. (#15367) - -Wallet ------- - -- Backwards compatibility has been dropped for two `getaddressinfo` RPC - deprecations, as notified in the 0.20 release notes. The deprecated `label` - field has been removed as well as the deprecated `labels` behavior of - returning a JSON object containing `name` and `purpose` key-value pairs. Since - 0.20, the `labels` field returns a JSON array of label names. (#19200) - -- To improve wallet privacy, the frequency of wallet rebroadcast attempts is - reduced from approximately once every 15 minutes to once every 12-36 hours. - To maintain a similar level of guarantee for initial broadcast of wallet - transactions, the mempool tracks these transactions as a part of the newly - introduced unbroadcast set. See the "P2P and network changes" section for - more information on the unbroadcast set. (#18038) - -- The `sendtoaddress` and `sendmany` RPCs accept an optional `verbose=True` - argument to also return the fee reason about the sent tx. (#19501) - -- The wallet can create a transaction without change even when the keypool is - empty. Previously it failed. (#17219) - -- The `-salvagewallet` startup option has been removed. A new `salvage` command - has been added to the `bitcoin-wallet` tool which performs the salvage - operations that `-salvagewallet` did. (#18918) - -- A new configuration flag `-maxapsfee` has been added, which sets the max - allowed avoid partial spends (APS) fee. It defaults to 0 (i.e. fee is the - same with and without APS). Setting it to -1 will disable APS, unless - `-avoidpartialspends` is set. (#14582) - -- The wallet will now avoid partial spends (APS) by default, if this does not - result in a difference in fees compared to the non-APS variant. The allowed - fee threshold can be adjusted using the new `-maxapsfee` configuration - option. (#14582) - -- The `createwallet`, `loadwallet`, and `unloadwallet` RPCs now accept - `load_on_startup` options to modify the settings list. Unless these options - are explicitly set to true or false, the list is not modified, so the RPC - methods remain backwards compatible. (#15937) - -- A new `send` RPC with similar syntax to `walletcreatefundedpsbt`, including - support for coin selection and a custom fee rate, is added. The `send` RPC is - experimental and may change in subsequent releases. (#16378) - -- The `estimate_mode` parameter is now case-insensitive in the `bumpfee`, - `fundrawtransaction`, `sendmany`, `sendtoaddress`, `send` and - `walletcreatefundedpsbt` RPCs. (#11413) - -- The `bumpfee` RPC now uses `conf_target` rather than `confTarget` in the - options. (#11413) - -- `fundrawtransaction` and `walletcreatefundedpsbt` when used with the - `lockUnspents` argument now lock manually selected coins, in addition to - automatically selected coins. Note that locked coins are never used in - automatic coin selection, but can still be manually selected. (#18244) - -- The `-zapwallettxes` startup option has been removed and its functionality - removed from the wallet. This option was originally intended to allow for - rescuing wallets which were affected by a malleability attack. More recently, - it has been used in the fee bumping of transactions that did not signal RBF. - This functionality has been superseded with the abandon transaction feature. (#19671) - -- The error code when no wallet is loaded, but a wallet RPC is called, has been - changed from `-32601` (method not found) to `-18` (wallet not found). - (#20101) - -### Automatic wallet creation removed - -Bitcoin Core will no longer automatically create new wallets on startup. It will -load existing wallets specified by `-wallet` options on the command line or in -`bitcoin.conf` or `settings.json` files. And by default it will also load a -top-level unnamed ("") wallet. However, if specified wallets don't exist, -Bitcoin Core will now just log warnings instead of creating new wallets with -new keys and addresses like previous releases did. - -New wallets can be created through the GUI (which has a more prominent create -wallet option), through the `bitcoin-cli createwallet` or `bitcoin-wallet -create` commands, or the `createwallet` RPC. (#15454, #20186) - -### Experimental Descriptor Wallets - -Please note that Descriptor Wallets are still experimental and not all expected functionality -is available. Additionally there may be some bugs and current functions may change in the future. -Bugs and missing functionality can be reported to the [issue tracker](https://github.com/bitcoin/bitcoin/issues). - -0.21 introduces a new type of wallet - Descriptor Wallets. Descriptor Wallets store -scriptPubKey information using output descriptors. This is in contrast to the Legacy Wallet -structure where keys are used to implicitly generate scriptPubKeys and addresses. Because of this -shift to being script based instead of key based, many of the confusing things that Legacy -Wallets do are not possible with Descriptor Wallets. Descriptor Wallets use a definition -of "mine" for scripts which is simpler and more intuitive than that used by Legacy Wallets. -Descriptor Wallets also uses different semantics for watch-only things and imports. - -As Descriptor Wallets are a new type of wallet, their introduction does not affect existing wallets. -Users who already have a Bitcoin Core wallet can continue to use it as they did before without -any change in behavior. Newly created Legacy Wallets (which remains the default type of wallet) will -behave as they did in previous versions of Bitcoin Core. - -The differences between Descriptor Wallets and Legacy Wallets are largely limited to non user facing -things. They are intended to behave similarly except for the import/export and watchonly functionality -as described below. - -#### Creating Descriptor Wallets - -Descriptor wallets are not the default type of wallet. - -In the GUI, a checkbox has been added to the Create Wallet Dialog to indicate that a -Descriptor Wallet should be created. And a `descriptors` option has been added to `createwallet` RPC. -Setting `descriptors` to `true` will create a Descriptor Wallet instead of a Legacy Wallet. - -Without those options being set, a Legacy Wallet will be created instead. - -#### `IsMine` Semantics - -`IsMine` refers to the function used to determine whether a script belongs to the wallet. -This is used to determine whether an output belongs to the wallet. `IsMine` in Legacy Wallets -returns true if the wallet would be able to sign an input that spends an output with that script. -Since keys can be involved in a variety of different scripts, this definition for `IsMine` can -lead to many unexpected scripts being considered part of the wallet. - -With Descriptor Wallets, descriptors explicitly specify the set of scripts that are owned by -the wallet. Since descriptors are deterministic and easily enumerable, users will know exactly -what scripts the wallet will consider to belong to it. Additionally the implementation of `IsMine` -in Descriptor Wallets is far simpler than for Legacy Wallets. Notably, in Legacy Wallets, `IsMine` -allowed for users to take one type of address (e.g. P2PKH), mutate it into another address type -(e.g. P2WPKH), and the wallet would still detect outputs sending to the new address type -even without that address being requested from the wallet. Descriptor Wallets do not -allow for this and will only watch for the addresses that were explicitly requested from the wallet. - -These changes to `IsMine` will make it easier to reason about what scripts the wallet will -actually be watching for in outputs. However for the vast majority of users, this change is -largely transparent and will not have noticeable effect. - -#### Imports and Exports - -In Legacy Wallets, raw scripts and keys could be imported to the wallet. Those imported scripts -and keys are treated separately from the keys generated by the wallet. This complicates the `IsMine` -logic as it has to distinguish between spendable and watchonly. - -Descriptor Wallets handle importing scripts and keys differently. Only complete descriptors can be -imported. These descriptors are then added to the wallet as if it were a descriptor generated by -the wallet itself. This simplifies the `IsMine` logic so that it no longer has to distinguish -between spendable and watchonly. As such, the watchonly model for Descriptor Wallets is also -different and described in more detail in the next section. - -To import into a Descriptor Wallet, a new `importdescriptors` RPC has been added that uses a syntax -similar to that of `importmulti`. - -As Legacy Wallets and Descriptor Wallets use different mechanisms for storing and importing scripts and keys -the existing import RPCs have been disabled for descriptor wallets. -New export RPCs for Descriptor Wallets have not yet been added. - -The following RPCs are disabled for Descriptor Wallets: - -* `importprivkey` -* `importpubkey` -* `importaddress` -* `importwallet` -* `dumpprivkey` -* `dumpwallet` -* `importmulti` -* `addmultisigaddress` -* `sethdseed` - -#### Watchonly Wallets - -A Legacy Wallet contains both private keys and scripts that were being watched. -Those watched scripts would not contribute to your normal balance. In order to see the watchonly -balance and to use watchonly things in transactions, an `include_watchonly` option was added -to many RPCs that would allow users to do that. However it is easy to forget to include this option. - -Descriptor Wallets move to a per-wallet watchonly model. Instead an entire wallet is considered to be -watchonly depending on whether it was created with private keys disabled. This eliminates the need -to distinguish between things that are watchonly and things that are not within a wallet itself. - -This change does have a caveat. If a Descriptor Wallet with private keys *enabled* has -a multiple key descriptor without all of the private keys (e.g. `multi(...)` with only one private key), -then the wallet will fail to sign and broadcast transactions. Such wallets would need to use the PSBT -workflow but the typical GUI Send, `sendtoaddress`, etc. workflows would still be available, just -non-functional. - -This issue is worsened if the wallet contains both single key (e.g. `wpkh(...)`) descriptors and such -multiple key descriptors as some transactions could be signed and broadcast and others not. This is -due to some transactions containing only single key inputs, while others would contain both single -key and multiple key inputs, depending on which are available and how the coin selection algorithm -selects inputs. However this is not considered to be a supported use case; multisigs -should be in their own wallets which do not already have descriptors. Although users cannot export -descriptors with private keys for now as explained earlier. - -#### BIP 44/49/84 Support - -The change to using descriptors changes the default derivation paths used by Bitcoin Core -to adhere to BIP 44/49/84. Descriptors with different derivation paths can be imported without -issue. - -#### SQLite Database Backend - -Descriptor wallets use SQLite for the wallet file instead of the Berkeley DB used in legacy wallets. -This will break compatibility with any existing tooling that operates on wallets, however compatibility -was already being broken by the move to descriptors. - -### Wallet RPC changes - -- The `upgradewallet` RPC replaces the `-upgradewallet` command line option. - (#15761) - -- The `settxfee` RPC will fail if the fee was set higher than the `-maxtxfee` - command line setting. The wallet will already fail to create transactions - with fees higher than `-maxtxfee`. (#18467) - -- A new `fee_rate` parameter/option denominated in satoshis per vbyte (sat/vB) - is introduced to the `sendtoaddress`, `sendmany`, `fundrawtransaction` and - `walletcreatefundedpsbt` RPCs as well as to the experimental new `send` - RPC. The legacy `feeRate` option in `fundrawtransaction` and - `walletcreatefundedpsbt` still exists for setting a fee rate in BTC per 1,000 - vbytes (BTC/kvB), but it is expected to be deprecated soon to avoid - confusion. For these RPCs, the fee rate error message is updated from BTC/kB - to sat/vB and the help documentation in BTC/kB is updated to BTC/kvB. The - `send` and `sendtoaddress` RPC examples are updated to aid users in creating - transactions with explicit fee rates. (#20305, #11413) - -- The `bumpfee` RPC `fee_rate` option is changed from BTC/kvB to sat/vB and the - help documentation is updated. Users are warned that this is a breaking API - change, but it should be relatively benign: the large (100,000 times) - difference between BTC/kvB and sat/vB units means that a transaction with a - fee rate mistakenly calculated in BTC/kvB rather than sat/vB should raise an - error due to the fee rate being set too low. In the worst case, the - transaction may send at 1 sat/vB, but as Replace-by-Fee (BIP125 RBF) is active - by default when an explicit fee rate is used, the transaction fee can be - bumped. (#20305) - -GUI changes ------------ - -- Wallets created or loaded in the GUI will now be automatically loaded on - startup, so they don't need to be manually reloaded next time Bitcoin Core is - started. The list of wallets to load on startup is stored in - `\/settings.json` and augments any command line or `bitcoin.conf` - `-wallet=` settings that specify more wallets to load. Wallets that are - unloaded in the GUI get removed from the settings list so they won't load - again automatically next startup. (#19754) - -- The GUI Peers window no longer displays a "Ban Score" field. This is part of - changes in 0.20.1 and in this release to the handling of misbehaving - peers. Refer to "Changes regarding misbehaving peers" in the 0.20.1 release - notes for details. (#19512) - -Low-level changes -================= - RPC --- -- To make RPC `sendtoaddress` more consistent with `sendmany` the following error - `sendtoaddress` codes were changed from `-4` to `-6`: - - Insufficient funds - - Fee estimation failed - - Transaction has too long of a mempool chain -- The `sendrawtransaction` error code for exceeding `maxfeerate` has been changed from - `-26` to `-25`. The error string has been changed from "absurdly-high-fee" to - "Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)." The - `testmempoolaccept` RPC returns `max-fee-exceeded` rather than `absurdly-high-fee` - as the `reject-reason`. (#19339) - -- To make wallet and rawtransaction RPCs more consistent, the error message for - exceeding maximum feerate has been changed to "Fee exceeds maximum configured by user - (e.g. -maxtxfee, maxfeerate)." (#19339) - -Tests ------ - -- The BIP 325 default signet can be enabled by the `-chain=signet` or `-signet` - setting. The settings `-signetchallenge` and `-signetseednode` allow - enabling a custom signet. - -- The `generateblock` RPC allows testers using regtest mode to - generate blocks that consist of a custom set of transactions. (#17693) - -0.21.0 change log +0.21.1 change log ================= -### Consensus -- #18267 BIP-325: Signet (kallewoof) -- #20016 uint256: 1 is a constant (ajtowns) -- #20006 Fix misleading error message: Clean stack rule (sanket1729) -- #19953 Implement BIP 340-342 validation (Schnorr/taproot/tapscript) (sipa) -- #20169 Taproot follow-up: Make ComputeEntrySchnorr and ComputeEntryECDSA const to clarify contract (practicalswift) - -### Policy -- #18766 Disable fee estimation in blocksonly mode (darosior) -- #19630 Cleanup fee estimation code (darosior) -- #20165 Only relay Taproot spends if next block has it active (sipa) - -### Mining -- #17946 Fix GBT: Restore "!segwit" and "csv" to "rules" key (luke-jr) - -### Privacy -- #16432 Add privacy to the Overview page (hebasto) -- #18861 Do not answer GETDATA for to-be-announced tx (sipa) -- #18038 Mempool tracks locally submitted transactions to improve wallet privacy (amitiuttarwar) -- #19109 Only allow getdata of recently announced invs (sipa) - -### Block and transaction handling -- #17737 Add ChainstateManager, remove BlockManager global (jamesob) -- #18960 indexes: Add compact block filter headers cache (jnewbery) -- #13204 Faster sigcache nonce (JeremyRubin) -- #19088 Use std::chrono throughout some validation functions (fanquake) -- #19142 Make VerifyDB level 4 interruptible (MarcoFalke) -- #17994 Flush undo files after last block write (kallewoof) -- #18990 log: Properly log txs rejected from mempool (MarcoFalke) -- #18984 Remove unnecessary input blockfile SetPos (dgenr8) -- #19526 log: Avoid treating remote misbehvior as local system error (MarcoFalke) -- #18044 Use wtxid for transaction relay (sdaftuar) -- #18637 coins: allow cache resize after init (jamesob) -- #19854 Avoid locking CTxMemPool::cs recursively in simple cases (hebasto) -- #19478 Remove CTxMempool::mapLinks data structure member (JeremyRubin) -- #19927 Reduce direct `g_chainman` usage (dongcarl) -- #19898 log: print unexpected version warning in validation log category (n-thumann) -- #20036 signet: Add assumed values for default signet (MarcoFalke) -- #20048 chainparams: do not log signet startup messages for other chains (jonatack) -- #19339 re-delegate absurd fee checking from mempool to clients (glozow) -- #20035 signet: Fix uninitialized read in validation (MarcoFalke) -- #20157 Bugfix: chainparams: Add missing (always enabled) Taproot deployment for Signet (luke-jr) -- #20263 Update assumed chain params (MarcoFalke) -- #20372 Avoid signed integer overflow when loading a mempool.dat file with a malformed time field (practicalswift) -- #18621 script: Disallow silent bool -> cscript conversion (MarcoFalke) -- #18612, #18732 script: Remove undocumented and unused operator+ (MarcoFalke) -- #19317 Add a left-justified width field to `log2_work` component for a uniform debug.log output (jamesgmorgan) - -### P2P protocol and network code -- #18544 Limit BIP37 filter lifespan (active between `filterload`..`filterclear`) (theStack) -- #18806 Remove is{Empty,Full} flags from CBloomFilter, clarify CVE fix (theStack) -- #18512 Improve asmap checks and add sanity check (sipa) -- #18877 Serve cfcheckpt requests (jnewbery) -- #18895 Unbroadcast followups: rpcs, nLastResend, mempool sanity check (gzhao408) -- #19010 net processing: Add support for `getcfheaders` (jnewbery) -- #16939 Delay querying DNS seeds (ajtowns) -- #18807 Unbroadcast follow-ups (amitiuttarwar) -- #19044 Add support for getcfilters (jnewbery) -- #19084 improve code documentation for dns seed behaviour (ajtowns) -- #19260 disconnect peers that send filterclear + update existing filter msg disconnect logic (gzhao408) -- #19284 Add seed.bitcoin.wiz.biz to DNS seeds (wiz) -- #19322 split PushInventory() (jnewbery) -- #19204 Reduce inv traffic during IBD (MarcoFalke) -- #19470 banlist: log post-swept banlist size at startup (fanquake) -- #19191 Extract download permission from noban (MarcoFalke) -- #14033 Drop `CADDR_TIME_VERSION` checks now that `MIN_PEER_PROTO_VERSION` is greater (Empact) -- #19464 net, rpc: remove -banscore option, deprecate banscore in getpeerinfo (jonatack) -- #19514 [net/net processing] check banman pointer before dereferencing (jnewbery) -- #19512 banscore updates to gui, tests, release notes (jonatack) -- #19360 improve encapsulation of CNetAddr (vasild) -- #19217 disambiguate block-relay-only variable names from blocksonly variables (glowang) -- #19473 Add -networkactive option (hebasto) -- #19472 [net processing] Reduce `cs_main` scope in MaybeDiscourageAndDisconnect() (jnewbery) -- #19583 clean up Misbehaving() (jnewbery) -- #19534 save the network type explicitly in CNetAddr (vasild) -- #19569 Enable fetching of orphan parents from wtxid peers (sipa) -- #18991 Cache responses to GETADDR to prevent topology leaks (naumenkogs) -- #19596 Deduplicate parent txid loop of requested transactions and missing parents of orphan transactions (sdaftuar) -- #19316 Cleanup logic around connection types (amitiuttarwar) -- #19070 Signal support for compact block filters with `NODE_COMPACT_FILTERS` (jnewbery) -- #19705 Shrink CAddress from 48 to 40 bytes on x64 (vasild) -- #19704 Move ProcessMessage() to PeerLogicValidation (jnewbery) -- #19628 Change CNetAddr::ip to have flexible size (vasild) -- #19797 Remove old check for 3-byte shifted IP addresses from pre-0.2.9 nodes (#19797) -- #19607 Add Peer struct for per-peer data in net processing (jnewbery) -- #19857 improve nLastBlockTime and nLastTXTime documentation (jonatack) -- #19724 Cleanup connection types- followups (amitiuttarwar) -- #19670 Protect localhost and block-relay-only peers from eviction (sdaftuar) -- #19728 Increase the ip address relay branching factor for unreachable networks (sipa) -- #19879 Miscellaneous wtxid followups (amitiuttarwar) -- #19697 Improvements on ADDR caching (naumenkogs) -- #17785 Unify Send and Receive protocol versions (hebasto) -- #19845 CNetAddr: add support to (un)serialize as ADDRv2 (vasild) -- #19107 Move all header verification into the network layer, extend logging (troygiorshev) -- #20003 Exit with error message if -proxy is specified without arguments (instead of continuing without proxy server) (practicalswift) -- #19991 Use alternative port for incoming Tor connections (hebasto) -- #19723 Ignore unknown messages before VERACK (sdaftuar) -- #19954 Complete the BIP155 implementation and upgrade to TORv3 (vasild) -- #20119 BIP155 follow-ups (sipa) -- #19988 Overhaul transaction request logic (sipa) -- #17428 Try to preserve outbound block-relay-only connections during restart (hebasto) -- #19911 Guard `vRecvGetData` with `cs_vRecv` and `orphan_work_set` with `g_cs_orphans` (narula) -- #19753 Don't add AlreadyHave transactions to recentRejects (troygiorshev) -- #20187 Test-before-evict bugfix and improvements for block-relay-only peers (sdaftuar) -- #20237 Hardcoded seeds update for 0.21 (laanwj) -- #20212 Fix output of peer address in version message (vasild) -- #20284 Ensure old versions don't parse peers.dat (vasild) -- #20405 Avoid calculating onion address checksum when version is not 3 (lontivero) -- #20564 Don't send 'sendaddrv2' to pre-70016 software, and send before 'verack' (sipa) -- #20660 Move signet onion seed from v2 to v3 (Sjors) - -### Wallet -- #18262 Exit selection when `best_waste` is 0 (achow101) -- #17824 Prefer full destination groups in coin selection (fjahr) -- #17219 Allow transaction without change if keypool is empty (Sjors) -- #15761 Replace -upgradewallet startup option with upgradewallet RPC (achow101) -- #18671 Add BlockUntilSyncedToCurrentChain to dumpwallet (MarcoFalke) -- #16528 Native Descriptor Wallets using DescriptorScriptPubKeyMan (achow101) -- #18777 Recommend absolute path for dumpwallet (MarcoFalke) -- #16426 Reverse `cs_main`, `cs_wallet` lock order and reduce `cs_main` locking (ariard) -- #18699 Avoid translating RPC errors (MarcoFalke) -- #18782 Make sure no DescriptorScriptPubKeyMan or WalletDescriptor members are left uninitialized after construction (practicalswift) -- #9381 Remove CWalletTx merging logic from AddToWallet (ryanofsky) -- #16946 Include a checksum of encrypted private keys (achow101) -- #17681 Keep inactive seeds after sethdseed and derive keys from them as needed (achow101) -- #18918 Move salvagewallet into wallettool (achow101) -- #14988 Fix for confirmed column in csv export for payment to self transactions (benthecarman) -- #18275 Error if an explicit fee rate was given but the needed fee rate differed (kallewoof) -- #19054 Skip hdKeypath of 'm' when determining inactive hd seeds (achow101) -- #17938 Disallow automatic conversion between disparate hash types (Empact) -- #19237 Check size after unserializing a pubkey (elichai) -- #11413 sendtoaddress/sendmany: Add explicit feerate option (kallewoof) -- #18850 Fix ZapSelectTx to sync wallet spends (bvbfan) -- #18923 Never schedule MaybeCompactWalletDB when `-flushwallet` is off (MarcoFalke) -- #19441 walletdb: Don't reinitialize desc cache with multiple cache entries (achow101) -- #18907 walletdb: Don't remove database transaction logs and instead error (achow101) -- #19334 Introduce WalletDatabase abstract class (achow101) -- #19335 Cleanup and separate BerkeleyDatabase and BerkeleyBatch (achow101) -- #19102 Introduce and use DummyDatabase instead of dummy BerkeleyDatabase (achow101) -- #19568 Wallet should not override signing errors (fjahr) -- #17204 Do not turn `OP_1NEGATE` in scriptSig into `0x0181` in signing code (sipa) (meshcollider) -- #19457 Cleanup wallettool salvage and walletdb extraneous declarations (achow101) -- #15937 Add loadwallet and createwallet `load_on_startup` options (ryanofsky) -- #16841 Replace GetScriptForWitness with GetScriptForDestination (meshcollider) -- #14582 always do avoid partial spends if fees are within a specified range (kallewoof) -- #19743 -maxapsfee follow-up (kallewoof) -- #19289 GetWalletTx and IsMine require `cs_wallet` lock (promag) -- #19671 Remove -zapwallettxes (achow101) -- #19805 Avoid deserializing unused records when salvaging (achow101) -- #19754 wallet, gui: Reload previously loaded wallets on startup (achow101) -- #19738 Avoid multiple BerkeleyBatch in DelAddressBook (promag) -- #19919 bugfix: make LoadWallet assigns status always (AkioNak) -- #16378 The ultimate send RPC (Sjors) -- #15454 Remove the automatic creation and loading of the default wallet (achow101) -- #19501 `send*` RPCs in the wallet returns the "fee reason" (stackman27) -- #20130 Remove db mode string (S3RK) -- #19077 Add sqlite as an alternative wallet database and use it for new descriptor wallets (achow101) -- #20125 Expose database format in getwalletinfo (promag) -- #20198 Show name, format and if uses descriptors in bitcoin-wallet tool (jonasschnelli) -- #20216 Fix buffer over-read in SQLite file magic check (theStack) -- #20186 Make -wallet setting not create wallets (ryanofsky) -- #20230 Fix bug when just created encrypted wallet cannot get address (hebasto) -- #20282 Change `upgradewallet` return type to be an object (jnewbery) -- #20220 Explicit fee rate follow-ups/fixes for 0.21 (jonatack) -- #20199 Ignore (but warn) on duplicate -wallet parameters (jonasschnelli) -- #20324 Set DatabaseStatus::SUCCESS in MakeSQLiteDatabase (MarcoFalke) -- #20266 Fix change detection of imported internal descriptors (achow101) -- #20153 Do not import a descriptor with hardened derivations into a watch-only wallet (S3RK) -- #20344 Fix scanning progress calculation for single block range (theStack) -- #19502 Bugfix: Wallet: Soft-fail exceptions within ListWalletDir file checks (luke-jr) -- #20378 Fix potential division by 0 in WalletLogPrintf (jonasschnelli) -- #18836 Upgradewallet fixes and additional tests (achow101) -- #20139 Do not return warnings from UpgradeWallet() (stackman27) -- #20305 Introduce `fee_rate` sat/vB param/option (jonatack) -- #20426 Allow zero-fee fundrawtransaction/walletcreatefundedpsbt and other fixes (jonatack) -- #20573 wallet, bugfix: allow send with string `fee_rate` amounts (jonatack) - -### RPC and other APIs -- #18574 cli: Call getbalances.ismine.trusted instead of getwalletinfo.balance (jonatack) -- #17693 Add `generateblock` to mine a custom set of transactions (andrewtoth) -- #18495 Remove deprecated migration code (vasild) -- #18493 Remove deprecated "size" from mempool txs (vasild) -- #18467 Improve documentation and return value of settxfee (fjahr) -- #18607 Fix named arguments in documentation (MarcoFalke) -- #17831 doc: Fix and extend getblockstats examples (asoltys) -- #18785 Prevent valgrind false positive in `rest_blockhash_by_height` (ryanofsky) -- #18999 log: Remove "No rpcpassword set" from logs (MarcoFalke) -- #19006 Avoid crash when `g_thread_http` was never started (MarcoFalke) -- #18594 cli: Display multiwallet balances in -getinfo (jonatack) -- #19056 Make gettxoutsetinfo/GetUTXOStats interruptible (MarcoFalke) -- #19112 Remove special case for unknown service flags (MarcoFalke) -- #18826 Expose txinwitness for coinbase in JSON form from RPC (rvagg) -- #19282 Rephrase generatetoaddress help, and use `PACKAGE_NAME` (luke-jr) -- #16377 don't automatically append inputs in walletcreatefundedpsbt (Sjors) -- #19200 Remove deprecated getaddressinfo fields (jonatack) -- #19133 rpc, cli, test: add bitcoin-cli -generate command (jonatack) -- #19469 Deprecate banscore field in getpeerinfo (jonatack) -- #16525 Dump transaction version as an unsigned integer in RPC/TxToUniv (TheBlueMatt) -- #19555 Deduplicate WriteHDKeypath() used in decodepsbt (theStack) -- #19589 Avoid useless mempool query in gettxoutproof (MarcoFalke) -- #19585 RPCResult Type of MempoolEntryDescription should be OBJ (stylesuxx) -- #19634 Document getwalletinfo's `unlocked_until` field as optional (justinmoon) -- #19658 Allow RPC to fetch all addrman records and add records to addrman (jnewbery) -- #19696 Fix addnode remove command error (fjahr) -- #18654 Separate bumpfee's psbt creation function into psbtbumpfee (achow101) -- #19655 Catch listsinceblock `target_confirmations` exceeding block count (adaminsky) -- #19644 Document returned error fields as optional if applicable (theStack) -- #19455 rpc generate: print useful help and error message (jonatack) -- #19550 Add listindices RPC (fjahr) -- #19169 Validate provided keys for `query_options` parameter in listunspent (PastaPastaPasta) -- #18244 fundrawtransaction and walletcreatefundedpsbt also lock manually selected coins (Sjors) -- #14687 zmq: Enable TCP keepalive (mruddy) -- #19405 Add network in/out connections to `getnetworkinfo` and `-getinfo` (jonatack) -- #19878 rawtransaction: Fix argument in combinerawtransaction help message (pinheadmz) -- #19940 Return fee and vsize from testmempoolaccept (gzhao408) -- #13686 zmq: Small cleanups in the ZMQ code (domob1812) -- #19386, #19528, #19717, #19849, #19994 Assert that RPCArg names are equal to CRPCCommand ones (MarcoFalke) -- #19725 Add connection type to getpeerinfo, improve logs (amitiuttarwar) -- #19969 Send RPC bug fix and touch-ups (Sjors) -- #18309 zmq: Add support to listen on multiple interfaces (n-thumann) -- #20055 Set HTTP Content-Type in bitcoin-cli (laanwj) -- #19956 Improve invalid vout value rpc error message (n1rna) -- #20101 Change no wallet loaded message to be clearer (achow101) -- #19998 Add `via_tor` to `getpeerinfo` output (hebasto) -- #19770 getpeerinfo: Deprecate "whitelisted" field (replaced by "permissions") (luke-jr) -- #20120 net, rpc, test, bugfix: update GetNetworkName, GetNetworksInfo, regression tests (jonatack) -- #20595 Improve heuristic hex transaction decoding (sipa) -- #20731 Add missing description of vout in getrawtransaction help text (benthecarman) -- #19328 Add gettxoutsetinfo `hash_type` option (fjahr) -- #19731 Expose nLastBlockTime/nLastTXTime as last `block/last_transaction` in getpeerinfo (jonatack) -- #19572 zmq: Create "sequence" notifier, enabling client-side mempool tracking (instagibbs) -- #20002 Expose peer network in getpeerinfo; simplify/improve -netinfo (jonatack) - -### GUI -- #17905 Avoid redundant tx status updates (ryanofsky) -- #18646 Use `PACKAGE_NAME` in exception message (fanquake) -- #17509 Save and load PSBT (Sjors) -- #18769 Remove bug fix for Qt < 5.5 (10xcryptodev) -- #15768 Add close window shortcut (IPGlider) -- #16224 Bilingual GUI error messages (hebasto) -- #18922 Do not translate InitWarning messages in debug.log (hebasto) -- #18152 Use NotificationStatus enum for signals to GUI (hebasto) -- #18587 Avoid wallet tryGetBalances calls in WalletModel::pollBalanceChanged (ryanofsky) -- #17597 Fix height of QR-less ReceiveRequestDialog (hebasto) -- #17918 Hide non PKHash-Addresses in signing address book (emilengler) -- #17956 Disable unavailable context menu items in transactions tab (kristapsk) -- #17968 Ensure that ModalOverlay is resized properly (hebasto) -- #17993 Balance/TxStatus polling update based on last block hash (furszy) -- #18424 Use parent-child relation to manage lifetime of OptionsModel object (hebasto) -- #18452 Fix shutdown when `waitfor*` cmds are called from RPC console (hebasto) -- #15202 Add Close All Wallets action (promag) -- #19132 lock `cs_main`, `m_cached_tip_mutex` in that order (vasild) -- #18898 Display warnings as rich text (hebasto) -- #19231 add missing translation.h include to fix build (fanquake) -- #18027 "PSBT Operations" dialog (gwillen) -- #19256 Change combiner for signals to `optional_last_value` (fanquake) -- #18896 Reset toolbar after all wallets are closed (hebasto) -- #18993 increase console command max length (10xcryptodev) -- #19323 Fix regression in *txoutset* in GUI console (hebasto) -- #19210 Get rid of cursor in out-of-focus labels (hebasto) -- #19011 Reduce `cs_main` lock accumulation during GUI startup (jonasschnelli) -- #19844 Remove usage of boost::bind (fanquake) -- #20479 Fix QPainter non-determinism on macOS (0.21 backport) (laanwj) -- gui#6 Do not truncate node flag strings in debugwindow peers details tab (Saibato) -- gui#8 Fix regression in TransactionTableModel (hebasto) -- gui#17 doc: Remove outdated comment in TransactionTablePriv (MarcoFalke) -- gui#20 Wrap tooltips in the intro window (hebasto) -- gui#30 Disable the main window toolbar when the modal overlay is shown (hebasto) -- gui#34 Show permissions instead of whitelisted (laanwj) -- gui#35 Parse params directly instead of through node (ryanofsky) -- gui#39 Add visual accenting for the 'Create new receiving address' button (hebasto) -- gui#40 Clarify block height label (hebasto) -- gui#43 bugfix: Call setWalletActionsEnabled(true) only for the first wallet (hebasto) -- gui#97 Relax GUI freezes during IBD (jonasschnelli) -- gui#71 Fix visual quality of text in QR image (hebasto) -- gui#96 Slight improve create wallet dialog (Sjors) -- gui#102 Fix SplashScreen crash when run with -disablewallet (hebasto) -- gui#116 Fix unreasonable default size of the main window without loaded wallets (hebasto) -- gui#120 Fix multiwallet transaction notifications (promag) - -### Build system -- #18504 Drop bitcoin-tx and bitcoin-wallet dependencies on libevent (ryanofsky) -- #18586 Bump gitian descriptors to 0.21 (laanwj) -- #17595 guix: Enable building for `x86_64-w64-mingw32` target (dongcarl) -- #17929 add linker optimisation flags to gitian & guix (Linux) (fanquake) -- #18556 Drop make dist in gitian builds (hebasto) -- #18088 ensure we aren't using GNU extensions (fanquake) -- #18741 guix: Make source tarball using git-archive (dongcarl) -- #18843 warn on potentially uninitialized reads (vasild) -- #17874 make linker checks more robust (fanquake) -- #18535 remove -Qunused-arguments workaround for clang + ccache (fanquake) -- #18743 Add --sysroot option to mac os native compile flags (ryanofsky) -- #18216 test, build: Enable -Werror=sign-compare (Empact) -- #18928 don't pass -w when building for Windows (fanquake) -- #16710 Enable -Wsuggest-override if available (hebasto) -- #18738 Suppress -Wdeprecated-copy warnings (hebasto) -- #18862 Remove fdelt_chk back-compat code and sanity check (fanquake) -- #18887 enable -Werror=gnu (vasild) -- #18956 enforce minimum required Windows version (7) (fanquake) -- #18958 guix: Make V=1 more powerful for debugging (dongcarl) -- #18677 Multiprocess build support (ryanofsky) -- #19094 Only allow ASCII identifiers (laanwj) -- #18820 Propagate well-known vars into depends (dongcarl) -- #19173 turn on --enable-c++17 by --enable-fuzz (vasild) -- #18297 Use pkg-config in BITCOIN_QT_CONFIGURE for all hosts including Windows (hebasto) -- #19301 don't warn when doxygen isn't found (fanquake) -- #19240 macOS toolchain simplification and bump (dongcarl) -- #19356 Fix search for brew-installed BDB 4 on OS X (gwillen) -- #19394 Remove unused `RES_IMAGES` (Bushstar) -- #19403 improve `__builtin_clz*` detection (fanquake) -- #19375 target Windows 7 when building libevent and fix ipv6 usage (fanquake) -- #19331 Do not include server symbols in wallet (MarcoFalke) -- #19257 remove BIP70 configure option (fanquake) -- #18288 Add MemorySanitizer (MSan) in Travis to detect use of uninitialized memory (practicalswift) -- #18307 Require pkg-config for all of the hosts (hebasto) -- #19445 Update msvc build to use ISO standard C++17 (sipsorcery) -- #18882 fix -Wformat-security check when compiling with GCC (fanquake) -- #17919 Allow building with system clang (dongcarl) -- #19553 pass -fcommon when building genisoimage (fanquake) -- #19565 call `AC_PATH_TOOL` for dsymutil in macOS cross-compile (fanquake) -- #19530 build LTO support into Apple's ld64 (theuni) -- #19525 add -Wl,-z,separate-code to hardening flags (fanquake) -- #19667 set minimum required Boost to 1.58.0 (fanquake) -- #19672 make clean removes .gcda and .gcno files from fuzz directory (Crypt-iQ) -- #19622 Drop ancient hack in gitian-linux descriptor (hebasto) -- #19688 Add support for llvm-cov (hebasto) -- #19718 Add missed gcov files to 'make clean' (hebasto) -- #19719 Add Werror=range-loop-analysis (MarcoFalke) -- #19015 Enable some commonly enabled compiler diagnostics (practicalswift) -- #19689 build, qt: Add Qt version checking (hebasto) -- #17396 modest Android improvements (icota) -- #18405 Drop all of the ZeroMQ patches (hebasto) -- #15704 Move Win32 defines to configure.ac to ensure they are globally defined (luke-jr) -- #19761 improve sed robustness by not using sed (fanquake) -- #19758 Drop deprecated and unused `GUARDED_VAR` and `PT_GUARDED_VAR` annotations (hebasto) -- #18921 add stack-clash and control-flow protection options to hardening flags (fanquake) -- #19803 Bugfix: Define and use `HAVE_FDATASYNC` correctly outside LevelDB (luke-jr) -- #19685 CMake invocation cleanup (dongcarl) -- #19861 add /usr/local/ to `LCOV_FILTER_PATTERN` for macOS builds (Crypt-iQ) -- #19916 allow user to specify `DIR_FUZZ_SEED_CORPUS` for `cov_fuzz` (Crypt-iQ) -- #19944 Update secp256k1 subtree (including BIP340 support) (sipa) -- #19558 Split pthread flags out of ldflags and dont use when building libconsensus (fanquake) -- #19959 patch qt libpng to fix powerpc build (fanquake) -- #19868 Fix target name (hebasto) -- #19960 The vcpkg tool has introduced a proper way to use manifests (sipsorcery) -- #20065 fuzz: Configure check for main function (MarcoFalke) -- #18750 Optionally skip external warnings (vasild) -- #20147 Update libsecp256k1 (endomorphism, test improvements) (sipa) -- #20156 Make sqlite support optional (compile-time) (luke-jr) -- #20318 Ensure source tarball has leading directory name (MarcoFalke) -- #20447 Patch `qt_intersect_spans` to avoid non-deterministic behavior in LLVM 8 (achow101) -- #20505 Avoid secp256k1.h include from system (dergoegge) -- #20527 Do not ignore Homebrew's SQLite on macOS (hebasto) -- #20478 Don't set BDB flags when configuring without (jonasschnelli) -- #20563 Check that Homebrew's berkeley-db4 package is actually installed (hebasto) -- #19493 Fix clang build on Mac (bvbfan) - -### Tests and QA -- #18593 Complete impl. of `msg_merkleblock` and `wait_for_merkleblock` (theStack) -- #18609 Remove REJECT message code (hebasto) -- #18584 Check that the version message does not leak the local address (MarcoFalke) -- #18597 Extend `wallet_dump` test to cover comments (MarcoFalke) -- #18596 Try once more when RPC connection fails on Windows (MarcoFalke) -- #18451 shift coverage from getunconfirmedbalance to getbalances (jonatack) -- #18631 appveyor: Disable functional tests for now (MarcoFalke) -- #18628 Add various low-level p2p tests (MarcoFalke) -- #18615 Avoid accessing free'd memory in `validation_chainstatemanager_tests` (MarcoFalke) -- #18571 fuzz: Disable debug log file (MarcoFalke) -- #18653 add coverage for bitcoin-cli -rpcwait (jonatack) -- #18660 Verify findCommonAncestor always initializes outputs (ryanofsky) -- #17669 Have coins simulation test also use CCoinsViewDB (jamesob) -- #18662 Replace gArgs with local argsman in bench (MarcoFalke) -- #18641 Create cached blocks not in the future (MarcoFalke) -- #18682 fuzz: `http_request` workaround for libevent < 2.1.1 (theStack) -- #18692 Bump timeout in `wallet_import_rescan` (MarcoFalke) -- #18695 Replace boost::mutex with std::mutex (hebasto) -- #18633 Properly raise FailedToStartError when rpc shutdown before warmup finished (MarcoFalke) -- #18675 Don't initialize PrecomputedTransactionData in txvalidationcache tests (jnewbery) -- #18691 Add `wait_for_cookie_credentials()` to framework for rpcwait tests (jonatack) -- #18672 Add further BIP37 size limit checks to `p2p_filter.py` (theStack) -- #18721 Fix linter issue (hebasto) -- #18384 More specific `feature_segwit` test error messages and fixing incorrect comments (gzhao408) -- #18575 bench: Remove requirement that all benches use same testing setup (MarcoFalke) -- #18690 Check object hashes in `wait_for_getdata` (robot-visions) -- #18712 display command line options passed to `send_cli()` in debug log (jonatack) -- #18745 Check submitblock return values (MarcoFalke) -- #18756 Use `wait_for_getdata()` in `p2p_compactblocks.py` (theStack) -- #18724 Add coverage for -rpcwallet cli option (jonatack) -- #18754 bench: Add caddrman benchmarks (vasild) -- #18585 Use zero-argument super() shortcut (Python 3.0+) (theStack) -- #18688 fuzz: Run in parallel (MarcoFalke) -- #18770 Remove raw-tx byte juggling in `mempool_reorg` (MarcoFalke) -- #18805 Add missing `sync_all` to `wallet_importdescriptors.py` (achow101) -- #18759 bench: Start nodes with -nodebuglogfile (MarcoFalke) -- #18774 Added test for upgradewallet RPC (brakmic) -- #18485 Add `mempool_updatefromblock.py` (hebasto) -- #18727 Add CreateWalletFromFile test (ryanofsky) -- #18726 Check misbehavior more independently in `p2p_filter.py` (robot-visions) -- #18825 Fix message for `ECC_InitSanityCheck` test (fanquake) -- #18576 Use unittest for `test_framework` unit testing (gzhao408) -- #18828 Strip down previous releases boilerplate (MarcoFalke) -- #18617 Add factor option to adjust test timeouts (brakmic) -- #18855 `feature_backwards_compatibility.py` test downgrade after upgrade (achow101) -- #18864 Add v0.16.3 backwards compatibility test, bump v0.19.0.1 to v0.19.1 (Sjors) -- #18917 fuzz: Fix vector size problem in system fuzzer (brakmic) -- #18901 fuzz: use std::optional for `sep_pos_opt` variable (brakmic) -- #18888 Remove RPCOverloadWrapper boilerplate (MarcoFalke) -- #18952 Avoid os-dependent path (fametrano) -- #18938 Fill fuzzing coverage gaps for functions in consensus/validation.h, primitives/block.h and util/translation.h (practicalswift) -- #18986 Add capability to disable RPC timeout in functional tests (rajarshimaitra) -- #18530 Add test for -blocksonly and -whitelistforcerelay param interaction (glowang) -- #19014 Replace `TEST_PREVIOUS_RELEASES` env var with `test_framework` option (MarcoFalke) -- #19052 Don't limit fuzzing inputs to 1 MB for afl-fuzz (now: ∞ ∀ fuzzers) (practicalswift) -- #19060 Remove global `wait_until` from `p2p_getdata` (MarcoFalke) -- #18926 Pass ArgsManager into `getarg_tests` (glowang) -- #19110 Explain that a bug should be filed when the tests fail (MarcoFalke) -- #18965 Implement `base58_decode` (10xcryptodev) -- #16564 Always define the `raii_event_tests` test suite (candrews) -- #19122 Add missing `sync_blocks` to `wallet_hd` (MarcoFalke) -- #18875 fuzz: Stop nodes in `process_message*` fuzzers (MarcoFalke) -- #18974 Check that invalid witness destinations can not be imported (MarcoFalke) -- #18210 Type hints in Python tests (kiminuo) -- #19159 Make valgrind.supp work on aarch64 (MarcoFalke) -- #19082 Moved the CScriptNum asserts into the unit test in script.py (gillichu) -- #19172 Do not swallow flake8 exit code (hebasto) -- #19188 Avoid overwriting the NodeContext member of the testing setup [-Wshadow-field] (MarcoFalke) -- #18890 `disconnect_nodes` should warn if nodes were already disconnected (robot-visions) -- #19227 change blacklist to blocklist (TrentZ) -- #19230 Move base58 to own module to break circular dependency (sipa) -- #19083 `msg_mempool`, `fRelay`, and other bloomfilter tests (gzhao408) -- #16756 Connection eviction logic tests (mzumsande) -- #19177 Fix and clean `p2p_invalid_messages` functional tests (troygiorshev) -- #19264 Don't import asyncio to test magic bytes (jnewbery) -- #19178 Make `mininode_lock` non-reentrant (jnewbery) -- #19153 Mempool compatibility test (S3RK) -- #18434 Add a test-security target and run it in CI (fanquake) -- #19252 Wait for disconnect in `disconnect_p2ps` + bloomfilter test followups (gzhao408) -- #19298 Add missing `sync_blocks` (MarcoFalke) -- #19304 Check that message sends successfully when header is split across two buffers (troygiorshev) -- #19208 move `sync_blocks` and `sync_mempool` functions to `test_framework.py` (ycshao) -- #19198 Check that peers with forcerelay permission are not asked to feefilter (MarcoFalke) -- #19351 add two edge case tests for CSubNet (vasild) -- #19272 net, test: invalid p2p messages and test framework improvements (jonatack) -- #19348 Bump linter versions (duncandean) -- #19366 Provide main(…) function in fuzzer. Allow building uninstrumented harnesses with --enable-fuzz (practicalswift) -- #19412 move `TEST_RUNNER_EXTRA` into native tsan setup (fanquake) -- #19368 Improve functional tests compatibility with BSD/macOS (S3RK) -- #19028 Set -logthreadnames in unit tests (MarcoFalke) -- #18649 Add std::locale::global to list of locale dependent functions (practicalswift) -- #19140 Avoid fuzzer-specific nullptr dereference in libevent when handling PROXY requests (practicalswift) -- #19214 Auto-detect SHA256 implementation in benchmarks (sipa) -- #19353 Fix mistakenly swapped "previous" and "current" lock orders (hebasto) -- #19533 Remove unnecessary `cs_mains` in `denialofservice_tests` (jnewbery) -- #19423 add functional test for txrelay during and after IBD (gzhao408) -- #16878 Fix non-deterministic coverage of test `DoS_mapOrphans` (davereikher) -- #19548 fuzz: add missing overrides to `signature_checker` (jonatack) -- #19562 Fix fuzzer compilation on macOS (freenancial) -- #19370 Static asserts for consistency of fee defaults (domob1812) -- #19599 clean `message_count` and `last_message` (troygiorshev) -- #19597 test decodepsbt fee calculation (count input value only once per UTXO) (theStack) -- #18011 Replace current benchmarking framework with nanobench (martinus) -- #19489 Fail `wait_until` early if connection is lost (MarcoFalke) -- #19340 Preserve the `LockData` initial state if "potential deadlock detected" exception thrown (hebasto) -- #19632 Catch decimal.InvalidOperation from `TestNodeCLI#send_cli` (Empact) -- #19098 Remove duplicate NodeContext hacks (ryanofsky) -- #19649 Restore test case for p2p transaction blinding (instagibbs) -- #19657 Wait until `is_connected` in `add_p2p_connection` (MarcoFalke) -- #19631 Wait for 'cmpctblock' in `p2p_compactblocks` when it is expected (Empact) -- #19674 use throwaway _ variable for unused loop counters (theStack) -- #19709 Fix 'make cov' with clang (hebasto) -- #19564 `p2p_feefilter` improvements (logging, refactoring, speedup) (theStack) -- #19756 add `sync_all` to fix race condition in wallet groups test (kallewoof) -- #19727 Removing unused classes from `p2p_leak.py` (dhruv) -- #19722 Add test for getblockheader verboseness (torhte) -- #19659 Add a seed corpus generation option to the fuzzing `test_runner` (darosior) -- #19775 Activate segwit in TestChain100Setup (MarcoFalke) -- #19760 Remove confusing mininode terminology (jnewbery) -- #19752 Update `wait_until` usage in tests not to use the one from utils (slmtpz) -- #19839 Set appveyor VM version to previous Visual Studio 2019 release (sipsorcery) -- #19830 Add tsan supp for leveldb::DBImpl::DeleteObsoleteFiles (MarcoFalke) -- #19710 bench: Prevent thread oversubscription and decreases the variance of result values (hebasto) -- #19842 Update the vcpkg checkout commit ID in appveyor config (sipsorcery) -- #19507 Expand functional zmq transaction tests (instagibbs) -- #19816 Rename wait until helper to `wait_until_helper` (MarcoFalke) -- #19859 Fixes failing functional test by changing version (n-thumann) -- #19887 Fix flaky `wallet_basic` test (fjahr) -- #19897 Change `FILE_CHAR_BLOCKLIST` to `FILE_CHARS_DISALLOWED` (verretor) -- #19800 Mockwallet (MarcoFalke) -- #19922 Run `rpc_txoutproof.py` even with wallet disabled (MarcoFalke) -- #19936 batch rpc with params (instagibbs) -- #19971 create default wallet in extended tests (Sjors) -- #19781 add parameterized constructor for `msg_sendcmpct()` (theStack) -- #19963 Clarify blocksonly whitelistforcerelay test (t-bast) -- #20022 Use explicit p2p objects where available (guggero) -- #20028 Check that invalid peer traffic is accounted for (MarcoFalke) -- #20004 Add signet witness commitment section parse tests (MarcoFalke) -- #20034 Get rid of default wallet hacks (ryanofsky) -- #20069 Mention commit id in scripted diff error (laanwj) -- #19947 Cover `change_type` option of "walletcreatefundedpsbt" RPC (guggero) -- #20126 `p2p_leak_tx.py` improvements (use MiniWallet, add `p2p_lock` acquires) (theStack) -- #20129 Don't export `in6addr_loopback` (vasild) -- #20131 Remove unused nVersion=1 in p2p tests (MarcoFalke) -- #20161 Minor Taproot follow-ups (sipa) -- #19401 Use GBT to get block versions correct (luke-jr) -- #20159 `mining_getblocktemplate_longpoll.py` improvements (use MiniWallet, add logging) (theStack) -- #20039 Convert amounts from float to decimal (prayank23) -- #20112 Speed up `wallet_resendwallettransactions` with mockscheduler RPC (MarcoFalke) -- #20247 fuzz: Check for addrv1 compatibility before using addrv1 serializer. Fuzz addrv2 serialization (practicalswift) -- #20167 Add test for -blockversion (MarcoFalke) -- #19877 Clarify `rpc_net` & `p2p_disconnect_ban functional` tests (amitiuttarwar) -- #20258 Remove getnettotals/getpeerinfo consistency test (jnewbery) -- #20242 fuzz: Properly initialize PrecomputedTransactionData (MarcoFalke) -- #20262 Skip --descriptor tests if sqlite is not compiled (achow101) -- #18788 Update more tests to work with descriptor wallets (achow101) -- #20289 fuzz: Check for addrv1 compatibility before using addrv1 serializer/deserializer on CService (practicalswift) -- #20290 fuzz: Fix DecodeHexTx fuzzing harness issue (practicalswift) -- #20245 Run `script_assets_test` even if built --with-libs=no (MarcoFalke) -- #20300 fuzz: Add missing `ECC_Start` to `descriptor_parse` test (S3RK) -- #20283 Only try witness deser when checking for witness deser failure (MarcoFalke) -- #20303 fuzz: Assert expected DecodeHexTx behaviour when using legacy decoding (practicalswift) -- #20316 Fix `wallet_multiwallet` test issue on Windows (MarcoFalke) -- #20326 Fix `ecdsa_verify` in test framework (stepansnigirev) -- #20328 cirrus: Skip tasks on the gui repo main branch (MarcoFalke) -- #20355 fuzz: Check for addrv1 compatibility before using addrv1 serializer/deserializer on CSubNet (practicalswift) -- #20332 Mock IBD in `net_processing` fuzzers (MarcoFalke) -- #20218 Suppress `epoll_ctl` data race (MarcoFalke) -- #20375 fuzz: Improve coverage for CPartialMerkleTree fuzzing harness (practicalswift) -- #19669 contrib: Fixup valgrind suppressions file (MarcoFalke) -- #18879 valgrind: remove outdated suppressions (fanquake) -- #19226 Add BerkeleyDatabase tsan suppression (MarcoFalke) -- #20379 Remove no longer needed UBSan suppression (float divide-by-zero in validation.cpp) (practicalswift) -- #18190, #18736, #18744, #18775, #18783, #18867, #18994, #19065, - #19067, #19143, #19222, #19247, #19286, #19296, #19379, #19934, - #20188, #20395 Add fuzzing harnessses (practicalswift) -- #18638 Use mockable time for ping/pong, add tests (MarcoFalke) -- #19951 CNetAddr scoped ipv6 test coverage, rename scopeId to `m_scope_id` (jonatack) -- #20027 Use mockable time everywhere in `net_processing` (sipa) -- #19105 Add Muhash3072 implementation in Python (fjahr) -- #18704, #18752, #18753, #18765, #18839, #18866, #18873, #19022, - #19023, #19429, #19552, #19778, #20176, #20179, #20214, #20292, - #20299, #20322 Fix intermittent test issues (MarcoFalke) -- #20390 CI/Cirrus: Skip `merge_base` step for non-PRs (luke-jr) -- #18634 ci: Add fuzzbuzz integration configuration file (practicalswift) -- #18591 Add C++17 build to Travis (sipa) -- #18581, #18667, #18798, #19495, #19519, #19538 CI improvements (hebasto) -- #18683, #18705, #18735, #18778, #18799, #18829, #18912, #18929, - #19008, #19041, #19164, #19201, #19267, #19276, #19321, #19371, - #19427, #19730, #19746, #19881, #20294, #20339, #20368 CI improvements (MarcoFalke) -- #20489, #20506 MSVC CI improvements (sipsorcery) - -### Miscellaneous -- #18713 scripts: Add macho stack canary check to security-check.py (fanquake) -- #18629 scripts: Add pe .reloc section check to security-check.py (fanquake) -- #18437 util: `Detect posix_fallocate()` instead of assuming (vasild) -- #18413 script: Prevent ub when computing abs value for num opcode serialize (pierreN) -- #18443 lockedpool: avoid sensitive data in core files (FreeBSD) (vasild) -- #18885 contrib: Move optimize-pngs.py script to the maintainer repo (MarcoFalke) -- #18317 Serialization improvements step 6 (all except wallet/gui) (sipa) -- #16127 More thread safety annotation coverage (ajtowns) -- #19228 Update libsecp256k1 subtree (sipa) -- #19277 util: Add assert identity function (MarcoFalke) -- #19491 util: Make assert work with any value (MarcoFalke) -- #19205 script: `previous_release.sh` rewritten in python (bliotti) -- #15935 Add /settings.json persistent settings storage (ryanofsky) -- #19439 script: Linter to check commit message formatting (Ghorbanian) -- #19654 lint: Improve commit message linter in travis (fjahr) -- #15382 util: Add runcommandparsejson (Sjors) -- #19614 util: Use `have_fdatasync` to determine fdatasync() use (fanquake) -- #19813 util, ci: Hard code previous release tarball checksums (hebasto) -- #19841 Implement Keccak and `SHA3_256` (sipa) -- #19643 Add -netinfo peer connections dashboard (jonatack) -- #15367 feature: Added ability for users to add a startup command (benthecarman) -- #19984 log: Remove static log message "Initializing chainstate Chainstate [ibd] @ height -1 (null)" (practicalswift) -- #20092 util: Do not use gargs global in argsmanager member functions (hebasto) -- #20168 contrib: Fix `gen_key_io_test_vectors.py` imports (MarcoFalke) -- #19624 Warn on unknown `rw_settings` (MarcoFalke) -- #20257 Update secp256k1 subtree to latest master (sipa) -- #20346 script: Modify security-check.py to use "==" instead of "is" for literal comparison (tylerchambers) -- #18881 Prevent UB in DeleteLock() function (hebasto) -- #19180, #19189, #19190, #19220, #19399 Replace RecursiveMutex with Mutex (hebasto) -- #19347 Make `cs_inventory` nonrecursive (jnewbery) -- #19773 Avoid recursive lock in IsTrusted (promag) -- #18790 Improve thread naming (hebasto) -- #20140 Restore compatibility with old CSubNet serialization (sipa) -- #17775 DecodeHexTx: Try case where txn has inputs first (instagibbs) - -### Documentation -- #18502 Update docs for getbalance (default minconf should be 0) (uzyn) -- #18632 Fix macos comments in release-notes (MarcoFalke) -- #18645 Update thread information in developer docs (jnewbery) -- #18709 Note why we can't use `thread_local` with glibc back compat (fanquake) -- #18410 Improve commenting for coins.cpp|h (jnewbery) -- #18157 fixing init.md documentation to not require rpcpassword (jkcd) -- #18739 Document how to fuzz Bitcoin Core using Honggfuzz (practicalswift) -- #18779 Better explain GNU ld's dislike of ld64's options (fanquake) -- #18663 Mention build docs in README.md (saahilshangle) -- #18810 Update rest info on block size and json (chrisabrams) -- #18939 Add c++17-enable flag to fuzzing instructions (mzumsande) -- #18957 Add a link from ZMQ doc to ZMQ example in contrib/ (meeDamian) -- #19058 Drop protobuf stuff (hebasto) -- #19061 Add link to Visual Studio build readme (maitrebitcoin) -- #19072 Expand section on Getting Started (MarcoFalke) -- #18968 noban precludes maxuploadtarget disconnects (MarcoFalke) -- #19005 Add documentation for 'checklevel' argument in 'verifychain' RPC… (kcalvinalvin) -- #19192 Extract net permissions doc (MarcoFalke) -- #19071 Separate repository for the gui (MarcoFalke) -- #19018 fixing description of the field sequence in walletcreatefundedpsbt RPC method (limpbrains) -- #19367 Span pitfalls (sipa) -- #19408 Windows WSL build recommendation to temporarily disable Win32 PE support (sipsorcery) -- #19407 explain why passing -mlinker-version is required when cross-compiling (fanquake) -- #19452 afl fuzzing comment about afl-gcc and afl-g++ (Crypt-iQ) -- #19258 improve subtree check instructions (Sjors) -- #19474 Use precise permission flags where possible (MarcoFalke) -- #19494 CONTRIBUTING.md improvements (jonatack) -- #19268 Add non-thread-safe note to FeeFilterRounder::round() (hebasto) -- #19547 Update macOS cross compilation dependencies for Focal (hebasto) -- #19617 Clang 8 or later is required with `FORCE_USE_SYSTEM_CLANG` (fanquake) -- #19639 Remove Reference Links #19582 (RobertHosking) -- #19605 Set `CC_FOR_BUILD` when building on OpenBSD (fanquake) -- #19765 Fix getmempoolancestors RPC result doc (MarcoFalke) -- #19786 Remove label from good first issue template (MarcoFalke) -- #19646 Updated outdated help command for getblocktemplate (jakeleventhal) -- #18817 Document differences in bitcoind and bitcoin-qt locale handling (practicalswift) -- #19870 update PyZMQ install instructions, fix `zmq_sub.py` file permissions (jonatack) -- #19903 Update build-openbsd.md with GUI support (grubles) -- #19241 help: Generate checkpoint height from chainparams (luke-jr) -- #18949 Add CODEOWNERS file to automatically nominate PR reviewers (adamjonas) -- #20014 Mention signet in -help output (hebasto) -- #20015 Added default signet config for linearize script (gr0kchain) -- #19958 Better document features of feelers (naumenkogs) -- #19871 Clarify scope of eviction protection of outbound block-relay peers (ariard) -- #20076 Update and improve files.md (hebasto) -- #20107 Collect release-notes snippets (MarcoFalke) -- #20109 Release notes and followups from 19339 (glozow) -- #20090 Tiny followups to new getpeerinfo connection type field (amitiuttarwar) -- #20152 Update wallet files in files.md (hebasto) -- #19124 Document `ALLOW_HOST_PACKAGES` dependency option (skmcontrib) -- #20271 Document that wallet salvage is experimental (MarcoFalke) -- #20281 Correct getblockstats documentation for `(sw)total_weight` (shesek) -- #20279 release process updates/fixups (jonatack) -- #20238 Missing comments for signet parameters (decryp2kanon) -- #20756 Add missing field (permissions) to the getpeerinfo help (amitiuttarwar) -- #20668 warn that incoming conns are unlikely when not using default ports (adamjonas) -- #19961 tor.md updates (jonatack) -- #19050 Add warning for rest interface limitation (fjahr) -- #19390 doc/REST-interface: Remove stale info (luke-jr) -- #19344 docs: update testgen usage example (Bushstar) Credits ======= Thanks to everyone who directly contributed to this release: -- 10xcryptodev -- Aaron Clauson -- Aaron Hook -- Adam Jonas -- Adam Soltys -- Adam Stein -- Akio Nakamura -- Alex Willmer -- Amir Ghorbanian -- Amiti Uttarwar -- Andrew Chow -- Andrew Toth -- Anthony Fieroni -- Anthony Towns -- Antoine Poinsot -- Antoine Riard -- Ben Carman -- Ben Woosley -- Benoit Verret -- Brian Liotti -- Bushstar -- Calvin Kim -- Carl Dong -- Chris Abrams -- Chris L -- Christopher Coverdale -- codeShark149 -- Cory Fields -- Craig Andrews -- Damian Mee -- Daniel Kraft -- Danny Lee -- David Reikher -- DesWurstes -- Dhruv Mehta -- Duncan Dean -- Elichai Turkel -- Elliott Jin -- Emil Engler -- Ethan Heilman -- eugene -- Fabian Jahr -- fanquake -- Ferdinando M. Ametrano -- freenancial -- furszy -- Gillian Chu -- Gleb Naumenko -- Glenn Willen -- Gloria Zhao -- glowang -- gr0kchain -- Gregory Sanders -- grubles -- gzhao408 -- Harris -- Hennadii Stepanov -- Hugo Nguyen -- Igor Cota -- Ivan Metlushko -- Ivan Vershigora -- Jake Leventhal -- James O'Beirne -- Jeremy Rubin -- jgmorgan -- Jim Posen -- “jkcd” -- jmorgan -- John Newbery -- Johnson Lau -- Jon Atack -- Jonas Schnelli -- Jonathan Schoeller -- João Barbosa -- Justin Moon -- kanon -- Karl-Johan Alm -- Kiminuo -- Kristaps Kaupe -- lontivero -- Luke Dashjr -- Marcin Jachymiak -- MarcoFalke -- Martin Ankerl -- Martin Zumsande -- maskoficarus -- Matt Corallo -- Matthew Zipkin -- MeshCollider -- Miguel Herranz -- MIZUTA Takeshi -- mruddy -- Nadav Ivgi -- Neha Narula -- Nicolas Thumann -- Niklas Gögge -- Nima Yazdanmehr -- nsa -- nthumann -- Oliver Gugger -- pad -- pasta -- Peter Bushnell -- pierrenn -- Pieter Wuille -- practicalswift -- Prayank -- Raúl Martínez (RME) -- RandyMcMillan -- Rene Pickhardt -- Riccardo Masutti -- Robert -- Rod Vagg -- Roy Shao -- Russell Yanofsky -- Saahil Shangle -- sachinkm77 -- saibato -- Samuel Dobson -- sanket1729 -- Sebastian Falbesoner -- Seleme Topuz -- Sishir Giri -- Sjors Provoost -- skmcontrib -- Stepan Snigirev -- Stephan Oeste -- Suhas Daftuar -- t-bast -- Tom Harding -- Torhte Butler -- TrentZ -- Troy Giorshev -- tryphe -- Tyler Chambers -- U-Zyn Chua -- Vasil Dimov -- wiz -- Wladimir J. van der Laan As well as to everyone that helped with translations on [Transifex](https://www.transifex.com/bitcoin/bitcoin/). diff --git a/doc/release-notes/release-notes-0.21.0.md b/doc/release-notes/release-notes-0.21.0.md new file mode 100644 index 0000000000..66aee77643 --- /dev/null +++ b/doc/release-notes/release-notes-0.21.0.md @@ -0,0 +1,1336 @@ +0.21.0 Release Notes +==================== + +Bitcoin Core version 0.21.0 is now available from: + + + +This release includes new features, various bug fixes and performance +improvements, as well as updated translations. + +Please report bugs using the issue tracker at GitHub: + + + +To receive security and update notifications, please subscribe to: + + + +How to Upgrade +============== + +If you are running an older version, shut it down. Wait until it has completely +shut down (which might take a few minutes in some cases), then run the +installer (on Windows) or just copy over `/Applications/Bitcoin-Qt` (on Mac) +or `bitcoind`/`bitcoin-qt` (on Linux). + +Upgrading directly from a version of Bitcoin Core that has reached its EOL is +possible, but it might take some time if the data directory needs to be migrated. Old +wallet versions of Bitcoin Core are generally supported. + +Compatibility +============== + +Bitcoin Core is supported and extensively tested on operating systems +using the Linux kernel, macOS 10.12+, and Windows 7 and newer. Bitcoin +Core should also work on most other Unix-like systems but is not as +frequently tested on them. It is not recommended to use Bitcoin Core on +unsupported systems. + +From Bitcoin Core 0.20.0 onwards, macOS versions earlier than 10.12 are no +longer supported. Additionally, Bitcoin Core does not yet change appearance +when macOS "dark mode" is activated. + +The node's known peers are persisted to disk in a file called `peers.dat`. The +format of this file has been changed in a backwards-incompatible way in order to +accommodate the storage of Tor v3 and other BIP155 addresses. This means that if +the file is modified by 0.21.0 or newer then older versions will not be able to +read it. Those old versions, in the event of a downgrade, will log an error +message "Incorrect keysize in addrman deserialization" and will continue normal +operation as if the file was missing, creating a new empty one. (#19954, #20284) + +Notable changes +=============== + +P2P and network changes +----------------------- + +- The mempool now tracks whether transactions submitted via the wallet or RPCs + have been successfully broadcast. Every 10-15 minutes, the node will try to + announce unbroadcast transactions until a peer requests it via a `getdata` + message or the transaction is removed from the mempool for other reasons. + The node will not track the broadcast status of transactions submitted to the + node using P2P relay. This version reduces the initial broadcast guarantees + for wallet transactions submitted via P2P to a node running the wallet. (#18038) + +- The size of the set of transactions that peers have announced and we consider + for requests has been reduced from 100000 to 5000 (per peer), and further + announcements will be ignored when that limit is reached. If you need to dump + (very) large batches of transactions, exceptions can be made for trusted + peers using the "relay" network permission. For localhost for example it can + be enabled using the command line option `-whitelist=relay@127.0.0.1`. + (#19988) + +- This release adds support for Tor version 3 hidden services, and rumoring them + over the network to other peers using + [BIP155](https://github.com/bitcoin/bips/blob/master/bip-0155.mediawiki). + Version 2 hidden services are still fully supported by Bitcoin Core, but the + Tor network will start + [deprecating](https://blog.torproject.org/v2-deprecation-timeline) them in the + coming months. (#19954) + +- The Tor onion service that is automatically created by setting the + `-listenonion` configuration parameter will now be created as a Tor v3 service + instead of Tor v2. The private key that was used for Tor v2 (if any) will be + left untouched in the `onion_private_key` file in the data directory (see + `-datadir`) and can be removed if not needed. Bitcoin Core will no longer + attempt to read it. The private key for the Tor v3 service will be saved in a + file named `onion_v3_private_key`. To use the deprecated Tor v2 service (not + recommended), the `onion_private_key` can be copied over + `onion_v3_private_key`, e.g. + `cp -f onion_private_key onion_v3_private_key`. (#19954) + +- The client writes a file (`anchors.dat`) at shutdown with the network addresses + of the node’s two outbound block-relay-only peers (so called "anchors"). The + next time the node starts, it reads this file and attempts to reconnect to those + same two peers. This prevents an attacker from using node restarts to trigger a + complete change in peers, which would be something they could use as part of an + eclipse attack. (#17428) + +- This release adds support for serving + [BIP157](https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki) compact + filters to peers on the network when enabled using + `-blockfilterindex=1 -peercfilters=1`. (#16442) + +- This release adds support for signets + ([BIP325](https://github.com/bitcoin/bips/blob/master/bip-0325.mediawiki)) in + addition to the existing mainnet, testnet, and regtest networks. Signets are + centrally-controlled test networks, allowing them to be more predictable + test environments than the older testnet. One public signet is maintained, and + selectable using `-signet`. It is also possible to create personal signets. + (#18267). + +- This release implements + [BIP339](https://github.com/bitcoin/bips/blob/master/bip-0339.mediawiki) + wtxid relay. When negotiated, transactions are announced using their wtxid + instead of their txid. (#18044). + +- This release implements the proposed Taproot consensus rules + ([BIP341](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki) and + [BIP342](https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki)), + without activation on mainnet. Experimentation with Taproot can be done on + signet, where its rules are already active. (#19553) + +Updated RPCs +------------ + +- The `getpeerinfo` RPC has a new `network` field that provides the type of + network ("ipv4", "ipv6", or "onion") that the peer connected through. (#20002) + +- The `getpeerinfo` RPC now has additional `last_block` and `last_transaction` + fields that return the UNIX epoch time of the last block and the last *valid* + transaction received from each peer. (#19731) + +- `getnetworkinfo` now returns two new fields, `connections_in` and + `connections_out`, that provide the number of inbound and outbound peer + connections. These new fields are in addition to the existing `connections` + field, which returns the total number of peer connections. (#19405) + +- Exposed transaction version numbers are now treated as unsigned 32-bit + integers instead of signed 32-bit integers. This matches their treatment in + consensus logic. Versions greater than 2 continue to be non-standard + (matching previous behavior of smaller than 1 or greater than 2 being + non-standard). Note that this includes the `joinpsbt` command, which combines + partially-signed transactions by selecting the highest version number. + (#16525) + +- `getmempoolinfo` now returns an additional `unbroadcastcount` field. The + mempool tracks locally submitted transactions until their initial broadcast + is acknowledged by a peer. This field returns the count of transactions + waiting for acknowledgement. + +- Mempool RPCs such as `getmempoolentry` and `getrawmempool` with + `verbose=true` now return an additional `unbroadcast` field. This indicates + whether initial broadcast of the transaction has been acknowledged by a + peer. `getmempoolancestors` and `getmempooldescendants` are also updated. + +- The `getpeerinfo` RPC no longer returns the `banscore` field unless the configuration + option `-deprecatedrpc=banscore` is used. The `banscore` field will be fully + removed in the next major release. (#19469) + +- The `testmempoolaccept` RPC returns `vsize` and a `fees` object with the `base` fee + if the transaction would pass validation. (#19940) + +- The `getpeerinfo` RPC now returns a `connection_type` field. This indicates + the type of connection established with the peer. It will return one of six + options. For more information, see the `getpeerinfo` help documentation. + (#19725) + +- The `getpeerinfo` RPC no longer returns the `addnode` field by default. This + field will be fully removed in the next major release. It can be accessed + with the configuration option `-deprecatedrpc=getpeerinfo_addnode`. However, + it is recommended to instead use the `connection_type` field (it will return + `manual` when addnode is true). (#19725) + +- The `getpeerinfo` RPC no longer returns the `whitelisted` field by default. + This field will be fully removed in the next major release. It can be accessed + with the configuration option `-deprecatedrpc=getpeerinfo_whitelisted`. However, + it is recommended to instead use the `permissions` field to understand if specific + privileges have been granted to the peer. (#19770) + +- The `walletcreatefundedpsbt` RPC call will now fail with + `Insufficient funds` when inputs are manually selected but are not enough to cover + the outputs and fee. Additional inputs can automatically be added through the + new `add_inputs` option. (#16377) + +- The `fundrawtransaction` RPC now supports `add_inputs` option that when `false` + prevents adding more inputs if necessary and consequently the RPC fails. + +Changes to Wallet or GUI related RPCs can be found in the GUI or Wallet section below. + +New RPCs +-------- + +- The `getindexinfo` RPC returns the actively running indices of the node, + including their current sync status and height. It also accepts an `index_name` + to specify returning the status of that index only. (#19550) + +Build System +------------ + +Updated settings +---------------- + +- The same ZeroMQ notification (e.g. `-zmqpubhashtx=address`) can now be + specified multiple times to publish the same notification to different ZeroMQ + sockets. (#18309) + +- The `-banscore` configuration option, which modified the default threshold for + disconnecting and discouraging misbehaving peers, has been removed as part of + changes in 0.20.1 and in this release to the handling of misbehaving peers. + Refer to "Changes regarding misbehaving peers" in the 0.20.1 release notes for + details. (#19464) + +- The `-debug=db` logging category, which was deprecated in 0.20 and replaced by + `-debug=walletdb` to distinguish it from `coindb`, has been removed. (#19202) + +- A `download` permission has been extracted from the `noban` permission. For + compatibility, `noban` implies the `download` permission, but this may change + in future releases. Refer to the help of the affected settings `-whitebind` + and `-whitelist` for more details. (#19191) + +- Netmasks that contain 1-bits after 0-bits (the 1-bits are not contiguous on + the left side, e.g. 255.0.255.255) are no longer accepted. They are invalid + according to RFC 4632. Netmasks are used in the `-rpcallowip` and `-whitelist` + configuration options and in the `setban` RPC. (#19628) + +- The `-blocksonly` setting now completely disables fee estimation. (#18766) + +Changes to Wallet or GUI related settings can be found in the GUI or Wallet section below. + +Tools and Utilities +------------------- + +- A new `bitcoin-cli -netinfo` command provides a network peer connections + dashboard that displays data from the `getpeerinfo` and `getnetworkinfo` RPCs + in a human-readable format. An optional integer argument from `0` to `4` may + be passed to see increasing levels of detail. (#19643) + +- A new `bitcoin-cli -generate` command, equivalent to RPC `generatenewaddress` + followed by `generatetoaddress`, can generate blocks for command line testing + purposes. This is a client-side version of the former `generate` RPC. See the + help for details. (#19133) + +- The `bitcoin-cli -getinfo` command now displays the wallet name and balance for + each of the loaded wallets when more than one is loaded (e.g. in multiwallet + mode) and a wallet is not specified with `-rpcwallet`. (#18594) + +- The `connections` field of `bitcoin-cli -getinfo` is now expanded to return a JSON + object with `in`, `out` and `total` numbers of peer connections. It previously + returned a single integer value for the total number of peer connections. (#19405) + +New settings +------------ + +- The `startupnotify` option is used to specify a command to + execute when Bitcoin Core has finished with its startup + sequence. (#15367) + +Wallet +------ + +- Backwards compatibility has been dropped for two `getaddressinfo` RPC + deprecations, as notified in the 0.20 release notes. The deprecated `label` + field has been removed as well as the deprecated `labels` behavior of + returning a JSON object containing `name` and `purpose` key-value pairs. Since + 0.20, the `labels` field returns a JSON array of label names. (#19200) + +- To improve wallet privacy, the frequency of wallet rebroadcast attempts is + reduced from approximately once every 15 minutes to once every 12-36 hours. + To maintain a similar level of guarantee for initial broadcast of wallet + transactions, the mempool tracks these transactions as a part of the newly + introduced unbroadcast set. See the "P2P and network changes" section for + more information on the unbroadcast set. (#18038) + +- The `sendtoaddress` and `sendmany` RPCs accept an optional `verbose=True` + argument to also return the fee reason about the sent tx. (#19501) + +- The wallet can create a transaction without change even when the keypool is + empty. Previously it failed. (#17219) + +- The `-salvagewallet` startup option has been removed. A new `salvage` command + has been added to the `bitcoin-wallet` tool which performs the salvage + operations that `-salvagewallet` did. (#18918) + +- A new configuration flag `-maxapsfee` has been added, which sets the max + allowed avoid partial spends (APS) fee. It defaults to 0 (i.e. fee is the + same with and without APS). Setting it to -1 will disable APS, unless + `-avoidpartialspends` is set. (#14582) + +- The wallet will now avoid partial spends (APS) by default, if this does not + result in a difference in fees compared to the non-APS variant. The allowed + fee threshold can be adjusted using the new `-maxapsfee` configuration + option. (#14582) + +- The `createwallet`, `loadwallet`, and `unloadwallet` RPCs now accept + `load_on_startup` options to modify the settings list. Unless these options + are explicitly set to true or false, the list is not modified, so the RPC + methods remain backwards compatible. (#15937) + +- A new `send` RPC with similar syntax to `walletcreatefundedpsbt`, including + support for coin selection and a custom fee rate, is added. The `send` RPC is + experimental and may change in subsequent releases. (#16378) + +- The `estimate_mode` parameter is now case-insensitive in the `bumpfee`, + `fundrawtransaction`, `sendmany`, `sendtoaddress`, `send` and + `walletcreatefundedpsbt` RPCs. (#11413) + +- The `bumpfee` RPC now uses `conf_target` rather than `confTarget` in the + options. (#11413) + +- `fundrawtransaction` and `walletcreatefundedpsbt` when used with the + `lockUnspents` argument now lock manually selected coins, in addition to + automatically selected coins. Note that locked coins are never used in + automatic coin selection, but can still be manually selected. (#18244) + +- The `-zapwallettxes` startup option has been removed and its functionality + removed from the wallet. This option was originally intended to allow for + rescuing wallets which were affected by a malleability attack. More recently, + it has been used in the fee bumping of transactions that did not signal RBF. + This functionality has been superseded with the abandon transaction feature. (#19671) + +- The error code when no wallet is loaded, but a wallet RPC is called, has been + changed from `-32601` (method not found) to `-18` (wallet not found). + (#20101) + +### Automatic wallet creation removed + +Bitcoin Core will no longer automatically create new wallets on startup. It will +load existing wallets specified by `-wallet` options on the command line or in +`bitcoin.conf` or `settings.json` files. And by default it will also load a +top-level unnamed ("") wallet. However, if specified wallets don't exist, +Bitcoin Core will now just log warnings instead of creating new wallets with +new keys and addresses like previous releases did. + +New wallets can be created through the GUI (which has a more prominent create +wallet option), through the `bitcoin-cli createwallet` or `bitcoin-wallet +create` commands, or the `createwallet` RPC. (#15454, #20186) + +### Experimental Descriptor Wallets + +Please note that Descriptor Wallets are still experimental and not all expected functionality +is available. Additionally there may be some bugs and current functions may change in the future. +Bugs and missing functionality can be reported to the [issue tracker](https://github.com/bitcoin/bitcoin/issues). + +0.21 introduces a new type of wallet - Descriptor Wallets. Descriptor Wallets store +scriptPubKey information using output descriptors. This is in contrast to the Legacy Wallet +structure where keys are used to implicitly generate scriptPubKeys and addresses. Because of this +shift to being script based instead of key based, many of the confusing things that Legacy +Wallets do are not possible with Descriptor Wallets. Descriptor Wallets use a definition +of "mine" for scripts which is simpler and more intuitive than that used by Legacy Wallets. +Descriptor Wallets also uses different semantics for watch-only things and imports. + +As Descriptor Wallets are a new type of wallet, their introduction does not affect existing wallets. +Users who already have a Bitcoin Core wallet can continue to use it as they did before without +any change in behavior. Newly created Legacy Wallets (which remains the default type of wallet) will +behave as they did in previous versions of Bitcoin Core. + +The differences between Descriptor Wallets and Legacy Wallets are largely limited to non user facing +things. They are intended to behave similarly except for the import/export and watchonly functionality +as described below. + +#### Creating Descriptor Wallets + +Descriptor wallets are not the default type of wallet. + +In the GUI, a checkbox has been added to the Create Wallet Dialog to indicate that a +Descriptor Wallet should be created. And a `descriptors` option has been added to `createwallet` RPC. +Setting `descriptors` to `true` will create a Descriptor Wallet instead of a Legacy Wallet. + +Without those options being set, a Legacy Wallet will be created instead. + +#### `IsMine` Semantics + +`IsMine` refers to the function used to determine whether a script belongs to the wallet. +This is used to determine whether an output belongs to the wallet. `IsMine` in Legacy Wallets +returns true if the wallet would be able to sign an input that spends an output with that script. +Since keys can be involved in a variety of different scripts, this definition for `IsMine` can +lead to many unexpected scripts being considered part of the wallet. + +With Descriptor Wallets, descriptors explicitly specify the set of scripts that are owned by +the wallet. Since descriptors are deterministic and easily enumerable, users will know exactly +what scripts the wallet will consider to belong to it. Additionally the implementation of `IsMine` +in Descriptor Wallets is far simpler than for Legacy Wallets. Notably, in Legacy Wallets, `IsMine` +allowed for users to take one type of address (e.g. P2PKH), mutate it into another address type +(e.g. P2WPKH), and the wallet would still detect outputs sending to the new address type +even without that address being requested from the wallet. Descriptor Wallets do not +allow for this and will only watch for the addresses that were explicitly requested from the wallet. + +These changes to `IsMine` will make it easier to reason about what scripts the wallet will +actually be watching for in outputs. However for the vast majority of users, this change is +largely transparent and will not have noticeable effect. + +#### Imports and Exports + +In Legacy Wallets, raw scripts and keys could be imported to the wallet. Those imported scripts +and keys are treated separately from the keys generated by the wallet. This complicates the `IsMine` +logic as it has to distinguish between spendable and watchonly. + +Descriptor Wallets handle importing scripts and keys differently. Only complete descriptors can be +imported. These descriptors are then added to the wallet as if it were a descriptor generated by +the wallet itself. This simplifies the `IsMine` logic so that it no longer has to distinguish +between spendable and watchonly. As such, the watchonly model for Descriptor Wallets is also +different and described in more detail in the next section. + +To import into a Descriptor Wallet, a new `importdescriptors` RPC has been added that uses a syntax +similar to that of `importmulti`. + +As Legacy Wallets and Descriptor Wallets use different mechanisms for storing and importing scripts and keys +the existing import RPCs have been disabled for descriptor wallets. +New export RPCs for Descriptor Wallets have not yet been added. + +The following RPCs are disabled for Descriptor Wallets: + +* `importprivkey` +* `importpubkey` +* `importaddress` +* `importwallet` +* `dumpprivkey` +* `dumpwallet` +* `importmulti` +* `addmultisigaddress` +* `sethdseed` + +#### Watchonly Wallets + +A Legacy Wallet contains both private keys and scripts that were being watched. +Those watched scripts would not contribute to your normal balance. In order to see the watchonly +balance and to use watchonly things in transactions, an `include_watchonly` option was added +to many RPCs that would allow users to do that. However it is easy to forget to include this option. + +Descriptor Wallets move to a per-wallet watchonly model. Instead an entire wallet is considered to be +watchonly depending on whether it was created with private keys disabled. This eliminates the need +to distinguish between things that are watchonly and things that are not within a wallet itself. + +This change does have a caveat. If a Descriptor Wallet with private keys *enabled* has +a multiple key descriptor without all of the private keys (e.g. `multi(...)` with only one private key), +then the wallet will fail to sign and broadcast transactions. Such wallets would need to use the PSBT +workflow but the typical GUI Send, `sendtoaddress`, etc. workflows would still be available, just +non-functional. + +This issue is worsened if the wallet contains both single key (e.g. `wpkh(...)`) descriptors and such +multiple key descriptors as some transactions could be signed and broadcast and others not. This is +due to some transactions containing only single key inputs, while others would contain both single +key and multiple key inputs, depending on which are available and how the coin selection algorithm +selects inputs. However this is not considered to be a supported use case; multisigs +should be in their own wallets which do not already have descriptors. Although users cannot export +descriptors with private keys for now as explained earlier. + +#### BIP 44/49/84 Support + +The change to using descriptors changes the default derivation paths used by Bitcoin Core +to adhere to BIP 44/49/84. Descriptors with different derivation paths can be imported without +issue. + +#### SQLite Database Backend + +Descriptor wallets use SQLite for the wallet file instead of the Berkeley DB used in legacy wallets. +This will break compatibility with any existing tooling that operates on wallets, however compatibility +was already being broken by the move to descriptors. + +### Wallet RPC changes + +- The `upgradewallet` RPC replaces the `-upgradewallet` command line option. + (#15761) + +- The `settxfee` RPC will fail if the fee was set higher than the `-maxtxfee` + command line setting. The wallet will already fail to create transactions + with fees higher than `-maxtxfee`. (#18467) + +- A new `fee_rate` parameter/option denominated in satoshis per vbyte (sat/vB) + is introduced to the `sendtoaddress`, `sendmany`, `fundrawtransaction` and + `walletcreatefundedpsbt` RPCs as well as to the experimental new `send` + RPC. The legacy `feeRate` option in `fundrawtransaction` and + `walletcreatefundedpsbt` still exists for setting a fee rate in BTC per 1,000 + vbytes (BTC/kvB), but it is expected to be deprecated soon to avoid + confusion. For these RPCs, the fee rate error message is updated from BTC/kB + to sat/vB and the help documentation in BTC/kB is updated to BTC/kvB. The + `send` and `sendtoaddress` RPC examples are updated to aid users in creating + transactions with explicit fee rates. (#20305, #11413) + +- The `bumpfee` RPC `fee_rate` option is changed from BTC/kvB to sat/vB and the + help documentation is updated. Users are warned that this is a breaking API + change, but it should be relatively benign: the large (100,000 times) + difference between BTC/kvB and sat/vB units means that a transaction with a + fee rate mistakenly calculated in BTC/kvB rather than sat/vB should raise an + error due to the fee rate being set too low. In the worst case, the + transaction may send at 1 sat/vB, but as Replace-by-Fee (BIP125 RBF) is active + by default when an explicit fee rate is used, the transaction fee can be + bumped. (#20305) + +GUI changes +----------- + +- Wallets created or loaded in the GUI will now be automatically loaded on + startup, so they don't need to be manually reloaded next time Bitcoin Core is + started. The list of wallets to load on startup is stored in + `\/settings.json` and augments any command line or `bitcoin.conf` + `-wallet=` settings that specify more wallets to load. Wallets that are + unloaded in the GUI get removed from the settings list so they won't load + again automatically next startup. (#19754) + +- The GUI Peers window no longer displays a "Ban Score" field. This is part of + changes in 0.20.1 and in this release to the handling of misbehaving + peers. Refer to "Changes regarding misbehaving peers" in the 0.20.1 release + notes for details. (#19512) + +Low-level changes +================= + +RPC +--- + +- To make RPC `sendtoaddress` more consistent with `sendmany` the following error + `sendtoaddress` codes were changed from `-4` to `-6`: + - Insufficient funds + - Fee estimation failed + - Transaction has too long of a mempool chain + +- The `sendrawtransaction` error code for exceeding `maxfeerate` has been changed from + `-26` to `-25`. The error string has been changed from "absurdly-high-fee" to + "Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)." The + `testmempoolaccept` RPC returns `max-fee-exceeded` rather than `absurdly-high-fee` + as the `reject-reason`. (#19339) + +- To make wallet and rawtransaction RPCs more consistent, the error message for + exceeding maximum feerate has been changed to "Fee exceeds maximum configured by user + (e.g. -maxtxfee, maxfeerate)." (#19339) + +Tests +----- + +- The BIP 325 default signet can be enabled by the `-chain=signet` or `-signet` + setting. The settings `-signetchallenge` and `-signetseednode` allow + enabling a custom signet. + +- The `generateblock` RPC allows testers using regtest mode to + generate blocks that consist of a custom set of transactions. (#17693) + +0.21.0 change log +================= + +### Consensus +- #18267 BIP-325: Signet (kallewoof) +- #20016 uint256: 1 is a constant (ajtowns) +- #20006 Fix misleading error message: Clean stack rule (sanket1729) +- #19953 Implement BIP 340-342 validation (Schnorr/taproot/tapscript) (sipa) +- #20169 Taproot follow-up: Make ComputeEntrySchnorr and ComputeEntryECDSA const to clarify contract (practicalswift) + +### Policy +- #18766 Disable fee estimation in blocksonly mode (darosior) +- #19630 Cleanup fee estimation code (darosior) +- #20165 Only relay Taproot spends if next block has it active (sipa) + +### Mining +- #17946 Fix GBT: Restore "!segwit" and "csv" to "rules" key (luke-jr) + +### Privacy +- #16432 Add privacy to the Overview page (hebasto) +- #18861 Do not answer GETDATA for to-be-announced tx (sipa) +- #18038 Mempool tracks locally submitted transactions to improve wallet privacy (amitiuttarwar) +- #19109 Only allow getdata of recently announced invs (sipa) + +### Block and transaction handling +- #17737 Add ChainstateManager, remove BlockManager global (jamesob) +- #18960 indexes: Add compact block filter headers cache (jnewbery) +- #13204 Faster sigcache nonce (JeremyRubin) +- #19088 Use std::chrono throughout some validation functions (fanquake) +- #19142 Make VerifyDB level 4 interruptible (MarcoFalke) +- #17994 Flush undo files after last block write (kallewoof) +- #18990 log: Properly log txs rejected from mempool (MarcoFalke) +- #18984 Remove unnecessary input blockfile SetPos (dgenr8) +- #19526 log: Avoid treating remote misbehvior as local system error (MarcoFalke) +- #18044 Use wtxid for transaction relay (sdaftuar) +- #18637 coins: allow cache resize after init (jamesob) +- #19854 Avoid locking CTxMemPool::cs recursively in simple cases (hebasto) +- #19478 Remove CTxMempool::mapLinks data structure member (JeremyRubin) +- #19927 Reduce direct `g_chainman` usage (dongcarl) +- #19898 log: print unexpected version warning in validation log category (n-thumann) +- #20036 signet: Add assumed values for default signet (MarcoFalke) +- #20048 chainparams: do not log signet startup messages for other chains (jonatack) +- #19339 re-delegate absurd fee checking from mempool to clients (glozow) +- #20035 signet: Fix uninitialized read in validation (MarcoFalke) +- #20157 Bugfix: chainparams: Add missing (always enabled) Taproot deployment for Signet (luke-jr) +- #20263 Update assumed chain params (MarcoFalke) +- #20372 Avoid signed integer overflow when loading a mempool.dat file with a malformed time field (practicalswift) +- #18621 script: Disallow silent bool -> cscript conversion (MarcoFalke) +- #18612, #18732 script: Remove undocumented and unused operator+ (MarcoFalke) +- #19317 Add a left-justified width field to `log2_work` component for a uniform debug.log output (jamesgmorgan) + +### P2P protocol and network code +- #18544 Limit BIP37 filter lifespan (active between `filterload`..`filterclear`) (theStack) +- #18806 Remove is{Empty,Full} flags from CBloomFilter, clarify CVE fix (theStack) +- #18512 Improve asmap checks and add sanity check (sipa) +- #18877 Serve cfcheckpt requests (jnewbery) +- #18895 Unbroadcast followups: rpcs, nLastResend, mempool sanity check (gzhao408) +- #19010 net processing: Add support for `getcfheaders` (jnewbery) +- #16939 Delay querying DNS seeds (ajtowns) +- #18807 Unbroadcast follow-ups (amitiuttarwar) +- #19044 Add support for getcfilters (jnewbery) +- #19084 improve code documentation for dns seed behaviour (ajtowns) +- #19260 disconnect peers that send filterclear + update existing filter msg disconnect logic (gzhao408) +- #19284 Add seed.bitcoin.wiz.biz to DNS seeds (wiz) +- #19322 split PushInventory() (jnewbery) +- #19204 Reduce inv traffic during IBD (MarcoFalke) +- #19470 banlist: log post-swept banlist size at startup (fanquake) +- #19191 Extract download permission from noban (MarcoFalke) +- #14033 Drop `CADDR_TIME_VERSION` checks now that `MIN_PEER_PROTO_VERSION` is greater (Empact) +- #19464 net, rpc: remove -banscore option, deprecate banscore in getpeerinfo (jonatack) +- #19514 [net/net processing] check banman pointer before dereferencing (jnewbery) +- #19512 banscore updates to gui, tests, release notes (jonatack) +- #19360 improve encapsulation of CNetAddr (vasild) +- #19217 disambiguate block-relay-only variable names from blocksonly variables (glowang) +- #19473 Add -networkactive option (hebasto) +- #19472 [net processing] Reduce `cs_main` scope in MaybeDiscourageAndDisconnect() (jnewbery) +- #19583 clean up Misbehaving() (jnewbery) +- #19534 save the network type explicitly in CNetAddr (vasild) +- #19569 Enable fetching of orphan parents from wtxid peers (sipa) +- #18991 Cache responses to GETADDR to prevent topology leaks (naumenkogs) +- #19596 Deduplicate parent txid loop of requested transactions and missing parents of orphan transactions (sdaftuar) +- #19316 Cleanup logic around connection types (amitiuttarwar) +- #19070 Signal support for compact block filters with `NODE_COMPACT_FILTERS` (jnewbery) +- #19705 Shrink CAddress from 48 to 40 bytes on x64 (vasild) +- #19704 Move ProcessMessage() to PeerLogicValidation (jnewbery) +- #19628 Change CNetAddr::ip to have flexible size (vasild) +- #19797 Remove old check for 3-byte shifted IP addresses from pre-0.2.9 nodes (#19797) +- #19607 Add Peer struct for per-peer data in net processing (jnewbery) +- #19857 improve nLastBlockTime and nLastTXTime documentation (jonatack) +- #19724 Cleanup connection types- followups (amitiuttarwar) +- #19670 Protect localhost and block-relay-only peers from eviction (sdaftuar) +- #19728 Increase the ip address relay branching factor for unreachable networks (sipa) +- #19879 Miscellaneous wtxid followups (amitiuttarwar) +- #19697 Improvements on ADDR caching (naumenkogs) +- #17785 Unify Send and Receive protocol versions (hebasto) +- #19845 CNetAddr: add support to (un)serialize as ADDRv2 (vasild) +- #19107 Move all header verification into the network layer, extend logging (troygiorshev) +- #20003 Exit with error message if -proxy is specified without arguments (instead of continuing without proxy server) (practicalswift) +- #19991 Use alternative port for incoming Tor connections (hebasto) +- #19723 Ignore unknown messages before VERACK (sdaftuar) +- #19954 Complete the BIP155 implementation and upgrade to TORv3 (vasild) +- #20119 BIP155 follow-ups (sipa) +- #19988 Overhaul transaction request logic (sipa) +- #17428 Try to preserve outbound block-relay-only connections during restart (hebasto) +- #19911 Guard `vRecvGetData` with `cs_vRecv` and `orphan_work_set` with `g_cs_orphans` (narula) +- #19753 Don't add AlreadyHave transactions to recentRejects (troygiorshev) +- #20187 Test-before-evict bugfix and improvements for block-relay-only peers (sdaftuar) +- #20237 Hardcoded seeds update for 0.21 (laanwj) +- #20212 Fix output of peer address in version message (vasild) +- #20284 Ensure old versions don't parse peers.dat (vasild) +- #20405 Avoid calculating onion address checksum when version is not 3 (lontivero) +- #20564 Don't send 'sendaddrv2' to pre-70016 software, and send before 'verack' (sipa) +- #20660 Move signet onion seed from v2 to v3 (Sjors) + +### Wallet +- #18262 Exit selection when `best_waste` is 0 (achow101) +- #17824 Prefer full destination groups in coin selection (fjahr) +- #17219 Allow transaction without change if keypool is empty (Sjors) +- #15761 Replace -upgradewallet startup option with upgradewallet RPC (achow101) +- #18671 Add BlockUntilSyncedToCurrentChain to dumpwallet (MarcoFalke) +- #16528 Native Descriptor Wallets using DescriptorScriptPubKeyMan (achow101) +- #18777 Recommend absolute path for dumpwallet (MarcoFalke) +- #16426 Reverse `cs_main`, `cs_wallet` lock order and reduce `cs_main` locking (ariard) +- #18699 Avoid translating RPC errors (MarcoFalke) +- #18782 Make sure no DescriptorScriptPubKeyMan or WalletDescriptor members are left uninitialized after construction (practicalswift) +- #9381 Remove CWalletTx merging logic from AddToWallet (ryanofsky) +- #16946 Include a checksum of encrypted private keys (achow101) +- #17681 Keep inactive seeds after sethdseed and derive keys from them as needed (achow101) +- #18918 Move salvagewallet into wallettool (achow101) +- #14988 Fix for confirmed column in csv export for payment to self transactions (benthecarman) +- #18275 Error if an explicit fee rate was given but the needed fee rate differed (kallewoof) +- #19054 Skip hdKeypath of 'm' when determining inactive hd seeds (achow101) +- #17938 Disallow automatic conversion between disparate hash types (Empact) +- #19237 Check size after unserializing a pubkey (elichai) +- #11413 sendtoaddress/sendmany: Add explicit feerate option (kallewoof) +- #18850 Fix ZapSelectTx to sync wallet spends (bvbfan) +- #18923 Never schedule MaybeCompactWalletDB when `-flushwallet` is off (MarcoFalke) +- #19441 walletdb: Don't reinitialize desc cache with multiple cache entries (achow101) +- #18907 walletdb: Don't remove database transaction logs and instead error (achow101) +- #19334 Introduce WalletDatabase abstract class (achow101) +- #19335 Cleanup and separate BerkeleyDatabase and BerkeleyBatch (achow101) +- #19102 Introduce and use DummyDatabase instead of dummy BerkeleyDatabase (achow101) +- #19568 Wallet should not override signing errors (fjahr) +- #17204 Do not turn `OP_1NEGATE` in scriptSig into `0x0181` in signing code (sipa) (meshcollider) +- #19457 Cleanup wallettool salvage and walletdb extraneous declarations (achow101) +- #15937 Add loadwallet and createwallet `load_on_startup` options (ryanofsky) +- #16841 Replace GetScriptForWitness with GetScriptForDestination (meshcollider) +- #14582 always do avoid partial spends if fees are within a specified range (kallewoof) +- #19743 -maxapsfee follow-up (kallewoof) +- #19289 GetWalletTx and IsMine require `cs_wallet` lock (promag) +- #19671 Remove -zapwallettxes (achow101) +- #19805 Avoid deserializing unused records when salvaging (achow101) +- #19754 wallet, gui: Reload previously loaded wallets on startup (achow101) +- #19738 Avoid multiple BerkeleyBatch in DelAddressBook (promag) +- #19919 bugfix: make LoadWallet assigns status always (AkioNak) +- #16378 The ultimate send RPC (Sjors) +- #15454 Remove the automatic creation and loading of the default wallet (achow101) +- #19501 `send*` RPCs in the wallet returns the "fee reason" (stackman27) +- #20130 Remove db mode string (S3RK) +- #19077 Add sqlite as an alternative wallet database and use it for new descriptor wallets (achow101) +- #20125 Expose database format in getwalletinfo (promag) +- #20198 Show name, format and if uses descriptors in bitcoin-wallet tool (jonasschnelli) +- #20216 Fix buffer over-read in SQLite file magic check (theStack) +- #20186 Make -wallet setting not create wallets (ryanofsky) +- #20230 Fix bug when just created encrypted wallet cannot get address (hebasto) +- #20282 Change `upgradewallet` return type to be an object (jnewbery) +- #20220 Explicit fee rate follow-ups/fixes for 0.21 (jonatack) +- #20199 Ignore (but warn) on duplicate -wallet parameters (jonasschnelli) +- #20324 Set DatabaseStatus::SUCCESS in MakeSQLiteDatabase (MarcoFalke) +- #20266 Fix change detection of imported internal descriptors (achow101) +- #20153 Do not import a descriptor with hardened derivations into a watch-only wallet (S3RK) +- #20344 Fix scanning progress calculation for single block range (theStack) +- #19502 Bugfix: Wallet: Soft-fail exceptions within ListWalletDir file checks (luke-jr) +- #20378 Fix potential division by 0 in WalletLogPrintf (jonasschnelli) +- #18836 Upgradewallet fixes and additional tests (achow101) +- #20139 Do not return warnings from UpgradeWallet() (stackman27) +- #20305 Introduce `fee_rate` sat/vB param/option (jonatack) +- #20426 Allow zero-fee fundrawtransaction/walletcreatefundedpsbt and other fixes (jonatack) +- #20573 wallet, bugfix: allow send with string `fee_rate` amounts (jonatack) + +### RPC and other APIs +- #18574 cli: Call getbalances.ismine.trusted instead of getwalletinfo.balance (jonatack) +- #17693 Add `generateblock` to mine a custom set of transactions (andrewtoth) +- #18495 Remove deprecated migration code (vasild) +- #18493 Remove deprecated "size" from mempool txs (vasild) +- #18467 Improve documentation and return value of settxfee (fjahr) +- #18607 Fix named arguments in documentation (MarcoFalke) +- #17831 doc: Fix and extend getblockstats examples (asoltys) +- #18785 Prevent valgrind false positive in `rest_blockhash_by_height` (ryanofsky) +- #18999 log: Remove "No rpcpassword set" from logs (MarcoFalke) +- #19006 Avoid crash when `g_thread_http` was never started (MarcoFalke) +- #18594 cli: Display multiwallet balances in -getinfo (jonatack) +- #19056 Make gettxoutsetinfo/GetUTXOStats interruptible (MarcoFalke) +- #19112 Remove special case for unknown service flags (MarcoFalke) +- #18826 Expose txinwitness for coinbase in JSON form from RPC (rvagg) +- #19282 Rephrase generatetoaddress help, and use `PACKAGE_NAME` (luke-jr) +- #16377 don't automatically append inputs in walletcreatefundedpsbt (Sjors) +- #19200 Remove deprecated getaddressinfo fields (jonatack) +- #19133 rpc, cli, test: add bitcoin-cli -generate command (jonatack) +- #19469 Deprecate banscore field in getpeerinfo (jonatack) +- #16525 Dump transaction version as an unsigned integer in RPC/TxToUniv (TheBlueMatt) +- #19555 Deduplicate WriteHDKeypath() used in decodepsbt (theStack) +- #19589 Avoid useless mempool query in gettxoutproof (MarcoFalke) +- #19585 RPCResult Type of MempoolEntryDescription should be OBJ (stylesuxx) +- #19634 Document getwalletinfo's `unlocked_until` field as optional (justinmoon) +- #19658 Allow RPC to fetch all addrman records and add records to addrman (jnewbery) +- #19696 Fix addnode remove command error (fjahr) +- #18654 Separate bumpfee's psbt creation function into psbtbumpfee (achow101) +- #19655 Catch listsinceblock `target_confirmations` exceeding block count (adaminsky) +- #19644 Document returned error fields as optional if applicable (theStack) +- #19455 rpc generate: print useful help and error message (jonatack) +- #19550 Add listindices RPC (fjahr) +- #19169 Validate provided keys for `query_options` parameter in listunspent (PastaPastaPasta) +- #18244 fundrawtransaction and walletcreatefundedpsbt also lock manually selected coins (Sjors) +- #14687 zmq: Enable TCP keepalive (mruddy) +- #19405 Add network in/out connections to `getnetworkinfo` and `-getinfo` (jonatack) +- #19878 rawtransaction: Fix argument in combinerawtransaction help message (pinheadmz) +- #19940 Return fee and vsize from testmempoolaccept (gzhao408) +- #13686 zmq: Small cleanups in the ZMQ code (domob1812) +- #19386, #19528, #19717, #19849, #19994 Assert that RPCArg names are equal to CRPCCommand ones (MarcoFalke) +- #19725 Add connection type to getpeerinfo, improve logs (amitiuttarwar) +- #19969 Send RPC bug fix and touch-ups (Sjors) +- #18309 zmq: Add support to listen on multiple interfaces (n-thumann) +- #20055 Set HTTP Content-Type in bitcoin-cli (laanwj) +- #19956 Improve invalid vout value rpc error message (n1rna) +- #20101 Change no wallet loaded message to be clearer (achow101) +- #19998 Add `via_tor` to `getpeerinfo` output (hebasto) +- #19770 getpeerinfo: Deprecate "whitelisted" field (replaced by "permissions") (luke-jr) +- #20120 net, rpc, test, bugfix: update GetNetworkName, GetNetworksInfo, regression tests (jonatack) +- #20595 Improve heuristic hex transaction decoding (sipa) +- #20731 Add missing description of vout in getrawtransaction help text (benthecarman) +- #19328 Add gettxoutsetinfo `hash_type` option (fjahr) +- #19731 Expose nLastBlockTime/nLastTXTime as last `block/last_transaction` in getpeerinfo (jonatack) +- #19572 zmq: Create "sequence" notifier, enabling client-side mempool tracking (instagibbs) +- #20002 Expose peer network in getpeerinfo; simplify/improve -netinfo (jonatack) + +### GUI +- #17905 Avoid redundant tx status updates (ryanofsky) +- #18646 Use `PACKAGE_NAME` in exception message (fanquake) +- #17509 Save and load PSBT (Sjors) +- #18769 Remove bug fix for Qt < 5.5 (10xcryptodev) +- #15768 Add close window shortcut (IPGlider) +- #16224 Bilingual GUI error messages (hebasto) +- #18922 Do not translate InitWarning messages in debug.log (hebasto) +- #18152 Use NotificationStatus enum for signals to GUI (hebasto) +- #18587 Avoid wallet tryGetBalances calls in WalletModel::pollBalanceChanged (ryanofsky) +- #17597 Fix height of QR-less ReceiveRequestDialog (hebasto) +- #17918 Hide non PKHash-Addresses in signing address book (emilengler) +- #17956 Disable unavailable context menu items in transactions tab (kristapsk) +- #17968 Ensure that ModalOverlay is resized properly (hebasto) +- #17993 Balance/TxStatus polling update based on last block hash (furszy) +- #18424 Use parent-child relation to manage lifetime of OptionsModel object (hebasto) +- #18452 Fix shutdown when `waitfor*` cmds are called from RPC console (hebasto) +- #15202 Add Close All Wallets action (promag) +- #19132 lock `cs_main`, `m_cached_tip_mutex` in that order (vasild) +- #18898 Display warnings as rich text (hebasto) +- #19231 add missing translation.h include to fix build (fanquake) +- #18027 "PSBT Operations" dialog (gwillen) +- #19256 Change combiner for signals to `optional_last_value` (fanquake) +- #18896 Reset toolbar after all wallets are closed (hebasto) +- #18993 increase console command max length (10xcryptodev) +- #19323 Fix regression in *txoutset* in GUI console (hebasto) +- #19210 Get rid of cursor in out-of-focus labels (hebasto) +- #19011 Reduce `cs_main` lock accumulation during GUI startup (jonasschnelli) +- #19844 Remove usage of boost::bind (fanquake) +- #20479 Fix QPainter non-determinism on macOS (0.21 backport) (laanwj) +- gui#6 Do not truncate node flag strings in debugwindow peers details tab (Saibato) +- gui#8 Fix regression in TransactionTableModel (hebasto) +- gui#17 doc: Remove outdated comment in TransactionTablePriv (MarcoFalke) +- gui#20 Wrap tooltips in the intro window (hebasto) +- gui#30 Disable the main window toolbar when the modal overlay is shown (hebasto) +- gui#34 Show permissions instead of whitelisted (laanwj) +- gui#35 Parse params directly instead of through node (ryanofsky) +- gui#39 Add visual accenting for the 'Create new receiving address' button (hebasto) +- gui#40 Clarify block height label (hebasto) +- gui#43 bugfix: Call setWalletActionsEnabled(true) only for the first wallet (hebasto) +- gui#97 Relax GUI freezes during IBD (jonasschnelli) +- gui#71 Fix visual quality of text in QR image (hebasto) +- gui#96 Slight improve create wallet dialog (Sjors) +- gui#102 Fix SplashScreen crash when run with -disablewallet (hebasto) +- gui#116 Fix unreasonable default size of the main window without loaded wallets (hebasto) +- gui#120 Fix multiwallet transaction notifications (promag) + +### Build system +- #18504 Drop bitcoin-tx and bitcoin-wallet dependencies on libevent (ryanofsky) +- #18586 Bump gitian descriptors to 0.21 (laanwj) +- #17595 guix: Enable building for `x86_64-w64-mingw32` target (dongcarl) +- #17929 add linker optimisation flags to gitian & guix (Linux) (fanquake) +- #18556 Drop make dist in gitian builds (hebasto) +- #18088 ensure we aren't using GNU extensions (fanquake) +- #18741 guix: Make source tarball using git-archive (dongcarl) +- #18843 warn on potentially uninitialized reads (vasild) +- #17874 make linker checks more robust (fanquake) +- #18535 remove -Qunused-arguments workaround for clang + ccache (fanquake) +- #18743 Add --sysroot option to mac os native compile flags (ryanofsky) +- #18216 test, build: Enable -Werror=sign-compare (Empact) +- #18928 don't pass -w when building for Windows (fanquake) +- #16710 Enable -Wsuggest-override if available (hebasto) +- #18738 Suppress -Wdeprecated-copy warnings (hebasto) +- #18862 Remove fdelt_chk back-compat code and sanity check (fanquake) +- #18887 enable -Werror=gnu (vasild) +- #18956 enforce minimum required Windows version (7) (fanquake) +- #18958 guix: Make V=1 more powerful for debugging (dongcarl) +- #18677 Multiprocess build support (ryanofsky) +- #19094 Only allow ASCII identifiers (laanwj) +- #18820 Propagate well-known vars into depends (dongcarl) +- #19173 turn on --enable-c++17 by --enable-fuzz (vasild) +- #18297 Use pkg-config in BITCOIN_QT_CONFIGURE for all hosts including Windows (hebasto) +- #19301 don't warn when doxygen isn't found (fanquake) +- #19240 macOS toolchain simplification and bump (dongcarl) +- #19356 Fix search for brew-installed BDB 4 on OS X (gwillen) +- #19394 Remove unused `RES_IMAGES` (Bushstar) +- #19403 improve `__builtin_clz*` detection (fanquake) +- #19375 target Windows 7 when building libevent and fix ipv6 usage (fanquake) +- #19331 Do not include server symbols in wallet (MarcoFalke) +- #19257 remove BIP70 configure option (fanquake) +- #18288 Add MemorySanitizer (MSan) in Travis to detect use of uninitialized memory (practicalswift) +- #18307 Require pkg-config for all of the hosts (hebasto) +- #19445 Update msvc build to use ISO standard C++17 (sipsorcery) +- #18882 fix -Wformat-security check when compiling with GCC (fanquake) +- #17919 Allow building with system clang (dongcarl) +- #19553 pass -fcommon when building genisoimage (fanquake) +- #19565 call `AC_PATH_TOOL` for dsymutil in macOS cross-compile (fanquake) +- #19530 build LTO support into Apple's ld64 (theuni) +- #19525 add -Wl,-z,separate-code to hardening flags (fanquake) +- #19667 set minimum required Boost to 1.58.0 (fanquake) +- #19672 make clean removes .gcda and .gcno files from fuzz directory (Crypt-iQ) +- #19622 Drop ancient hack in gitian-linux descriptor (hebasto) +- #19688 Add support for llvm-cov (hebasto) +- #19718 Add missed gcov files to 'make clean' (hebasto) +- #19719 Add Werror=range-loop-analysis (MarcoFalke) +- #19015 Enable some commonly enabled compiler diagnostics (practicalswift) +- #19689 build, qt: Add Qt version checking (hebasto) +- #17396 modest Android improvements (icota) +- #18405 Drop all of the ZeroMQ patches (hebasto) +- #15704 Move Win32 defines to configure.ac to ensure they are globally defined (luke-jr) +- #19761 improve sed robustness by not using sed (fanquake) +- #19758 Drop deprecated and unused `GUARDED_VAR` and `PT_GUARDED_VAR` annotations (hebasto) +- #18921 add stack-clash and control-flow protection options to hardening flags (fanquake) +- #19803 Bugfix: Define and use `HAVE_FDATASYNC` correctly outside LevelDB (luke-jr) +- #19685 CMake invocation cleanup (dongcarl) +- #19861 add /usr/local/ to `LCOV_FILTER_PATTERN` for macOS builds (Crypt-iQ) +- #19916 allow user to specify `DIR_FUZZ_SEED_CORPUS` for `cov_fuzz` (Crypt-iQ) +- #19944 Update secp256k1 subtree (including BIP340 support) (sipa) +- #19558 Split pthread flags out of ldflags and dont use when building libconsensus (fanquake) +- #19959 patch qt libpng to fix powerpc build (fanquake) +- #19868 Fix target name (hebasto) +- #19960 The vcpkg tool has introduced a proper way to use manifests (sipsorcery) +- #20065 fuzz: Configure check for main function (MarcoFalke) +- #18750 Optionally skip external warnings (vasild) +- #20147 Update libsecp256k1 (endomorphism, test improvements) (sipa) +- #20156 Make sqlite support optional (compile-time) (luke-jr) +- #20318 Ensure source tarball has leading directory name (MarcoFalke) +- #20447 Patch `qt_intersect_spans` to avoid non-deterministic behavior in LLVM 8 (achow101) +- #20505 Avoid secp256k1.h include from system (dergoegge) +- #20527 Do not ignore Homebrew's SQLite on macOS (hebasto) +- #20478 Don't set BDB flags when configuring without (jonasschnelli) +- #20563 Check that Homebrew's berkeley-db4 package is actually installed (hebasto) +- #19493 Fix clang build on Mac (bvbfan) + +### Tests and QA +- #18593 Complete impl. of `msg_merkleblock` and `wait_for_merkleblock` (theStack) +- #18609 Remove REJECT message code (hebasto) +- #18584 Check that the version message does not leak the local address (MarcoFalke) +- #18597 Extend `wallet_dump` test to cover comments (MarcoFalke) +- #18596 Try once more when RPC connection fails on Windows (MarcoFalke) +- #18451 shift coverage from getunconfirmedbalance to getbalances (jonatack) +- #18631 appveyor: Disable functional tests for now (MarcoFalke) +- #18628 Add various low-level p2p tests (MarcoFalke) +- #18615 Avoid accessing free'd memory in `validation_chainstatemanager_tests` (MarcoFalke) +- #18571 fuzz: Disable debug log file (MarcoFalke) +- #18653 add coverage for bitcoin-cli -rpcwait (jonatack) +- #18660 Verify findCommonAncestor always initializes outputs (ryanofsky) +- #17669 Have coins simulation test also use CCoinsViewDB (jamesob) +- #18662 Replace gArgs with local argsman in bench (MarcoFalke) +- #18641 Create cached blocks not in the future (MarcoFalke) +- #18682 fuzz: `http_request` workaround for libevent < 2.1.1 (theStack) +- #18692 Bump timeout in `wallet_import_rescan` (MarcoFalke) +- #18695 Replace boost::mutex with std::mutex (hebasto) +- #18633 Properly raise FailedToStartError when rpc shutdown before warmup finished (MarcoFalke) +- #18675 Don't initialize PrecomputedTransactionData in txvalidationcache tests (jnewbery) +- #18691 Add `wait_for_cookie_credentials()` to framework for rpcwait tests (jonatack) +- #18672 Add further BIP37 size limit checks to `p2p_filter.py` (theStack) +- #18721 Fix linter issue (hebasto) +- #18384 More specific `feature_segwit` test error messages and fixing incorrect comments (gzhao408) +- #18575 bench: Remove requirement that all benches use same testing setup (MarcoFalke) +- #18690 Check object hashes in `wait_for_getdata` (robot-visions) +- #18712 display command line options passed to `send_cli()` in debug log (jonatack) +- #18745 Check submitblock return values (MarcoFalke) +- #18756 Use `wait_for_getdata()` in `p2p_compactblocks.py` (theStack) +- #18724 Add coverage for -rpcwallet cli option (jonatack) +- #18754 bench: Add caddrman benchmarks (vasild) +- #18585 Use zero-argument super() shortcut (Python 3.0+) (theStack) +- #18688 fuzz: Run in parallel (MarcoFalke) +- #18770 Remove raw-tx byte juggling in `mempool_reorg` (MarcoFalke) +- #18805 Add missing `sync_all` to `wallet_importdescriptors.py` (achow101) +- #18759 bench: Start nodes with -nodebuglogfile (MarcoFalke) +- #18774 Added test for upgradewallet RPC (brakmic) +- #18485 Add `mempool_updatefromblock.py` (hebasto) +- #18727 Add CreateWalletFromFile test (ryanofsky) +- #18726 Check misbehavior more independently in `p2p_filter.py` (robot-visions) +- #18825 Fix message for `ECC_InitSanityCheck` test (fanquake) +- #18576 Use unittest for `test_framework` unit testing (gzhao408) +- #18828 Strip down previous releases boilerplate (MarcoFalke) +- #18617 Add factor option to adjust test timeouts (brakmic) +- #18855 `feature_backwards_compatibility.py` test downgrade after upgrade (achow101) +- #18864 Add v0.16.3 backwards compatibility test, bump v0.19.0.1 to v0.19.1 (Sjors) +- #18917 fuzz: Fix vector size problem in system fuzzer (brakmic) +- #18901 fuzz: use std::optional for `sep_pos_opt` variable (brakmic) +- #18888 Remove RPCOverloadWrapper boilerplate (MarcoFalke) +- #18952 Avoid os-dependent path (fametrano) +- #18938 Fill fuzzing coverage gaps for functions in consensus/validation.h, primitives/block.h and util/translation.h (practicalswift) +- #18986 Add capability to disable RPC timeout in functional tests (rajarshimaitra) +- #18530 Add test for -blocksonly and -whitelistforcerelay param interaction (glowang) +- #19014 Replace `TEST_PREVIOUS_RELEASES` env var with `test_framework` option (MarcoFalke) +- #19052 Don't limit fuzzing inputs to 1 MB for afl-fuzz (now: ∞ ∀ fuzzers) (practicalswift) +- #19060 Remove global `wait_until` from `p2p_getdata` (MarcoFalke) +- #18926 Pass ArgsManager into `getarg_tests` (glowang) +- #19110 Explain that a bug should be filed when the tests fail (MarcoFalke) +- #18965 Implement `base58_decode` (10xcryptodev) +- #16564 Always define the `raii_event_tests` test suite (candrews) +- #19122 Add missing `sync_blocks` to `wallet_hd` (MarcoFalke) +- #18875 fuzz: Stop nodes in `process_message*` fuzzers (MarcoFalke) +- #18974 Check that invalid witness destinations can not be imported (MarcoFalke) +- #18210 Type hints in Python tests (kiminuo) +- #19159 Make valgrind.supp work on aarch64 (MarcoFalke) +- #19082 Moved the CScriptNum asserts into the unit test in script.py (gillichu) +- #19172 Do not swallow flake8 exit code (hebasto) +- #19188 Avoid overwriting the NodeContext member of the testing setup [-Wshadow-field] (MarcoFalke) +- #18890 `disconnect_nodes` should warn if nodes were already disconnected (robot-visions) +- #19227 change blacklist to blocklist (TrentZ) +- #19230 Move base58 to own module to break circular dependency (sipa) +- #19083 `msg_mempool`, `fRelay`, and other bloomfilter tests (gzhao408) +- #16756 Connection eviction logic tests (mzumsande) +- #19177 Fix and clean `p2p_invalid_messages` functional tests (troygiorshev) +- #19264 Don't import asyncio to test magic bytes (jnewbery) +- #19178 Make `mininode_lock` non-reentrant (jnewbery) +- #19153 Mempool compatibility test (S3RK) +- #18434 Add a test-security target and run it in CI (fanquake) +- #19252 Wait for disconnect in `disconnect_p2ps` + bloomfilter test followups (gzhao408) +- #19298 Add missing `sync_blocks` (MarcoFalke) +- #19304 Check that message sends successfully when header is split across two buffers (troygiorshev) +- #19208 move `sync_blocks` and `sync_mempool` functions to `test_framework.py` (ycshao) +- #19198 Check that peers with forcerelay permission are not asked to feefilter (MarcoFalke) +- #19351 add two edge case tests for CSubNet (vasild) +- #19272 net, test: invalid p2p messages and test framework improvements (jonatack) +- #19348 Bump linter versions (duncandean) +- #19366 Provide main(…) function in fuzzer. Allow building uninstrumented harnesses with --enable-fuzz (practicalswift) +- #19412 move `TEST_RUNNER_EXTRA` into native tsan setup (fanquake) +- #19368 Improve functional tests compatibility with BSD/macOS (S3RK) +- #19028 Set -logthreadnames in unit tests (MarcoFalke) +- #18649 Add std::locale::global to list of locale dependent functions (practicalswift) +- #19140 Avoid fuzzer-specific nullptr dereference in libevent when handling PROXY requests (practicalswift) +- #19214 Auto-detect SHA256 implementation in benchmarks (sipa) +- #19353 Fix mistakenly swapped "previous" and "current" lock orders (hebasto) +- #19533 Remove unnecessary `cs_mains` in `denialofservice_tests` (jnewbery) +- #19423 add functional test for txrelay during and after IBD (gzhao408) +- #16878 Fix non-deterministic coverage of test `DoS_mapOrphans` (davereikher) +- #19548 fuzz: add missing overrides to `signature_checker` (jonatack) +- #19562 Fix fuzzer compilation on macOS (freenancial) +- #19370 Static asserts for consistency of fee defaults (domob1812) +- #19599 clean `message_count` and `last_message` (troygiorshev) +- #19597 test decodepsbt fee calculation (count input value only once per UTXO) (theStack) +- #18011 Replace current benchmarking framework with nanobench (martinus) +- #19489 Fail `wait_until` early if connection is lost (MarcoFalke) +- #19340 Preserve the `LockData` initial state if "potential deadlock detected" exception thrown (hebasto) +- #19632 Catch decimal.InvalidOperation from `TestNodeCLI#send_cli` (Empact) +- #19098 Remove duplicate NodeContext hacks (ryanofsky) +- #19649 Restore test case for p2p transaction blinding (instagibbs) +- #19657 Wait until `is_connected` in `add_p2p_connection` (MarcoFalke) +- #19631 Wait for 'cmpctblock' in `p2p_compactblocks` when it is expected (Empact) +- #19674 use throwaway _ variable for unused loop counters (theStack) +- #19709 Fix 'make cov' with clang (hebasto) +- #19564 `p2p_feefilter` improvements (logging, refactoring, speedup) (theStack) +- #19756 add `sync_all` to fix race condition in wallet groups test (kallewoof) +- #19727 Removing unused classes from `p2p_leak.py` (dhruv) +- #19722 Add test for getblockheader verboseness (torhte) +- #19659 Add a seed corpus generation option to the fuzzing `test_runner` (darosior) +- #19775 Activate segwit in TestChain100Setup (MarcoFalke) +- #19760 Remove confusing mininode terminology (jnewbery) +- #19752 Update `wait_until` usage in tests not to use the one from utils (slmtpz) +- #19839 Set appveyor VM version to previous Visual Studio 2019 release (sipsorcery) +- #19830 Add tsan supp for leveldb::DBImpl::DeleteObsoleteFiles (MarcoFalke) +- #19710 bench: Prevent thread oversubscription and decreases the variance of result values (hebasto) +- #19842 Update the vcpkg checkout commit ID in appveyor config (sipsorcery) +- #19507 Expand functional zmq transaction tests (instagibbs) +- #19816 Rename wait until helper to `wait_until_helper` (MarcoFalke) +- #19859 Fixes failing functional test by changing version (n-thumann) +- #19887 Fix flaky `wallet_basic` test (fjahr) +- #19897 Change `FILE_CHAR_BLOCKLIST` to `FILE_CHARS_DISALLOWED` (verretor) +- #19800 Mockwallet (MarcoFalke) +- #19922 Run `rpc_txoutproof.py` even with wallet disabled (MarcoFalke) +- #19936 batch rpc with params (instagibbs) +- #19971 create default wallet in extended tests (Sjors) +- #19781 add parameterized constructor for `msg_sendcmpct()` (theStack) +- #19963 Clarify blocksonly whitelistforcerelay test (t-bast) +- #20022 Use explicit p2p objects where available (guggero) +- #20028 Check that invalid peer traffic is accounted for (MarcoFalke) +- #20004 Add signet witness commitment section parse tests (MarcoFalke) +- #20034 Get rid of default wallet hacks (ryanofsky) +- #20069 Mention commit id in scripted diff error (laanwj) +- #19947 Cover `change_type` option of "walletcreatefundedpsbt" RPC (guggero) +- #20126 `p2p_leak_tx.py` improvements (use MiniWallet, add `p2p_lock` acquires) (theStack) +- #20129 Don't export `in6addr_loopback` (vasild) +- #20131 Remove unused nVersion=1 in p2p tests (MarcoFalke) +- #20161 Minor Taproot follow-ups (sipa) +- #19401 Use GBT to get block versions correct (luke-jr) +- #20159 `mining_getblocktemplate_longpoll.py` improvements (use MiniWallet, add logging) (theStack) +- #20039 Convert amounts from float to decimal (prayank23) +- #20112 Speed up `wallet_resendwallettransactions` with mockscheduler RPC (MarcoFalke) +- #20247 fuzz: Check for addrv1 compatibility before using addrv1 serializer. Fuzz addrv2 serialization (practicalswift) +- #20167 Add test for -blockversion (MarcoFalke) +- #19877 Clarify `rpc_net` & `p2p_disconnect_ban functional` tests (amitiuttarwar) +- #20258 Remove getnettotals/getpeerinfo consistency test (jnewbery) +- #20242 fuzz: Properly initialize PrecomputedTransactionData (MarcoFalke) +- #20262 Skip --descriptor tests if sqlite is not compiled (achow101) +- #18788 Update more tests to work with descriptor wallets (achow101) +- #20289 fuzz: Check for addrv1 compatibility before using addrv1 serializer/deserializer on CService (practicalswift) +- #20290 fuzz: Fix DecodeHexTx fuzzing harness issue (practicalswift) +- #20245 Run `script_assets_test` even if built --with-libs=no (MarcoFalke) +- #20300 fuzz: Add missing `ECC_Start` to `descriptor_parse` test (S3RK) +- #20283 Only try witness deser when checking for witness deser failure (MarcoFalke) +- #20303 fuzz: Assert expected DecodeHexTx behaviour when using legacy decoding (practicalswift) +- #20316 Fix `wallet_multiwallet` test issue on Windows (MarcoFalke) +- #20326 Fix `ecdsa_verify` in test framework (stepansnigirev) +- #20328 cirrus: Skip tasks on the gui repo main branch (MarcoFalke) +- #20355 fuzz: Check for addrv1 compatibility before using addrv1 serializer/deserializer on CSubNet (practicalswift) +- #20332 Mock IBD in `net_processing` fuzzers (MarcoFalke) +- #20218 Suppress `epoll_ctl` data race (MarcoFalke) +- #20375 fuzz: Improve coverage for CPartialMerkleTree fuzzing harness (practicalswift) +- #19669 contrib: Fixup valgrind suppressions file (MarcoFalke) +- #18879 valgrind: remove outdated suppressions (fanquake) +- #19226 Add BerkeleyDatabase tsan suppression (MarcoFalke) +- #20379 Remove no longer needed UBSan suppression (float divide-by-zero in validation.cpp) (practicalswift) +- #18190, #18736, #18744, #18775, #18783, #18867, #18994, #19065, + #19067, #19143, #19222, #19247, #19286, #19296, #19379, #19934, + #20188, #20395 Add fuzzing harnessses (practicalswift) +- #18638 Use mockable time for ping/pong, add tests (MarcoFalke) +- #19951 CNetAddr scoped ipv6 test coverage, rename scopeId to `m_scope_id` (jonatack) +- #20027 Use mockable time everywhere in `net_processing` (sipa) +- #19105 Add Muhash3072 implementation in Python (fjahr) +- #18704, #18752, #18753, #18765, #18839, #18866, #18873, #19022, + #19023, #19429, #19552, #19778, #20176, #20179, #20214, #20292, + #20299, #20322 Fix intermittent test issues (MarcoFalke) +- #20390 CI/Cirrus: Skip `merge_base` step for non-PRs (luke-jr) +- #18634 ci: Add fuzzbuzz integration configuration file (practicalswift) +- #18591 Add C++17 build to Travis (sipa) +- #18581, #18667, #18798, #19495, #19519, #19538 CI improvements (hebasto) +- #18683, #18705, #18735, #18778, #18799, #18829, #18912, #18929, + #19008, #19041, #19164, #19201, #19267, #19276, #19321, #19371, + #19427, #19730, #19746, #19881, #20294, #20339, #20368 CI improvements (MarcoFalke) +- #20489, #20506 MSVC CI improvements (sipsorcery) + +### Miscellaneous +- #18713 scripts: Add macho stack canary check to security-check.py (fanquake) +- #18629 scripts: Add pe .reloc section check to security-check.py (fanquake) +- #18437 util: `Detect posix_fallocate()` instead of assuming (vasild) +- #18413 script: Prevent ub when computing abs value for num opcode serialize (pierreN) +- #18443 lockedpool: avoid sensitive data in core files (FreeBSD) (vasild) +- #18885 contrib: Move optimize-pngs.py script to the maintainer repo (MarcoFalke) +- #18317 Serialization improvements step 6 (all except wallet/gui) (sipa) +- #16127 More thread safety annotation coverage (ajtowns) +- #19228 Update libsecp256k1 subtree (sipa) +- #19277 util: Add assert identity function (MarcoFalke) +- #19491 util: Make assert work with any value (MarcoFalke) +- #19205 script: `previous_release.sh` rewritten in python (bliotti) +- #15935 Add /settings.json persistent settings storage (ryanofsky) +- #19439 script: Linter to check commit message formatting (Ghorbanian) +- #19654 lint: Improve commit message linter in travis (fjahr) +- #15382 util: Add runcommandparsejson (Sjors) +- #19614 util: Use `have_fdatasync` to determine fdatasync() use (fanquake) +- #19813 util, ci: Hard code previous release tarball checksums (hebasto) +- #19841 Implement Keccak and `SHA3_256` (sipa) +- #19643 Add -netinfo peer connections dashboard (jonatack) +- #15367 feature: Added ability for users to add a startup command (benthecarman) +- #19984 log: Remove static log message "Initializing chainstate Chainstate [ibd] @ height -1 (null)" (practicalswift) +- #20092 util: Do not use gargs global in argsmanager member functions (hebasto) +- #20168 contrib: Fix `gen_key_io_test_vectors.py` imports (MarcoFalke) +- #19624 Warn on unknown `rw_settings` (MarcoFalke) +- #20257 Update secp256k1 subtree to latest master (sipa) +- #20346 script: Modify security-check.py to use "==" instead of "is" for literal comparison (tylerchambers) +- #18881 Prevent UB in DeleteLock() function (hebasto) +- #19180, #19189, #19190, #19220, #19399 Replace RecursiveMutex with Mutex (hebasto) +- #19347 Make `cs_inventory` nonrecursive (jnewbery) +- #19773 Avoid recursive lock in IsTrusted (promag) +- #18790 Improve thread naming (hebasto) +- #20140 Restore compatibility with old CSubNet serialization (sipa) +- #17775 DecodeHexTx: Try case where txn has inputs first (instagibbs) + +### Documentation +- #18502 Update docs for getbalance (default minconf should be 0) (uzyn) +- #18632 Fix macos comments in release-notes (MarcoFalke) +- #18645 Update thread information in developer docs (jnewbery) +- #18709 Note why we can't use `thread_local` with glibc back compat (fanquake) +- #18410 Improve commenting for coins.cpp|h (jnewbery) +- #18157 fixing init.md documentation to not require rpcpassword (jkcd) +- #18739 Document how to fuzz Bitcoin Core using Honggfuzz (practicalswift) +- #18779 Better explain GNU ld's dislike of ld64's options (fanquake) +- #18663 Mention build docs in README.md (saahilshangle) +- #18810 Update rest info on block size and json (chrisabrams) +- #18939 Add c++17-enable flag to fuzzing instructions (mzumsande) +- #18957 Add a link from ZMQ doc to ZMQ example in contrib/ (meeDamian) +- #19058 Drop protobuf stuff (hebasto) +- #19061 Add link to Visual Studio build readme (maitrebitcoin) +- #19072 Expand section on Getting Started (MarcoFalke) +- #18968 noban precludes maxuploadtarget disconnects (MarcoFalke) +- #19005 Add documentation for 'checklevel' argument in 'verifychain' RPC… (kcalvinalvin) +- #19192 Extract net permissions doc (MarcoFalke) +- #19071 Separate repository for the gui (MarcoFalke) +- #19018 fixing description of the field sequence in walletcreatefundedpsbt RPC method (limpbrains) +- #19367 Span pitfalls (sipa) +- #19408 Windows WSL build recommendation to temporarily disable Win32 PE support (sipsorcery) +- #19407 explain why passing -mlinker-version is required when cross-compiling (fanquake) +- #19452 afl fuzzing comment about afl-gcc and afl-g++ (Crypt-iQ) +- #19258 improve subtree check instructions (Sjors) +- #19474 Use precise permission flags where possible (MarcoFalke) +- #19494 CONTRIBUTING.md improvements (jonatack) +- #19268 Add non-thread-safe note to FeeFilterRounder::round() (hebasto) +- #19547 Update macOS cross compilation dependencies for Focal (hebasto) +- #19617 Clang 8 or later is required with `FORCE_USE_SYSTEM_CLANG` (fanquake) +- #19639 Remove Reference Links #19582 (RobertHosking) +- #19605 Set `CC_FOR_BUILD` when building on OpenBSD (fanquake) +- #19765 Fix getmempoolancestors RPC result doc (MarcoFalke) +- #19786 Remove label from good first issue template (MarcoFalke) +- #19646 Updated outdated help command for getblocktemplate (jakeleventhal) +- #18817 Document differences in bitcoind and bitcoin-qt locale handling (practicalswift) +- #19870 update PyZMQ install instructions, fix `zmq_sub.py` file permissions (jonatack) +- #19903 Update build-openbsd.md with GUI support (grubles) +- #19241 help: Generate checkpoint height from chainparams (luke-jr) +- #18949 Add CODEOWNERS file to automatically nominate PR reviewers (adamjonas) +- #20014 Mention signet in -help output (hebasto) +- #20015 Added default signet config for linearize script (gr0kchain) +- #19958 Better document features of feelers (naumenkogs) +- #19871 Clarify scope of eviction protection of outbound block-relay peers (ariard) +- #20076 Update and improve files.md (hebasto) +- #20107 Collect release-notes snippets (MarcoFalke) +- #20109 Release notes and followups from 19339 (glozow) +- #20090 Tiny followups to new getpeerinfo connection type field (amitiuttarwar) +- #20152 Update wallet files in files.md (hebasto) +- #19124 Document `ALLOW_HOST_PACKAGES` dependency option (skmcontrib) +- #20271 Document that wallet salvage is experimental (MarcoFalke) +- #20281 Correct getblockstats documentation for `(sw)total_weight` (shesek) +- #20279 release process updates/fixups (jonatack) +- #20238 Missing comments for signet parameters (decryp2kanon) +- #20756 Add missing field (permissions) to the getpeerinfo help (amitiuttarwar) +- #20668 warn that incoming conns are unlikely when not using default ports (adamjonas) +- #19961 tor.md updates (jonatack) +- #19050 Add warning for rest interface limitation (fjahr) +- #19390 doc/REST-interface: Remove stale info (luke-jr) +- #19344 docs: update testgen usage example (Bushstar) + +Credits +======= + +Thanks to everyone who directly contributed to this release: + +- 10xcryptodev +- Aaron Clauson +- Aaron Hook +- Adam Jonas +- Adam Soltys +- Adam Stein +- Akio Nakamura +- Alex Willmer +- Amir Ghorbanian +- Amiti Uttarwar +- Andrew Chow +- Andrew Toth +- Anthony Fieroni +- Anthony Towns +- Antoine Poinsot +- Antoine Riard +- Ben Carman +- Ben Woosley +- Benoit Verret +- Brian Liotti +- Bushstar +- Calvin Kim +- Carl Dong +- Chris Abrams +- Chris L +- Christopher Coverdale +- codeShark149 +- Cory Fields +- Craig Andrews +- Damian Mee +- Daniel Kraft +- Danny Lee +- David Reikher +- DesWurstes +- Dhruv Mehta +- Duncan Dean +- Elichai Turkel +- Elliott Jin +- Emil Engler +- Ethan Heilman +- eugene +- Fabian Jahr +- fanquake +- Ferdinando M. Ametrano +- freenancial +- furszy +- Gillian Chu +- Gleb Naumenko +- Glenn Willen +- Gloria Zhao +- glowang +- gr0kchain +- Gregory Sanders +- grubles +- gzhao408 +- Harris +- Hennadii Stepanov +- Hugo Nguyen +- Igor Cota +- Ivan Metlushko +- Ivan Vershigora +- Jake Leventhal +- James O'Beirne +- Jeremy Rubin +- jgmorgan +- Jim Posen +- “jkcd” +- jmorgan +- John Newbery +- Johnson Lau +- Jon Atack +- Jonas Schnelli +- Jonathan Schoeller +- João Barbosa +- Justin Moon +- kanon +- Karl-Johan Alm +- Kiminuo +- Kristaps Kaupe +- lontivero +- Luke Dashjr +- Marcin Jachymiak +- MarcoFalke +- Martin Ankerl +- Martin Zumsande +- maskoficarus +- Matt Corallo +- Matthew Zipkin +- MeshCollider +- Miguel Herranz +- MIZUTA Takeshi +- mruddy +- Nadav Ivgi +- Neha Narula +- Nicolas Thumann +- Niklas Gögge +- Nima Yazdanmehr +- nsa +- nthumann +- Oliver Gugger +- pad +- pasta +- Peter Bushnell +- pierrenn +- Pieter Wuille +- practicalswift +- Prayank +- Raúl Martínez (RME) +- RandyMcMillan +- Rene Pickhardt +- Riccardo Masutti +- Robert +- Rod Vagg +- Roy Shao +- Russell Yanofsky +- Saahil Shangle +- sachinkm77 +- saibato +- Samuel Dobson +- sanket1729 +- Sebastian Falbesoner +- Seleme Topuz +- Sishir Giri +- Sjors Provoost +- skmcontrib +- Stepan Snigirev +- Stephan Oeste +- Suhas Daftuar +- t-bast +- Tom Harding +- Torhte Butler +- TrentZ +- Troy Giorshev +- tryphe +- Tyler Chambers +- U-Zyn Chua +- Vasil Dimov +- wiz +- Wladimir J. van der Laan + +As well as to everyone that helped with translations on +[Transifex](https://www.transifex.com/bitcoin/bitcoin/). From c3bd45e5dd959e0a820598fa95283ef73283463b Mon Sep 17 00:00:00 2001 From: Anthony Towns Date: Mon, 19 Oct 2020 20:49:42 +1000 Subject: [PATCH 42/84] tests: more helpful errors for failing versionbits tests Co-authored-by: Sjors Provoost (cherry picked from commit 3ba9283a47ac358168db9db7840ae559f443486c) --- src/test/versionbits_tests.cpp | 72 ++++++++++++---------------------- 1 file changed, 26 insertions(+), 46 deletions(-) diff --git a/src/test/versionbits_tests.cpp b/src/test/versionbits_tests.cpp index 50444f7bbe..23b1709c8f 100644 --- a/src/test/versionbits_tests.cpp +++ b/src/test/versionbits_tests.cpp @@ -14,6 +14,18 @@ /* Define a virtual block time, one block per 10 minutes after Nov 14 2014, 0:55:36am */ static int32_t TestTime(int nHeight) { return 1415926536 + 600 * nHeight; } +static const std::string StateName(ThresholdState state) +{ + switch (state) { + case ThresholdState::DEFINED: return "DEFINED"; + case ThresholdState::STARTED: return "STARTED"; + case ThresholdState::LOCKED_IN: return "LOCKED_IN"; + case ThresholdState::ACTIVE: return "ACTIVE"; + case ThresholdState::FAILED: return "FAILED"; + } // no default case, so the compiler can warn about missing cases + return ""; +} + static const Consensus::Params paramsDummy = Consensus::Params(); class TestConditionChecker : public AbstractThresholdConditionChecker @@ -98,60 +110,28 @@ public: return *this; } - VersionBitsTester& TestDefined() { + VersionBitsTester& TestState(ThresholdState exp) { for (int i = 0; i < CHECKERS; i++) { if (InsecureRandBits(i) == 0) { - BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::DEFINED, strprintf("Test %i for DEFINED", num)); - BOOST_CHECK_MESSAGE(checker_always[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::ACTIVE, strprintf("Test %i for ACTIVE (always active)", num)); + const CBlockIndex* pindex = vpblock.empty() ? nullptr : vpblock.back(); + ThresholdState got = checker[i].GetStateFor(pindex); + ThresholdState got_always = checker_always[i].GetStateFor(pindex); + // nHeight of the next block. If vpblock is empty, the next (ie first) + // block should be the genesis block with nHeight == 0. + int height = pindex == nullptr ? 0 : pindex->nHeight + 1; + BOOST_CHECK_MESSAGE(got == exp, strprintf("Test %i for %s height %d (got %s)", num, StateName(exp), height, StateName(got))); + BOOST_CHECK_MESSAGE(got_always == ThresholdState::ACTIVE, strprintf("Test %i for ACTIVE height %d (got %s; always active case)", num, height, StateName(got_always))); } } num++; return *this; } - VersionBitsTester& TestStarted() { - for (int i = 0; i < CHECKERS; i++) { - if (InsecureRandBits(i) == 0) { - BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::STARTED, strprintf("Test %i for STARTED", num)); - BOOST_CHECK_MESSAGE(checker_always[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::ACTIVE, strprintf("Test %i for ACTIVE (always active)", num)); - } - } - num++; - return *this; - } - - VersionBitsTester& TestLockedIn() { - for (int i = 0; i < CHECKERS; i++) { - if (InsecureRandBits(i) == 0) { - BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::LOCKED_IN, strprintf("Test %i for LOCKED_IN", num)); - BOOST_CHECK_MESSAGE(checker_always[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::ACTIVE, strprintf("Test %i for ACTIVE (always active)", num)); - } - } - num++; - return *this; - } - - VersionBitsTester& TestActive() { - for (int i = 0; i < CHECKERS; i++) { - if (InsecureRandBits(i) == 0) { - BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::ACTIVE, strprintf("Test %i for ACTIVE", num)); - BOOST_CHECK_MESSAGE(checker_always[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::ACTIVE, strprintf("Test %i for ACTIVE (always active)", num)); - } - } - num++; - return *this; - } - - VersionBitsTester& TestFailed() { - for (int i = 0; i < CHECKERS; i++) { - if (InsecureRandBits(i) == 0) { - BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::FAILED, strprintf("Test %i for FAILED", num)); - BOOST_CHECK_MESSAGE(checker_always[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::ACTIVE, strprintf("Test %i for ACTIVE (always active)", num)); - } - } - num++; - return *this; - } + VersionBitsTester& TestDefined() { return TestState(ThresholdState::DEFINED); } + VersionBitsTester& TestStarted() { return TestState(ThresholdState::STARTED); } + VersionBitsTester& TestLockedIn() { return TestState(ThresholdState::LOCKED_IN); } + VersionBitsTester& TestActive() { return TestState(ThresholdState::ACTIVE); } + VersionBitsTester& TestFailed() { return TestState(ThresholdState::FAILED); } CBlockIndex * Tip() { return vpblock.size() ? vpblock.back() : nullptr; } }; From b8d678c9c9d79c81849397832a03c1e4345536d3 Mon Sep 17 00:00:00 2001 From: Anthony Towns Date: Mon, 19 Oct 2020 22:59:50 +1000 Subject: [PATCH 43/84] tests: check never active versionbits (cherry picked from commit 0c471a5f306044cbd2eb230714571f05dd6aaf3c) --- src/test/versionbits_tests.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/test/versionbits_tests.cpp b/src/test/versionbits_tests.cpp index 23b1709c8f..8841a540f2 100644 --- a/src/test/versionbits_tests.cpp +++ b/src/test/versionbits_tests.cpp @@ -50,6 +50,13 @@ public: int64_t BeginTime(const Consensus::Params& params) const override { return Consensus::BIP9Deployment::ALWAYS_ACTIVE; } }; +class TestNeverActiveConditionChecker : public TestConditionChecker +{ +public: + int64_t BeginTime(const Consensus::Params& params) const override { return 0; } + int64_t EndTime(const Consensus::Params& params) const override { return 1230768000; } +}; + #define CHECKERS 6 class VersionBitsTester @@ -63,6 +70,8 @@ class VersionBitsTester TestConditionChecker checker[CHECKERS]; // Another 6 that assume always active activation TestAlwaysActiveConditionChecker checker_always[CHECKERS]; + // Another 6 that assume never active activation + TestNeverActiveConditionChecker checker_never[CHECKERS]; // Test counter (to identify failures) int num; @@ -77,6 +86,7 @@ public: for (unsigned int i = 0; i < CHECKERS; i++) { checker[i] = TestConditionChecker(); checker_always[i] = TestAlwaysActiveConditionChecker(); + checker_never[i] = TestNeverActiveConditionChecker(); } vpblock.clear(); return *this; @@ -104,6 +114,10 @@ public: if (InsecureRandBits(i) == 0) { BOOST_CHECK_MESSAGE(checker[i].GetStateSinceHeightFor(vpblock.empty() ? nullptr : vpblock.back()) == height, strprintf("Test %i for StateSinceHeight", num)); BOOST_CHECK_MESSAGE(checker_always[i].GetStateSinceHeightFor(vpblock.empty() ? nullptr : vpblock.back()) == 0, strprintf("Test %i for StateSinceHeight (always active)", num)); + + // never active may go from DEFINED -> FAILED at the first period + const auto never_height = checker_never[i].GetStateSinceHeightFor(vpblock.empty() ? nullptr : vpblock.back()); + BOOST_CHECK_MESSAGE(never_height == 0 || never_height == checker_never[i].Period(paramsDummy), strprintf("Test %i for StateSinceHeight (never active)", num)); } } num++; @@ -116,11 +130,13 @@ public: const CBlockIndex* pindex = vpblock.empty() ? nullptr : vpblock.back(); ThresholdState got = checker[i].GetStateFor(pindex); ThresholdState got_always = checker_always[i].GetStateFor(pindex); + ThresholdState got_never = checker_never[i].GetStateFor(pindex); // nHeight of the next block. If vpblock is empty, the next (ie first) // block should be the genesis block with nHeight == 0. int height = pindex == nullptr ? 0 : pindex->nHeight + 1; BOOST_CHECK_MESSAGE(got == exp, strprintf("Test %i for %s height %d (got %s)", num, StateName(exp), height, StateName(got))); BOOST_CHECK_MESSAGE(got_always == ThresholdState::ACTIVE, strprintf("Test %i for ACTIVE height %d (got %s; always active case)", num, height, StateName(got_always))); + BOOST_CHECK_MESSAGE(got_never == ThresholdState::DEFINED|| got_never == ThresholdState::FAILED, strprintf("Test %i for DEFINED/FAILED height %d (got %s; never active case)", num, height, StateName(got_never))); } } num++; From 81ea0ed4a611ae97775f57180d01059d81fa9e31 Mon Sep 17 00:00:00 2001 From: Anthony Towns Date: Tue, 16 Mar 2021 18:35:45 +1000 Subject: [PATCH 44/84] tests: Add fuzzing harness for versionbits Github-Pull: #21380 Rebased-From: 1639c3b76c3f2b74606f62ecd3ca725154e27f1b (cherry picked from commit e775b0a6dd8358df0e8921739faf15942027239e) --- src/Makefile.test.include | 9 +- src/test/fuzz/versionbits.cpp | 345 ++++++++++++++++++++++++++++++++++ 2 files changed, 353 insertions(+), 1 deletion(-) create mode 100644 src/test/fuzz/versionbits.cpp diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 8972306b89..65b5fcde89 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -158,7 +158,8 @@ FUZZ_TARGETS = \ test/fuzz/txundo_deserialize \ test/fuzz/uint160_deserialize \ test/fuzz/uint256_deserialize \ - test/fuzz/witness_program + test/fuzz/witness_program \ + test/fuzz/versionbits if ENABLE_FUZZ noinst_PROGRAMS += $(FUZZ_TARGETS:=) @@ -1274,6 +1275,12 @@ test_fuzz_witness_program_LDADD = $(FUZZ_SUITE_LD_COMMON) test_fuzz_witness_program_LDFLAGS = $(FUZZ_SUITE_LDFLAGS_COMMON) test_fuzz_witness_program_SOURCES = test/fuzz/witness_program.cpp +test_fuzz_versionbits_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +test_fuzz_versionbits_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +test_fuzz_versionbits_LDADD = $(FUZZ_SUITE_LD_COMMON) +test_fuzz_versionbits_LDFLAGS = $(FUZZ_SUITE_LDFLAGS_COMMON) +test_fuzz_versionbits_SOURCES = test/fuzz/versionbits.cpp + endif # ENABLE_FUZZ nodist_test_test_bitcoin_SOURCES = $(GENERATED_TEST_FILES) diff --git a/src/test/fuzz/versionbits.cpp b/src/test/fuzz/versionbits.cpp new file mode 100644 index 0000000000..992a5c1321 --- /dev/null +++ b/src/test/fuzz/versionbits.cpp @@ -0,0 +1,345 @@ +// Copyright (c) 2020-2021 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 +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +namespace { +class TestConditionChecker : public AbstractThresholdConditionChecker +{ +private: + mutable ThresholdConditionCache m_cache; + const Consensus::Params dummy_params{}; + +public: + const int64_t m_begin = 0; + const int64_t m_end = 0; + const int m_period = 0; + const int m_threshold = 0; + const int m_bit = 0; + + TestConditionChecker(int64_t begin, int64_t end, int period, int threshold, int bit) + : m_begin{begin}, m_end{end}, m_period{period}, m_threshold{threshold}, m_bit{bit} + { + assert(m_period > 0); + assert(0 <= m_threshold && m_threshold <= m_period); + assert(0 <= m_bit && m_bit <= 32 && m_bit < VERSIONBITS_NUM_BITS); + } + + bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const override { return Condition(pindex->nVersion); } + int64_t BeginTime(const Consensus::Params& params) const override { return m_begin; } + int64_t EndTime(const Consensus::Params& params) const override { return m_end; } + int Period(const Consensus::Params& params) const override { return m_period; } + int Threshold(const Consensus::Params& params) const override { return m_threshold; } + + ThresholdState GetStateFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateFor(pindexPrev, dummy_params, m_cache); } + int GetStateSinceHeightFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateSinceHeightFor(pindexPrev, dummy_params, m_cache); } + BIP9Stats GetStateStatisticsFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateStatisticsFor(pindexPrev, dummy_params); } + + bool Condition(int64_t version) const + { + return ((version >> m_bit) & 1) != 0 && (version & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS; + } + + bool Condition(const CBlockIndex* pindex) const { return Condition(pindex->nVersion); } +}; + +/** Track blocks mined for test */ +class Blocks +{ +private: + std::vector> m_blocks; + const uint32_t m_start_time; + const uint32_t m_interval; + const int32_t m_signal; + const int32_t m_no_signal; + +public: + Blocks(uint32_t start_time, uint32_t interval, int32_t signal, int32_t no_signal) + : m_start_time{start_time}, m_interval{interval}, m_signal{signal}, m_no_signal{no_signal} {} + + size_t size() const { return m_blocks.size(); } + + CBlockIndex* tip() const + { + return m_blocks.empty() ? nullptr : m_blocks.back().get(); + } + + CBlockIndex* mine_block(bool signal) + { + CBlockHeader header; + header.nVersion = signal ? m_signal : m_no_signal; + header.nTime = m_start_time + m_blocks.size() * m_interval; + header.nBits = 0x1d00ffff; + + auto current_block = std::make_unique(header); + current_block->pprev = tip(); + current_block->nHeight = m_blocks.size(); + current_block->BuildSkip(); + + return m_blocks.emplace_back(std::move(current_block)).get(); + } +}; +} // namespace + +void initialize() +{ + SelectParams(CBaseChainParams::MAIN); +} + +constexpr uint32_t MAX_TIME = 4102444800; // 2100-01-01 + +void test_one_input(const std::vector& buffer) +{ + const CChainParams& params = Params(); + + const int64_t interval = params.GetConsensus().nPowTargetSpacing; + assert(interval > 1); // need to be able to halve it + assert(interval < std::numeric_limits::max()); + + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + + // making period/max_periods larger slows these tests down significantly + const int period = 32; + const size_t max_periods = 16; + const size_t max_blocks = 2 * period * max_periods; + + const int threshold = fuzzed_data_provider.ConsumeIntegralInRange(1, period); + assert(0 < threshold && threshold <= period); // must be able to both pass and fail threshold! + + // too many blocks at 10min each might cause uint32_t time to overflow if + // block_start_time is at the end of the range above + assert(std::numeric_limits::max() - MAX_TIME > interval * max_blocks); + + const int64_t block_start_time = fuzzed_data_provider.ConsumeIntegralInRange(params.GenesisBlock().nTime, MAX_TIME); + + // what values for version will we use to signal / not signal? + const int32_t ver_signal = fuzzed_data_provider.ConsumeIntegral(); + const int32_t ver_nosignal = fuzzed_data_provider.ConsumeIntegral(); + + // select deployment parameters: bit, start time, timeout + const int bit = fuzzed_data_provider.ConsumeIntegralInRange(0, VERSIONBITS_NUM_BITS - 1); + + bool always_active_test = false; + bool never_active_test = false; + int64_t start_time; + int64_t timeout; + if (fuzzed_data_provider.ConsumeBool()) { + // pick the timestamp to switch based on a block + // note states will change *after* these blocks because mediantime lags + int start_block = fuzzed_data_provider.ConsumeIntegralInRange(0, period * (max_periods - 3)); + int end_block = fuzzed_data_provider.ConsumeIntegralInRange(start_block, period * (max_periods - 3)); + + start_time = block_start_time + start_block * interval; + timeout = block_start_time + end_block * interval; + + assert(start_time <= timeout); + + // allow for times to not exactly match a block + if (fuzzed_data_provider.ConsumeBool()) start_time += interval / 2; + if (fuzzed_data_provider.ConsumeBool()) timeout += interval / 2; + + // this may make timeout too early; if so, don't run the test + if (start_time > timeout) return; + } else { + if (fuzzed_data_provider.ConsumeBool()) { + start_time = Consensus::BIP9Deployment::ALWAYS_ACTIVE; + timeout = Consensus::BIP9Deployment::NO_TIMEOUT; + always_active_test = true; + } else { + start_time = 1199145601; // January 1, 2008 + timeout = 1230767999; // December 31, 2008 + never_active_test = true; + } + } + + TestConditionChecker checker(start_time, timeout, period, threshold, bit); + + // Early exit if the versions don't signal sensibly for the deployment + if (!checker.Condition(ver_signal)) return; + if (checker.Condition(ver_nosignal)) return; + if (ver_nosignal < 0) return; + + // TOP_BITS should ensure version will be positive + assert(ver_signal > 0); + + // Now that we have chosen time and versions, setup to mine blocks + Blocks blocks(block_start_time, interval, ver_signal, ver_nosignal); + + /* Strategy: + * * we will mine a final period worth of blocks, with + * randomised signalling according to a mask + * * but before we mine those blocks, we will mine some + * randomised number of prior periods; with either all + * or no blocks in the period signalling + * + * We establish the mask first, then consume "bools" until + * we run out of fuzz data to work out how many prior periods + * there are and which ones will signal. + */ + + // establish the mask + const uint32_t signalling_mask = fuzzed_data_provider.ConsumeIntegral(); + + // mine prior periods + while (fuzzed_data_provider.remaining_bytes() > 0) { + // all blocks in these periods either do or don't signal + bool signal = fuzzed_data_provider.ConsumeBool(); + for (int b = 0; b < period; ++b) { + blocks.mine_block(signal); + } + + // don't risk exceeding max_blocks or times may wrap around + if (blocks.size() + period*2 > max_blocks) break; + } + // NOTE: fuzzed_data_provider may be fully consumed at this point and should not be used further + + // now we mine the final period and check that everything looks sane + + // count the number of signalling blocks + int blocks_sig = 0; + + // get the info for the first block of the period + CBlockIndex* prev = blocks.tip(); + const int exp_since = checker.GetStateSinceHeightFor(prev); + const ThresholdState exp_state = checker.GetStateFor(prev); + BIP9Stats last_stats = checker.GetStateStatisticsFor(prev); + + int prev_next_height = (prev == nullptr ? 0 : prev->nHeight + 1); + assert(exp_since <= prev_next_height); + + // mine (period-1) blocks and check state + for (int b = 1; b < period; ++b) { + const bool signal = (signalling_mask >> (b % 32)) & 1; + if (signal) ++blocks_sig; + + CBlockIndex* current_block = blocks.mine_block(signal); + + // verify that signalling attempt was interpreted correctly + assert(checker.Condition(current_block) == signal); + + // state and since don't change within the period + const ThresholdState state = checker.GetStateFor(current_block); + const int since = checker.GetStateSinceHeightFor(current_block); + assert(state == exp_state); + assert(since == exp_since); + + // GetStateStatistics may crash when state is not STARTED + if (state != ThresholdState::STARTED) continue; + + // check that after mining this block stats change as expected + const BIP9Stats stats = checker.GetStateStatisticsFor(current_block); + assert(stats.period == period); + assert(stats.threshold == threshold); + assert(stats.elapsed == b); + assert(stats.count == last_stats.count + (signal ? 1 : 0)); + assert(stats.possible == (stats.count + period >= stats.elapsed + threshold)); + last_stats = stats; + } + + if (exp_state == ThresholdState::STARTED) { + // double check that stats.possible is sane + if (blocks_sig >= threshold - 1) assert(last_stats.possible); + } + + // mine the final block + bool signal = (signalling_mask >> (period % 32)) & 1; + if (signal) ++blocks_sig; + CBlockIndex* current_block = blocks.mine_block(signal); + assert(checker.Condition(current_block) == signal); + + // GetStateStatistics is safe on a period boundary + // and has progressed to a new period + const BIP9Stats stats = checker.GetStateStatisticsFor(current_block); + assert(stats.period == period); + assert(stats.threshold == threshold); + assert(stats.elapsed == 0); + assert(stats.count == 0); + assert(stats.possible == true); + + // More interesting is whether the state changed. + const ThresholdState state = checker.GetStateFor(current_block); + const int since = checker.GetStateSinceHeightFor(current_block); + + // since is straightforward: + assert(since % period == 0); + assert(0 <= since && since <= current_block->nHeight + 1); + if (state == exp_state) { + assert(since == exp_since); + } else { + assert(since == current_block->nHeight + 1); + } + + // state is where everything interesting is + switch (state) { + case ThresholdState::DEFINED: + assert(since == 0); + assert(exp_state == ThresholdState::DEFINED); + assert(current_block->GetMedianTimePast() < checker.m_begin); + assert(current_block->GetMedianTimePast() < checker.m_end); + break; + case ThresholdState::STARTED: + assert(current_block->GetMedianTimePast() >= checker.m_begin); + assert(current_block->GetMedianTimePast() < checker.m_end); + if (exp_state == ThresholdState::STARTED) { + assert(blocks_sig < threshold); + } else { + assert(exp_state == ThresholdState::DEFINED); + } + break; + case ThresholdState::LOCKED_IN: + assert(exp_state == ThresholdState::STARTED); + assert(current_block->GetMedianTimePast() < checker.m_end); + assert(blocks_sig >= threshold); + break; + case ThresholdState::ACTIVE: + assert(exp_state == ThresholdState::ACTIVE || exp_state == ThresholdState::LOCKED_IN); + break; + case ThresholdState::FAILED: + assert(current_block->GetMedianTimePast() >= checker.m_end); + assert(exp_state != ThresholdState::LOCKED_IN && exp_state != ThresholdState::ACTIVE); + break; + default: + assert(false); + } + + if (blocks.size() >= max_periods * period) { + // we chose the timeout (and block times) so that by the time we have this many blocks it's all over + assert(state == ThresholdState::ACTIVE || state == ThresholdState::FAILED); + } + + // "always active" has additional restrictions + if (always_active_test) { + assert(state == ThresholdState::ACTIVE); + assert(exp_state == ThresholdState::ACTIVE); + assert(since == 0); + } else { + // except for always active, the initial state is always DEFINED + assert(since > 0 || state == ThresholdState::DEFINED); + assert(exp_since > 0 || exp_state == ThresholdState::DEFINED); + } + + // "never active" does too + if (never_active_test) { + assert(state == ThresholdState::FAILED); + assert(since == period); + if (exp_since == 0) { + assert(exp_state == ThresholdState::DEFINED); + } else { + assert(exp_state == ThresholdState::FAILED); + } + } +} From 0682f35ee483e59959dd3fbc210f9e892922bee3 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 4 Jan 2021 18:37:52 +0100 Subject: [PATCH 45/84] net: allow CSubNet of non-IP networks Allow creation of valid `CSubNet` objects of non-IP networks and only match the single address they were created from (like /32 for IPv4 or /128 for IPv6). This fixes a deficiency in `CConnman::DisconnectNode(const CNetAddr& addr)` and in `BanMan` which assume that creating a subnet from any address using the `CSubNet(CNetAddr)` constructor would later match that address only. Before this change a non-IP subnet would be invalid and would not match any address. Github-Pull: #20852 Rebased-From: 94d335da7f8232bc653c9b08b0a33b517b4c98ad (cherry picked from commit c33fbab25c82b6a18773b80e8b355c987066ae5a) --- src/netaddress.cpp | 81 +++++++++++++++++++++++++++++++------- src/netaddress.h | 24 ++++++++++- src/test/netbase_tests.cpp | 21 ++++++++-- 3 files changed, 107 insertions(+), 19 deletions(-) diff --git a/src/netaddress.cpp b/src/netaddress.cpp index 35e9161f58..e0d4638dd6 100644 --- a/src/netaddress.cpp +++ b/src/netaddress.cpp @@ -1063,15 +1063,24 @@ CSubNet::CSubNet(const CNetAddr& addr, const CNetAddr& mask) : CSubNet() CSubNet::CSubNet(const CNetAddr& addr) : CSubNet() { - valid = addr.IsIPv4() || addr.IsIPv6(); - if (!valid) { + switch (addr.m_net) { + case NET_IPV4: + case NET_IPV6: + valid = true; + assert(addr.m_addr.size() <= sizeof(netmask)); + memset(netmask, 0xFF, addr.m_addr.size()); + break; + case NET_ONION: + case NET_I2P: + case NET_CJDNS: + valid = true; + break; + case NET_INTERNAL: + case NET_UNROUTABLE: + case NET_MAX: return; } - assert(addr.m_addr.size() <= sizeof(netmask)); - - memset(netmask, 0xFF, addr.m_addr.size()); - network = addr; } @@ -1083,6 +1092,21 @@ bool CSubNet::Match(const CNetAddr &addr) const { if (!valid || !addr.IsValid() || network.m_net != addr.m_net) return false; + + switch (network.m_net) { + case NET_IPV4: + case NET_IPV6: + break; + case NET_ONION: + case NET_I2P: + case NET_CJDNS: + case NET_INTERNAL: + return addr == network; + case NET_UNROUTABLE: + case NET_MAX: + return false; + } + assert(network.m_addr.size() == addr.m_addr.size()); for (size_t x = 0; x < addr.m_addr.size(); ++x) { if ((addr.m_addr[x] & netmask[x]) != network.m_addr[x]) { @@ -1094,18 +1118,35 @@ bool CSubNet::Match(const CNetAddr &addr) const std::string CSubNet::ToString() const { - assert(network.m_addr.size() <= sizeof(netmask)); + std::string suffix; - uint8_t cidr = 0; + switch (network.m_net) { + case NET_IPV4: + case NET_IPV6: { + assert(network.m_addr.size() <= sizeof(netmask)); - for (size_t i = 0; i < network.m_addr.size(); ++i) { - if (netmask[i] == 0x00) { - break; + uint8_t cidr = 0; + + for (size_t i = 0; i < network.m_addr.size(); ++i) { + if (netmask[i] == 0x00) { + break; + } + cidr += NetmaskBits(netmask[i]); } - cidr += NetmaskBits(netmask[i]); + + suffix = strprintf("/%u", cidr); + break; + } + case NET_ONION: + case NET_I2P: + case NET_CJDNS: + case NET_INTERNAL: + case NET_UNROUTABLE: + case NET_MAX: + break; } - return network.ToString() + strprintf("/%u", cidr); + return network.ToString() + suffix; } bool CSubNet::IsValid() const @@ -1115,7 +1156,19 @@ bool CSubNet::IsValid() const bool CSubNet::SanityCheck() const { - if (!(network.IsIPv4() || network.IsIPv6())) return false; + switch (network.m_net) { + case NET_IPV4: + case NET_IPV6: + break; + case NET_ONION: + case NET_I2P: + case NET_CJDNS: + return true; + case NET_INTERNAL: + case NET_UNROUTABLE: + case NET_MAX: + return false; + } for (size_t x = 0; x < network.m_addr.size(); ++x) { if (network.m_addr[x] & ~netmask[x]) return false; diff --git a/src/netaddress.h b/src/netaddress.h index 29b2eaafeb..b9beb1e358 100644 --- a/src/netaddress.h +++ b/src/netaddress.h @@ -462,11 +462,33 @@ class CSubNet bool SanityCheck() const; public: + /** + * Construct an invalid subnet (empty, `Match()` always returns false). + */ CSubNet(); + + /** + * Construct from a given network start and number of bits (CIDR mask). + * @param[in] addr Network start. Must be IPv4 or IPv6, otherwise an invalid subnet is + * created. + * @param[in] mask CIDR mask, must be in [0, 32] for IPv4 addresses and in [0, 128] for + * IPv6 addresses. Otherwise an invalid subnet is created. + */ CSubNet(const CNetAddr& addr, uint8_t mask); + + /** + * Construct from a given network start and mask. + * @param[in] addr Network start. Must be IPv4 or IPv6, otherwise an invalid subnet is + * created. + * @param[in] mask Network mask, must be of the same type as `addr` and not contain 0-bits + * followed by 1-bits. Otherwise an invalid subnet is created. + */ CSubNet(const CNetAddr& addr, const CNetAddr& mask); - //constructor for single ip subnet (/32 or /128) + /** + * Construct a single-host subnet. + * @param[in] addr The sole address to be contained in the subnet, can also be non-IPv[46]. + */ explicit CSubNet(const CNetAddr& addr); bool Match(const CNetAddr &addr) const; diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index f5d26fafef..36f18fcf67 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -224,8 +224,22 @@ BOOST_AUTO_TEST_CASE(subnet_test) // IPv4 address with IPv6 netmask or the other way around. BOOST_CHECK(!CSubNet(ResolveIP("1.1.1.1"), ResolveIP("ffff::")).IsValid()); BOOST_CHECK(!CSubNet(ResolveIP("::1"), ResolveIP("255.0.0.0")).IsValid()); - // Can't subnet TOR (or any other non-IPv4 and non-IPv6 network). - BOOST_CHECK(!CSubNet(ResolveIP("5wyqrzbvrdsumnok.onion"), ResolveIP("255.0.0.0")).IsValid()); + + // Create Non-IP subnets. + + const CNetAddr tor_addr{ + ResolveIP("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion")}; + + subnet = CSubNet(tor_addr); + BOOST_CHECK(subnet.IsValid()); + BOOST_CHECK_EQUAL(subnet.ToString(), tor_addr.ToString()); + BOOST_CHECK(subnet.Match(tor_addr)); + BOOST_CHECK( + !subnet.Match(ResolveIP("kpgvmscirrdqpekbqjsvw5teanhatztpp2gl6eee4zkowvwfxwenqaid.onion"))); + BOOST_CHECK(!subnet.Match(ResolveIP("1.2.3.4"))); + + BOOST_CHECK(!CSubNet(tor_addr, 200).IsValid()); + BOOST_CHECK(!CSubNet(tor_addr, ResolveIP("255.0.0.0")).IsValid()); subnet = ResolveSubNet("1.2.3.4/255.255.255.255"); BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/32"); @@ -440,8 +454,7 @@ BOOST_AUTO_TEST_CASE(netbase_dont_resolve_strings_with_embedded_nul_characters) BOOST_CHECK(!LookupSubNet(std::string("1.2.3.0/24\0", 11), ret)); BOOST_CHECK(!LookupSubNet(std::string("1.2.3.0/24\0example.com", 22), ret)); BOOST_CHECK(!LookupSubNet(std::string("1.2.3.0/24\0example.com\0", 23), ret)); - // We only do subnetting for IPv4 and IPv6 - BOOST_CHECK(!LookupSubNet(std::string("5wyqrzbvrdsumnok.onion", 22), ret)); + BOOST_CHECK(LookupSubNet(std::string("5wyqrzbvrdsumnok.onion", 22), ret)); BOOST_CHECK(!LookupSubNet(std::string("5wyqrzbvrdsumnok.onion\0", 23), ret)); BOOST_CHECK(!LookupSubNet(std::string("5wyqrzbvrdsumnok.onion\0example.com", 34), ret)); BOOST_CHECK(!LookupSubNet(std::string("5wyqrzbvrdsumnok.onion\0example.com\0", 35), ret)); From de31f16d6098eb83ff2aa5a2f9851873b566ce51 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Sun, 10 Jan 2021 15:51:25 +0100 Subject: [PATCH 46/84] test: add test for banning of non-IP addresses Co-authored-by: Jon Atack Github-Pull: #20852 Rebased-From: 39b43298d9c54f9c18bef36f3d5934f57aefd088 (cherry picked from commit bdce029191ab094a4a325b143324487f1c62ba7c) --- test/functional/rpc_setban.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/functional/rpc_setban.py b/test/functional/rpc_setban.py index bc48449084..551eb4d724 100755 --- a/test/functional/rpc_setban.py +++ b/test/functional/rpc_setban.py @@ -15,6 +15,9 @@ class SetBanTests(BitcoinTestFramework): self.setup_clean_chain = True self.extra_args = [[],[]] + def is_banned(self, node, addr): + return any(e['address'] == addr for e in node.listbanned()) + def run_test(self): # Node 0 connects to Node 1, check that the noban permission is not granted self.connect_nodes(0, 1) @@ -42,5 +45,18 @@ class SetBanTests(BitcoinTestFramework): peerinfo = self.nodes[1].getpeerinfo()[0] assert(not 'noban' in peerinfo['permissions']) + self.log.info("Test that a non-IP address can be banned/unbanned") + node = self.nodes[1] + tor_addr = "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion" + ip_addr = "1.2.3.4" + assert(not self.is_banned(node, tor_addr)) + assert(not self.is_banned(node, ip_addr)) + node.setban(tor_addr, "add") + assert(self.is_banned(node, tor_addr)) + assert(not self.is_banned(node, ip_addr)) + node.setban(tor_addr, "remove") + assert(not self.is_banned(self.nodes[1], tor_addr)) + assert(not self.is_banned(node, ip_addr)) + if __name__ == '__main__': SetBanTests().main() From 62c12bde50c8528321b20b013a279031cd22da8b Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 9 Dec 2020 22:50:31 +0000 Subject: [PATCH 47/84] Bugfix: GUI: Restore SendConfirmationDialog button default to "Yes" The SendConfirmationDialog is used for bumping the fee, where "Send" doesn't really make sense Github-Pull: #bitcoin-core/gui#148 Rebased-From: 8775691383ff394b998232ac8e63fac3a214d18b (cherry picked from commit 7bf3ed495b96f0959d5c45c6e1936d8628dec730) --- src/qt/sendcoinsdialog.cpp | 3 +++ src/qt/sendcoinsdialog.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 4c39372611..37c28f62cb 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -981,6 +981,9 @@ SendConfirmationDialog::SendConfirmationDialog(const QString& title, const QStri setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel); setDefaultButton(QMessageBox::Cancel); yesButton = button(QMessageBox::Yes); + if (confirmButtonText.isEmpty()) { + confirmButtonText = yesButton->text(); + } updateYesButton(); connect(&countDownTimer, &QTimer::timeout, this, &SendConfirmationDialog::countDown); } diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h index 8519f1f65b..8863d2e5c8 100644 --- a/src/qt/sendcoinsdialog.h +++ b/src/qt/sendcoinsdialog.h @@ -115,7 +115,7 @@ class SendConfirmationDialog : public QMessageBox Q_OBJECT public: - SendConfirmationDialog(const QString& title, const QString& text, const QString& informative_text = "", const QString& detailed_text = "", int secDelay = SEND_CONFIRM_DELAY, const QString& confirmText = "Send", QWidget* parent = nullptr); + SendConfirmationDialog(const QString& title, const QString& text, const QString& informative_text = "", const QString& detailed_text = "", int secDelay = SEND_CONFIRM_DELAY, const QString& confirmText = "", QWidget* parent = nullptr); int exec() override; private Q_SLOTS: From c89caab2836afc4842792a5caffef744bce98347 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Fri, 1 Jan 2021 12:36:00 +0200 Subject: [PATCH 48/84] qt: Use layout manager for Create Wallet dialog Github-Pull: bitcoin-core/gui#171 Rebased-From: d4feb6812a2707ef85d75dda4372086ec62eb922 (cherry picked from commit 0dba346a568882434098dd08566978e23eb4a516) --- src/qt/forms/createwalletdialog.ui | 253 ++++++++++++++--------------- 1 file changed, 124 insertions(+), 129 deletions(-) diff --git a/src/qt/forms/createwalletdialog.ui b/src/qt/forms/createwalletdialog.ui index 0b33c2cb8d..881869a46c 100644 --- a/src/qt/forms/createwalletdialog.ui +++ b/src/qt/forms/createwalletdialog.ui @@ -7,140 +7,135 @@ 0 0 364 - 213 + 249 Create Wallet - - - - 10 - 170 - 341 - 32 - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - 120 - 20 - 231 - 24 - - - - Wallet - - - - - - 20 - 20 - 101 - 21 - - - - Wallet Name - - - - - - 20 - 50 - 220 - 22 - - - - Encrypt the wallet. The wallet will be encrypted with a passphrase of your choice. - - - Encrypt Wallet - - - false - - - - - - 20 - 90 - 220 - 21 - - - - font-weight:bold; - - - Advanced options - - - - - true - - - - 20 - 115 - 220 - 22 - - - - Disable private keys for this wallet. Wallets with private keys disabled will have no private keys and cannot have an HD seed or imported private keys. This is ideal for watch-only wallets. - - - Disable Private Keys - - - - - - 20 - 135 - 220 - 22 - - - - Make a blank wallet. Blank wallets do not initially have private keys or scripts. Private keys and addresses can be imported, or an HD seed can be set, at a later time. - - - Make Blank Wallet - - - - - - 20 - 155 - 220 - 22 - - - - Use descriptors for scriptPubKey management - - - Descriptor Wallet - - + + true + + + + + + + + Wallet Name + + + + + + + + 262 + 0 + + + + Wallet + + + + + + + + + Encrypt the wallet. The wallet will be encrypted with a passphrase of your choice. + + + Encrypt Wallet + + + false + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 8 + + + + + + + + Advanced Options + + + + + + true + + + Disable private keys for this wallet. Wallets with private keys disabled will have no private keys and cannot have an HD seed or imported private keys. This is ideal for watch-only wallets. + + + Disable Private Keys + + + + + + + Make a blank wallet. Blank wallets do not initially have private keys or scripts. Private keys and addresses can be imported, or an HD seed can be set, at a later time. + + + Make Blank Wallet + + + + + + + Use descriptors for scriptPubKey management + + + Descriptor Wallet + + + + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + wallet_name_line_edit From 5823cc3b43f0493dd540fb1327322908f95d633f Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sun, 3 Jan 2021 11:27:19 +0200 Subject: [PATCH 49/84] qt: Add TransactionOverviewWidget class Github-Pull: bitcoin-core/gui#176 Rebased-From: d43992140679fb9a5ebc7850923679033f9837f3 (cherry picked from commit b7086e69ff3825c3f3bfde4ca9af90663a4575dd) --- src/Makefile.qt.include | 2 ++ src/qt/forms/overviewpage.ui | 12 ++++++++- src/qt/overviewpage.cpp | 3 ++- src/qt/transactionoverviewwidget.h | 41 ++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 src/qt/transactionoverviewwidget.h diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 9d2f644704..d50d78eb6d 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -77,6 +77,7 @@ QT_MOC_CPP = \ qt/moc_transactiondesc.cpp \ qt/moc_transactiondescdialog.cpp \ qt/moc_transactionfilterproxy.cpp \ + qt/moc_transactionoverviewwidget.cpp \ qt/moc_transactiontablemodel.cpp \ qt/moc_transactionview.cpp \ qt/moc_utilitydialog.cpp \ @@ -150,6 +151,7 @@ BITCOIN_QT_H = \ qt/transactiondesc.h \ qt/transactiondescdialog.h \ qt/transactionfilterproxy.h \ + qt/transactionoverviewwidget.h \ qt/transactionrecord.h \ qt/transactiontablemodel.h \ qt/transactionview.h \ diff --git a/src/qt/forms/overviewpage.ui b/src/qt/forms/overviewpage.ui index f36d2dab73..8296a4a9bc 100644 --- a/src/qt/forms/overviewpage.ui +++ b/src/qt/forms/overviewpage.ui @@ -610,7 +610,7 @@ - + QListView { background: transparent; } @@ -626,6 +626,9 @@ QAbstractItemView::NoSelection + + true + @@ -639,6 +642,13 @@ + + + TransactionOverviewWidget + QListView +
qt/transactionoverviewwidget.h
+
+
diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 8dc2b7eaee..a8cc5c2d1f 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -133,7 +134,7 @@ 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, &QListView::clicked, this, &OverviewPage::handleTransactionClicked); + connect(ui->listTransactions, &TransactionOverviewWidget::clicked, this, &OverviewPage::handleTransactionClicked); // start with displaying the "out of sync" warnings showOutOfSyncWarning(true); diff --git a/src/qt/transactionoverviewwidget.h b/src/qt/transactionoverviewwidget.h new file mode 100644 index 0000000000..2bdead7bc4 --- /dev/null +++ b/src/qt/transactionoverviewwidget.h @@ -0,0 +1,41 @@ +// Copyright (c) 2021 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_QT_TRANSACTIONOVERVIEWWIDGET_H +#define BITCOIN_QT_TRANSACTIONOVERVIEWWIDGET_H + +#include + +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QShowEvent; +class QWidget; +QT_END_NAMESPACE + +class TransactionOverviewWidget : public QListView +{ + Q_OBJECT + +public: + explicit TransactionOverviewWidget(QWidget* parent = nullptr) : QListView(parent) {} + + QSize sizeHint() const override + { + return {sizeHintForColumn(TransactionTableModel::ToAddress), QListView::sizeHint().height()}; + } + +protected: + void showEvent(QShowEvent* event) override + { + Q_UNUSED(event); + QSizePolicy sp = sizePolicy(); + sp.setHorizontalPolicy(QSizePolicy::Minimum); + setSizePolicy(sp); + } +}; + +#endif // BITCOIN_QT_TRANSACTIONOVERVIEWWIDGET_H From 2ccf3823cf6f0486753887787e814dbf8d4e47ab Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sat, 2 Jan 2021 21:00:46 +0200 Subject: [PATCH 50/84] qt: Fix TxViewDelegate layout This change (1) prevents overlapping date and amount strings, and (2) guaranties that "eye" sign at the end of the watch-only address/label is always visible. Github-Pull: bitcoin-core/gui#176 Rebased-From: f0d04795e23606399414d074d78efe5aa0da7259 (cherry picked from commit 7bc4498234e16bc75975555cbe7855384489782f) --- src/qt/forms/overviewpage.ui | 3 +++ src/qt/overviewpage.cpp | 35 +++++++++++++++++++++++++++++------ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/qt/forms/overviewpage.ui b/src/qt/forms/overviewpage.ui index 8296a4a9bc..e76de0f1bf 100644 --- a/src/qt/forms/overviewpage.ui +++ b/src/qt/forms/overviewpage.ui @@ -623,6 +623,9 @@ Qt::ScrollBarAlwaysOff + + QAbstractScrollArea::AdjustToContents + QAbstractItemView::NoSelection diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index a8cc5c2d1f..1c31f6a82c 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -23,6 +23,9 @@ #include #include +#include +#include + #define DECORATION_SIZE 54 #define NUM_ITEMS 5 @@ -36,7 +39,7 @@ public: QAbstractItemDelegate(parent), unit(BitcoinUnits::BTC), platformStyle(_platformStyle) { - + connect(this, &TxViewDelegate::width_changed, this, &TxViewDelegate::sizeHintChanged); } inline void paint(QPainter *painter, const QStyleOptionViewItem &option, @@ -69,13 +72,15 @@ public: painter->setPen(foreground); QRect boundingRect; - painter->drawText(addressRect, Qt::AlignLeft|Qt::AlignVCenter, address, &boundingRect); + painter->drawText(addressRect, Qt::AlignLeft | Qt::AlignVCenter, address, &boundingRect); + int address_rect_min_width = boundingRect.width(); if (index.data(TransactionTableModel::WatchonlyRole).toBool()) { QIcon iconWatchonly = qvariant_cast(index.data(TransactionTableModel::WatchonlyDecorationRole)); QRect watchonlyRect(boundingRect.right() + 5, mainRect.top()+ypad+halfheight, 16, halfheight); iconWatchonly.paint(painter, watchonlyRect); + address_rect_min_width += 5 + watchonlyRect.width(); } if(amount < 0) @@ -92,23 +97,41 @@ public: } painter->setPen(foreground); QString amountText = index.sibling(index.row(), TransactionTableModel::Amount).data(Qt::DisplayRole).toString(); - painter->drawText(amountRect, Qt::AlignRight|Qt::AlignVCenter, amountText); + QRect amount_bounding_rect; + painter->drawText(amountRect, Qt::AlignRight | Qt::AlignVCenter, amountText, &amount_bounding_rect); painter->setPen(option.palette.color(QPalette::Text)); - painter->drawText(amountRect, Qt::AlignLeft|Qt::AlignVCenter, GUIUtil::dateTimeStr(date)); + QRect date_bounding_rect; + painter->drawText(amountRect, Qt::AlignLeft | Qt::AlignVCenter, GUIUtil::dateTimeStr(date), &date_bounding_rect); + + const int minimum_width = std::max(address_rect_min_width, amount_bounding_rect.width() + date_bounding_rect.width()); + const auto search = m_minimum_width.find(index.row()); + if (search == m_minimum_width.end() || search->second != minimum_width) { + m_minimum_width[index.row()] = minimum_width; + Q_EMIT width_changed(index); + } painter->restore(); } inline QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override { - return QSize(DECORATION_SIZE, DECORATION_SIZE); + const auto search = m_minimum_width.find(index.row()); + const int minimum_text_width = search == m_minimum_width.end() ? 0 : search->second; + return {DECORATION_SIZE + 8 + minimum_text_width, DECORATION_SIZE}; } int unit; - const PlatformStyle *platformStyle; +Q_SIGNALS: + //! An intermediate signal for emitting from the `paint() const` member function. + void width_changed(const QModelIndex& index) const; + +private: + const PlatformStyle* platformStyle; + mutable std::map m_minimum_width; }; + #include OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent) : From ce108b00610850b5bbeb05e16705f8061e4c2f38 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Tue, 5 Jan 2021 22:33:28 +0200 Subject: [PATCH 51/84] qt: Stop the effect of hidden widgets on the size of QStackedWidget Layouts of the hidden widgets, those are children of QStackedWidget, could prevent to adjust the size of the parent widget in the WalletFrame widget. Github-Pull: bitcoin-core/gui#176 Rebased-From: af58f5b12cea91467692dd4ae71d8cc916a608ed (cherry picked from commit bdc64c9030488e7a6b88f369fb876c0b21c04a25) --- src/qt/walletframe.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp index 4a9b4a5c84..eaa18b03a3 100644 --- a/src/qt/walletframe.cpp +++ b/src/qt/walletframe.cpp @@ -106,9 +106,24 @@ void WalletFrame::setCurrentWallet(WalletModel* wallet_model) { if (mapWalletViews.count(wallet_model) == 0) return; + // Stop the effect of hidden widgets on the size hint of the shown one in QStackedWidget. + WalletView* view_about_to_hide = currentWalletView(); + if (view_about_to_hide) { + QSizePolicy sp = view_about_to_hide->sizePolicy(); + sp.setHorizontalPolicy(QSizePolicy::Ignored); + view_about_to_hide->setSizePolicy(sp); + } + WalletView *walletView = mapWalletViews.value(wallet_model); - walletStack->setCurrentWidget(walletView); assert(walletView); + + // Set or restore the default QSizePolicy which could be set to QSizePolicy::Ignored previously. + QSizePolicy sp = walletView->sizePolicy(); + sp.setHorizontalPolicy(QSizePolicy::Preferred); + walletView->setSizePolicy(sp); + walletView->updateGeometry(); + + walletStack->setCurrentWidget(walletView); walletView->updateEncryptionStatus(); } From 640b94fe9a7f83187e58e3b19105b8a5bd7539ec Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Thu, 21 Jan 2021 23:09:17 +0200 Subject: [PATCH 52/84] Fix MSVC build after gui#176 Github-Pull: #20983 Rebased-From: c5354e4641d8a92807e4183894d4bb32241e4b5b (cherry picked from commit a98f211940dc6eaed8050263efad7656126b7b3e) --- build_msvc/libbitcoin_qt/libbitcoin_qt.vcxproj | 1 + 1 file changed, 1 insertion(+) diff --git a/build_msvc/libbitcoin_qt/libbitcoin_qt.vcxproj b/build_msvc/libbitcoin_qt/libbitcoin_qt.vcxproj index 6a3c9f1dc1..490ce8b1ce 100644 --- a/build_msvc/libbitcoin_qt/libbitcoin_qt.vcxproj +++ b/build_msvc/libbitcoin_qt/libbitcoin_qt.vcxproj @@ -104,6 +104,7 @@ + From b514a872c394313e258ad4fbacc2046d4555a64a Mon Sep 17 00:00:00 2001 From: randymcmillan Date: Tue, 29 Dec 2020 16:54:16 -0500 Subject: [PATCH 53/84] raise helpMessageDialog Github-Pull: bitcoin-core/gui#167 Rebased-From: 77114462f2328914b7a918f40776e522a0898e56 (cherry picked from commit e2ebc8567a96e92d1c039b2e7c5f48826fece810) --- src/qt/bitcoingui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 31c2ffcc31..6f6b68c1a8 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -839,7 +839,7 @@ void BitcoinGUI::showDebugWindowActivateConsole() void BitcoinGUI::showHelpMessageClicked() { - helpMessageDialog->show(); + GUIUtil::bringToFront(helpMessageDialog); } #ifdef ENABLE_WALLET From 9e6c08d514be256e8f1e037efc39ffd9df1b63a4 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Thu, 7 Jan 2021 23:04:56 +0200 Subject: [PATCH 54/84] qt: Use "fusion" style on macOS Big Sur with old Qt The "macintosh" style is broken on macOS Big Sur at least for Qt 5.9.8. Github-Pull: #bitcoin-core/gui#177 Rebased-From: 4e1154dfd128cbada65e9ea08ee274cdeafc4c53 (cherry picked from commit 6dc58e99457fe4609fa3c401e89f98c92dbd9878) --- src/qt/bitcoin.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 2a5965153d..224c7e9ca7 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #if defined(QT_STATICPLUGIN) #include @@ -443,6 +444,13 @@ int GuiMain(int argc, char* argv[]) QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); #endif +#if (QT_VERSION <= QT_VERSION_CHECK(5, 9, 8)) && defined(Q_OS_MACOS) + const auto os_name = QSysInfo::prettyProductName(); + if (os_name.startsWith("macOS 11") || os_name.startsWith("macOS 10.16")) { + QApplication::setStyle("fusion"); + } +#endif + BitcoinApplication app; /// 2. Parse command-line options. We do this after qt in order to show an error if there are problems parsing these From 16e2673e24d2031b3107d888b46772d43b6d3a5f Mon Sep 17 00:00:00 2001 From: Bruno Garcia Date: Thu, 4 Feb 2021 10:49:45 -0200 Subject: [PATCH 55/84] fix the unreachable code at feature_taproot Github-Pull: #21081 Rebased-From: 5e0cd25e29541e6c19559fb5c2555e008ed896fa (cherry picked from commit 4607019798c543f046bcd22d5b7c09750e7e0ee2) --- test/functional/feature_taproot.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/functional/feature_taproot.py b/test/functional/feature_taproot.py index ea52769ebb..34604b63e0 100755 --- a/test/functional/feature_taproot.py +++ b/test/functional/feature_taproot.py @@ -531,7 +531,6 @@ def add_spender(spenders, *args, **kwargs): def random_checksig_style(pubkey): """Creates a random CHECKSIG* tapscript that would succeed with only the valid signature on witness stack.""" - return bytes(CScript([pubkey, OP_CHECKSIG])) opcode = random.choice([OP_CHECKSIG, OP_CHECKSIGVERIFY, OP_CHECKSIGADD]) if (opcode == OP_CHECKSIGVERIFY): ret = CScript([pubkey, opcode, OP_1]) From f0dec76142db79c98d26b7312b424cf9de8b1fd0 Mon Sep 17 00:00:00 2001 From: practicalswift Date: Sun, 31 Jan 2021 21:03:05 +0000 Subject: [PATCH 56/84] net: Avoid UBSan warning in ProcessMessage(...) Github-Pull: #21043 Rebased-From: f5f2f9716885e7548809e77f46b493c896a019bf (cherry picked from commit 95218ee95cdb4046ee7d622eac822e74d94314c7) --- src/net_processing.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 98e3d90c2d..f29be8d8a3 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -2305,6 +2305,9 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat bool fRelay = true; vRecv >> nVersion >> nServiceInt >> nTime >> addrMe; + if (nTime < 0) { + nTime = 0; + } nServices = ServiceFlags(nServiceInt); if (!pfrom.IsInboundConn()) { From 7233f69fc4f496c937e6def586e796cda447d745 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 1 Feb 2021 14:57:34 +0000 Subject: [PATCH 57/84] util: Disallow negative mocktime Signed-off-by: practicalswift Github-Pull: #21043 Rebased-From: 3ddbf22ed179a2db733af4b521bec5d2b13ebf4b (cherry picked from commit 08dada84565ea5f49127123e356c82a150626f3c) --- src/rpc/misc.cpp | 19 +++++++++++-------- src/util/time.cpp | 5 ++++- test/functional/rpc_uptime.py | 5 +++++ 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index f26fffbfc1..2467469d01 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -401,13 +401,13 @@ static RPCHelpMan signmessagewithprivkey() static RPCHelpMan setmocktime() { return RPCHelpMan{"setmocktime", - "\nSet the local time to given timestamp (-regtest only)\n", - { - {"timestamp", RPCArg::Type::NUM, RPCArg::Optional::NO, UNIX_EPOCH_TIME + "\n" - " Pass 0 to go back to using the system time."}, - }, - RPCResult{RPCResult::Type::NONE, "", ""}, - RPCExamples{""}, + "\nSet the local time to given timestamp (-regtest only)\n", + { + {"timestamp", RPCArg::Type::NUM, RPCArg::Optional::NO, UNIX_EPOCH_TIME + "\n" + "Pass 0 to go back to using the system time."}, + }, + RPCResult{RPCResult::Type::NONE, "", ""}, + RPCExamples{""}, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { if (!Params().IsMockableChain()) { @@ -422,7 +422,10 @@ static RPCHelpMan setmocktime() LOCK(cs_main); RPCTypeCheck(request.params, {UniValue::VNUM}); - int64_t time = request.params[0].get_int64(); + const int64_t time{request.params[0].get_int64()}; + if (time < 0) { + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Mocktime can not be negative: %s.", time)); + } SetMockTime(time); if (request.context.Has()) { for (const auto& chain_client : request.context.Get().chain_clients) { diff --git a/src/util/time.cpp b/src/util/time.cpp index e96972fe12..d130e4e4d4 100644 --- a/src/util/time.cpp +++ b/src/util/time.cpp @@ -9,6 +9,8 @@ #include +#include + #include #include #include @@ -18,7 +20,7 @@ void UninterruptibleSleep(const std::chrono::microseconds& n) { std::this_thread::sleep_for(n); } -static std::atomic nMockTime(0); //!< For unit testing +static std::atomic nMockTime(0); //!< For testing int64_t GetTime() { @@ -46,6 +48,7 @@ template std::chrono::microseconds GetTime(); void SetMockTime(int64_t nMockTimeIn) { + Assert(nMockTimeIn >= 0); nMockTime.store(nMockTimeIn, std::memory_order_relaxed); } diff --git a/test/functional/rpc_uptime.py b/test/functional/rpc_uptime.py index e86f91b1d0..6177970872 100755 --- a/test/functional/rpc_uptime.py +++ b/test/functional/rpc_uptime.py @@ -10,6 +10,7 @@ Test corresponds to code in rpc/server.cpp. import time from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_raises_rpc_error class UptimeTest(BitcoinTestFramework): @@ -18,8 +19,12 @@ class UptimeTest(BitcoinTestFramework): self.setup_clean_chain = True def run_test(self): + self._test_negative_time() self._test_uptime() + def _test_negative_time(self): + assert_raises_rpc_error(-8, "Mocktime can not be negative: -1.", self.nodes[0].setmocktime, -1) + def _test_uptime(self): wait_time = 10 self.nodes[0].setmocktime(int(time.time() + wait_time)) From a143b7b87d9b1ab1373e5e0a566a6800f74f217f Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Tue, 16 Feb 2021 13:22:49 -0500 Subject: [PATCH 58/84] Disallow sendtoaddress and sendmany when private keys disabled Github-Pull: #21201 Rebased-From: 0997019e7681efb00847a7246c15ac8f235128d8 (cherry picked from commit d6b5eb5fcc8e8f7f0ab778f32d49aabf6e04d80d) --- src/wallet/rpcwallet.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 58f36dde23..b4f1f207a2 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -447,6 +447,12 @@ UniValue SendMoney(CWallet* const pwallet, const CCoinControl &coin_control, std { EnsureWalletIsUnlocked(pwallet); + // This function is only used by sendtoaddress and sendmany. + // This should always try to sign, if we don't have private keys, don't try to do anything here. + if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) { + throw JSONRPCError(RPC_WALLET_ERROR, "Error: Private keys are disabled for this wallet"); + } + // Shuffle recipient list std::shuffle(recipients.begin(), recipients.end(), FastRandomContext()); @@ -458,7 +464,7 @@ UniValue SendMoney(CWallet* const pwallet, const CCoinControl &coin_control, std FeeCalculation fee_calc_out; auto blind_details = g_con_elementsmode ? MakeUnique() : nullptr; if (blind_details) blind_details->ignore_blind_failure = ignore_blind_fail; - bool fCreated = pwallet->CreateTransaction(recipients, tx, nFeeRequired, nChangePosRet, error, coin_control, fee_calc_out, !pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS), blind_details.get()); + const bool fCreated = pwallet->CreateTransaction(recipients, tx, nFeeRequired, nChangePosRet, error, coin_control, fee_calc_out, true, blind_details.get()); if (!fCreated) { throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, error.original); } From 08298c34d8a37cbda9824182713495e9855be6eb Mon Sep 17 00:00:00 2001 From: Jon Atack Date: Tue, 16 Feb 2021 20:41:21 +0100 Subject: [PATCH 59/84] test: disallow sendtoaddress/sendmany when private keys disabled Github-Pull: #21201 Rebased-From: 6bfbc97d716faad38c87603ac6049d222236d623 (cherry picked from commit 4ef1e4bd407ccf80b2a1d40e946e2ac832e624e5) --- test/functional/wallet_watchonly.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/functional/wallet_watchonly.py b/test/functional/wallet_watchonly.py index 10b479e00a..79516686ee 100755 --- a/test/functional/wallet_watchonly.py +++ b/test/functional/wallet_watchonly.py @@ -2,7 +2,7 @@ # Copyright (c) 2018-2019 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 createwallet arguments. +"""Test createwallet watchonly arguments. """ from test_framework.test_framework import BitcoinTestFramework @@ -50,6 +50,11 @@ class CreateWalletWatchonlyTest(BitcoinTestFramework): assert_equal(len(wo_wallet.listtransactions()), 1) assert_equal(wo_wallet.getbalance(include_watchonly=False)['bitcoin'], 0) + self.log.info('Test sending from a watch-only wallet raises RPC error') + msg = "Error: Private keys are disabled for this wallet" + assert_raises_rpc_error(-4, msg, wo_wallet.sendtoaddress, a1, 0.1) + assert_raises_rpc_error(-4, msg, wo_wallet.sendmany, amounts={a1: 0.1}) + self.log.info('Testing listreceivedbyaddress watch-only defaults') result = wo_wallet.listreceivedbyaddress() assert_equal(len(result), 1) From c4494ede6bb602f6a1c38d3104dbf8889e9a4123 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Thu, 3 Dec 2020 14:43:03 -0500 Subject: [PATCH 60/84] tests: Test that a fully signed tx given to signrawtx is unchanged Tests that a fully signed transaction given to signrawtransactionwithwallet is both unchanged and marked as complete. This tests for a regression in 0.20 where the transaction would not be marked as complete. Github-Pull: #20562 Rebased-From: 773c42b265fb2212b5cb8785b7226a206d063543 (cherry picked from commit 36ecf5eb8752890fdffd617c9fedb08033607f99) --- test/functional/rpc_signrawtransaction.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/functional/rpc_signrawtransaction.py b/test/functional/rpc_signrawtransaction.py index 2b18433619..cbc7f0524a 100755 --- a/test/functional/rpc_signrawtransaction.py +++ b/test/functional/rpc_signrawtransaction.py @@ -161,6 +161,19 @@ class SignRawTransactionsTest(BitcoinTestFramework): assert_equal(rawTxSigned['errors'][1]['witness'], ["304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de67eebee01", "025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357"]) assert not rawTxSigned['errors'][0]['witness'] + def test_fully_signed_tx(self): + self.log.info("Test signing a fully signed transaction does nothing") + self.nodes[0].walletpassphrase("password", 9999) + self.nodes[0].generate(101) + rawtx = self.nodes[0].createrawtransaction([], [{self.nodes[0].getnewaddress(): 10}]) + fundedtx = self.nodes[0].fundrawtransaction(rawtx) + signedtx = self.nodes[0].signrawtransactionwithwallet(fundedtx["hex"]) + assert_equal(signedtx["complete"], True) + signedtx2 = self.nodes[0].signrawtransactionwithwallet(signedtx["hex"]) + assert_equal(signedtx2["complete"], True) + assert_equal(signedtx["hex"], signedtx2["hex"]) + self.nodes[0].walletlock() + def witness_script_test(self): self.log.info("Test signing transaction to P2SH-P2WSH addresses without wallet") # Create a new P2SH-P2WSH 1-of-1 multisig address: @@ -314,6 +327,7 @@ class SignRawTransactionsTest(BitcoinTestFramework): self.witness_script_test() self.OP_1NEGATE_test() self.test_with_lock_outputs() + self.test_fully_signed_tx() # Blinded descriptors not supported yet if not self.options.descriptors: From 337297d605750999c51ddb03644596a455d825dc Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Mon, 18 Jan 2021 20:38:28 -0500 Subject: [PATCH 61/84] GUI: Write PSBTs to file with binary mode Github-Pull: #bitcoin-core/gui#188 Rebased-From: cc3971c9ff538a924c1a76ca1352bcaeb24f579f (cherry picked from commit 3a126724195fcf00d84e852a9247475fccd14f38) --- src/qt/psbtoperationsdialog.cpp | 2 +- src/qt/sendcoinsdialog.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/psbtoperationsdialog.cpp b/src/qt/psbtoperationsdialog.cpp index 1ab8edd367..904ca3d97d 100644 --- a/src/qt/psbtoperationsdialog.cpp +++ b/src/qt/psbtoperationsdialog.cpp @@ -145,7 +145,7 @@ void PSBTOperationsDialog::saveTransaction() { if (filename.isEmpty()) { return; } - std::ofstream out(filename.toLocal8Bit().data()); + std::ofstream out(filename.toLocal8Bit().data(), std::ofstream::out | std::ofstream::binary); out << ssTx.str(); out.close(); showStatus(tr("PSBT saved to disk."), StatusLevel::INFO); diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 37c28f62cb..f161a6d6e5 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -435,7 +435,7 @@ void SendCoinsDialog::on_sendButton_clicked() if (filename.isEmpty()) { return; } - std::ofstream out(filename.toLocal8Bit().data()); + std::ofstream out(filename.toLocal8Bit().data(), std::ofstream::out | std::ofstream::binary); out << ssTx.str(); out.close(); Q_EMIT message(tr("PSBT saved"), "PSBT saved to disk", CClientUIInterface::MSG_INFORMATION); From 969357988d4f5d276ca85e215f735262ba2388e7 Mon Sep 17 00:00:00 2001 From: Aaron Clauson Date: Mon, 15 Mar 2021 17:18:42 +0000 Subject: [PATCH 62/84] Update vcpkg checkout commit. Previously vcpkg was relying on https://repo.msys2.org/mingw/i686/mingw-w64-i686-pkg-config-0.29.2-1-any.pkg.tar.xz which is no longer available. The vcpkg source has been updated to use http://repo.msys2.org/mingw/i686/mingw-w64-i686-pkg-config-0.29.2-2-any.pkg.tar.zst. This PR updates the commit ID used to checkout vcpkg for the updated URL. Github-Pull: #21446 Rebased-From: b9e3f3530611d5fbb799a401b839ee23e3eba835 (cherry picked from commit b35711efdebc4e95906b1e809e711bc707852f2d) --- .appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.appveyor.yml b/.appveyor.yml index 7250d4ad94..097874b17a 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -10,7 +10,7 @@ environment: QT_DOWNLOAD_URL: 'https://github.com/sipsorcery/qt_win_binary/releases/download/qt598x64_vs2019_v1681/qt598_x64_vs2019_1681.zip' QT_DOWNLOAD_HASH: '00cf7327818c07d74e0b1a4464ffe987c2728b00d49d4bf333065892af0515c3' QT_LOCAL_PATH: 'C:\Qt5.9.8_x64_static_vs2019' - VCPKG_TAG: '2020.11-1' + VCPKG_TAG: '75522bb1f2e7d863078bcd06322348f053a9e33f' install: # Disable zmq test for now since python zmq library on Windows would cause Access violation sometimes. # - cmd: pip install zmq From 4940b460c44b0d7c61db06cb83a4af1cfca1b375 Mon Sep 17 00:00:00 2001 From: Jon Atack Date: Mon, 8 Mar 2021 00:22:57 +0100 Subject: [PATCH 63/84] doc: add signet to share/examples/bitcoin.conf Github-Pull: #21384 Rebased-From: 21b6a233734da1601846a16a741b108522901782 (cherry picked from commit 58975d5c0abeab8cb66f6006ee558d4bb7cc12b5) --- share/examples/bitcoin.conf | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/share/examples/bitcoin.conf b/share/examples/bitcoin.conf index 90a592cc63..5b7fc776a4 100644 --- a/share/examples/bitcoin.conf +++ b/share/examples/bitcoin.conf @@ -4,13 +4,16 @@ # Network-related settings: -# Note that if you use testnet or regtest, particularly with the options +# Note that if you use testnet, signet or regtest, particularly with the options # addnode, connect, port, bind, rpcport, rpcbind or wallet, you will also # want to read "[Sections]" further down. -# Run on the test network instead of the real bitcoin network. +# Run on the testnet network #testnet=0 +# Run on a signet network +#signet=0 + # Run a regression test network #regtest=0 @@ -57,7 +60,7 @@ # Listening mode, enabled by default except when 'connect' is being used #listen=1 -# Port on which to listen for connections (default: 8333, testnet: 18333, regtest: 18444) +# Port on which to listen for connections (default: 8333, testnet: 18333, signet: 38333, regtest: 18444) #port= # Maximum number of inbound+outbound connections. @@ -155,7 +158,7 @@ #minimizetotray=1 # [Sections] -# Most options apply to mainnet, testnet and regtest. +# Most options apply to mainnet, testnet, signet and regtest. # If you want to confine an option to just one network, you should add it in the # relevant section below. # EXCEPTIONS: The options addnode, connect, port, bind, rpcport, rpcbind and wallet @@ -167,5 +170,8 @@ # Options only for testnet [test] +# Options only for signet +[signet] + # Options only for regtest [regtest] From cdb30c3787077da93a71397105cc30f906154d82 Mon Sep 17 00:00:00 2001 From: Jon Atack Date: Mon, 8 Mar 2021 00:43:53 +0100 Subject: [PATCH 64/84] doc: add signet to doc/bitcoin-conf.md Github-Pull: #21384 Rebased-From: 4a285107c11edde2cfc8adfa831c5448c93798d3 (cherry picked from commit 6746cd078be8a15c69f8f5ba5253b1768d0acf21) --- doc/bitcoin-conf.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/bitcoin-conf.md b/doc/bitcoin-conf.md index f4a8edec75..9a312bc33c 100644 --- a/doc/bitcoin-conf.md +++ b/doc/bitcoin-conf.md @@ -27,7 +27,7 @@ Comments may appear in two ways: ### Network specific options Network specific options can be: -- placed into sections with headers `[main]` (not `[mainnet]`), `[test]` (not `[testnet]`) or `[regtest]`; +- placed into sections with headers `[main]` (not `[mainnet]`), `[test]` (not `[testnet]`), `[signet]` or `[regtest]`; - prefixed with a chain name; e.g., `regtest.maxmempool=100`. Network specific options take precedence over non-network specific options. From 07745976c7458d301b76ff209ea5f5b4ae6f18f5 Mon Sep 17 00:00:00 2001 From: practicalswift Date: Mon, 21 Dec 2020 23:19:33 +0000 Subject: [PATCH 65/84] fuzz: Update FuzzedDataProvider.h from upstream (LLVM) Upstream revision: https://github.com/llvm/llvm-project/blob/6d0488f75bb2f37bcfe93fc8f59f6e78c9a0c939/compiler-rt/include/fuzzer/FuzzedDataProvider.h Changes: * [compiler-rt] FuzzedDataProvider: add ConsumeData and method. * [compiler-rt] Fix a typo in a comment in FuzzedDataProvider.h. * [compiler-rt] Add ConsumeRandomLengthString() version without arguments. * [compiler-rt] Refactor FuzzedDataProvider for better readability. * [compiler-rt] FuzzedDataProvider: make linter happy. * [compiler-rt] Mark FDP non-template methods inline to avoid ODR violations. Github-Pull: #20740 Rebased-From: e3d2ba7c70b13a2165020e45abf02373a1e953f7 (cherry picked from commit a48c9d31610cab3ddd4f7334e83db5cf4f184df1) --- src/test/fuzz/FuzzedDataProvider.h | 564 +++++++++++++++++------------ 1 file changed, 323 insertions(+), 241 deletions(-) diff --git a/src/test/fuzz/FuzzedDataProvider.h b/src/test/fuzz/FuzzedDataProvider.h index 9694824633..208f551bd8 100644 --- a/src/test/fuzz/FuzzedDataProvider.h +++ b/src/test/fuzz/FuzzedDataProvider.h @@ -35,208 +35,47 @@ class FuzzedDataProvider { : data_ptr_(data), remaining_bytes_(size) {} ~FuzzedDataProvider() = default; - // Returns a std::vector containing |num_bytes| of input data. If fewer than - // |num_bytes| of data remain, returns a shorter std::vector containing all - // of the data that's left. Can be used with any byte sized type, such as - // char, unsigned char, uint8_t, etc. - template std::vector ConsumeBytes(size_t num_bytes) { - num_bytes = std::min(num_bytes, remaining_bytes_); - return ConsumeBytes(num_bytes, num_bytes); - } + // See the implementation below (after the class definition) for more verbose + // comments for each of the methods. - // Similar to |ConsumeBytes|, but also appends the terminator value at the end - // of the resulting vector. Useful, when a mutable null-terminated C-string is - // needed, for example. But that is a rare case. Better avoid it, if possible, - // and prefer using |ConsumeBytes| or |ConsumeBytesAsString| methods. + // Methods returning std::vector of bytes. These are the most popular choice + // when splitting fuzzing input into pieces, as every piece is put into a + // separate buffer (i.e. ASan would catch any under-/overflow) and the memory + // will be released automatically. + template std::vector ConsumeBytes(size_t num_bytes); template - std::vector ConsumeBytesWithTerminator(size_t num_bytes, - T terminator = 0) { - num_bytes = std::min(num_bytes, remaining_bytes_); - std::vector result = ConsumeBytes(num_bytes + 1, num_bytes); - result.back() = terminator; - return result; - } + std::vector ConsumeBytesWithTerminator(size_t num_bytes, T terminator = 0); + template std::vector ConsumeRemainingBytes(); - // Returns a std::string containing |num_bytes| of input data. Using this and - // |.c_str()| on the resulting string is the best way to get an immutable - // null-terminated C string. If fewer than |num_bytes| of data remain, returns - // a shorter std::string containing all of the data that's left. - std::string ConsumeBytesAsString(size_t num_bytes) { - static_assert(sizeof(std::string::value_type) == sizeof(uint8_t), - "ConsumeBytesAsString cannot convert the data to a string."); + // Methods returning strings. Use only when you need a std::string or a null + // terminated C-string. Otherwise, prefer the methods returning std::vector. + std::string ConsumeBytesAsString(size_t num_bytes); + std::string ConsumeRandomLengthString(size_t max_length); + std::string ConsumeRandomLengthString(); + std::string ConsumeRemainingBytesAsString(); - num_bytes = std::min(num_bytes, remaining_bytes_); - std::string result( - reinterpret_cast(data_ptr_), - num_bytes); - Advance(num_bytes); - return result; - } + // Methods returning integer values. + template T ConsumeIntegral(); + template T ConsumeIntegralInRange(T min, T max); - // Returns a number in the range [min, max] by consuming bytes from the - // input data. The value might not be uniformly distributed in the given - // range. If there's no input data left, always returns |min|. |min| must - // be less than or equal to |max|. - template T ConsumeIntegralInRange(T min, T max) { - static_assert(std::is_integral::value, "An integral type is required."); - static_assert(sizeof(T) <= sizeof(uint64_t), "Unsupported integral type."); + // Methods returning floating point values. + template T ConsumeFloatingPoint(); + template T ConsumeFloatingPointInRange(T min, T max); - if (min > max) - abort(); + // 0 <= return value <= 1. + template T ConsumeProbability(); - // Use the biggest type possible to hold the range and the result. - uint64_t range = static_cast(max) - min; - uint64_t result = 0; - size_t offset = 0; + bool ConsumeBool(); - while (offset < sizeof(T) * CHAR_BIT && (range >> offset) > 0 && - remaining_bytes_ != 0) { - // Pull bytes off the end of the seed data. Experimentally, this seems to - // allow the fuzzer to more easily explore the input space. This makes - // sense, since it works by modifying inputs that caused new code to run, - // and this data is often used to encode length of data read by - // |ConsumeBytes|. Separating out read lengths makes it easier modify the - // contents of the data that is actually read. - --remaining_bytes_; - result = (result << CHAR_BIT) | data_ptr_[remaining_bytes_]; - offset += CHAR_BIT; - } + // Returns a value chosen from the given enum. + template T ConsumeEnum(); - // Avoid division by 0, in case |range + 1| results in overflow. - if (range != std::numeric_limits::max()) - result = result % (range + 1); + // Returns a value from the given array. + template T PickValueInArray(const T (&array)[size]); + template T PickValueInArray(std::initializer_list list); - return static_cast(min + result); - } - - // Returns a std::string of length from 0 to |max_length|. When it runs out of - // input data, returns what remains of the input. Designed to be more stable - // with respect to a fuzzer inserting characters than just picking a random - // length and then consuming that many bytes with |ConsumeBytes|. - std::string ConsumeRandomLengthString(size_t max_length) { - // Reads bytes from the start of |data_ptr_|. Maps "\\" to "\", and maps "\" - // followed by anything else to the end of the string. As a result of this - // logic, a fuzzer can insert characters into the string, and the string - // will be lengthened to include those new characters, resulting in a more - // stable fuzzer than picking the length of a string independently from - // picking its contents. - std::string result; - - // Reserve the anticipated capaticity to prevent several reallocations. - result.reserve(std::min(max_length, remaining_bytes_)); - for (size_t i = 0; i < max_length && remaining_bytes_ != 0; ++i) { - char next = ConvertUnsignedToSigned(data_ptr_[0]); - Advance(1); - if (next == '\\' && remaining_bytes_ != 0) { - next = ConvertUnsignedToSigned(data_ptr_[0]); - Advance(1); - if (next != '\\') - break; - } - result += next; - } - - result.shrink_to_fit(); - return result; - } - - // Returns a std::vector containing all remaining bytes of the input data. - template std::vector ConsumeRemainingBytes() { - return ConsumeBytes(remaining_bytes_); - } - - // Returns a std::string containing all remaining bytes of the input data. - // Prefer using |ConsumeRemainingBytes| unless you actually need a std::string - // object. - std::string ConsumeRemainingBytesAsString() { - return ConsumeBytesAsString(remaining_bytes_); - } - - // Returns a number in the range [Type's min, Type's max]. The value might - // not be uniformly distributed in the given range. If there's no input data - // left, always returns |min|. - template T ConsumeIntegral() { - return ConsumeIntegralInRange(std::numeric_limits::min(), - std::numeric_limits::max()); - } - - // Reads one byte and returns a bool, or false when no data remains. - bool ConsumeBool() { return 1 & ConsumeIntegral(); } - - // Returns a copy of the value selected from the given fixed-size |array|. - template - T PickValueInArray(const T (&array)[size]) { - static_assert(size > 0, "The array must be non empty."); - return array[ConsumeIntegralInRange(0, size - 1)]; - } - - template - T PickValueInArray(std::initializer_list list) { - // TODO(Dor1s): switch to static_assert once C++14 is allowed. - if (!list.size()) - abort(); - - return *(list.begin() + ConsumeIntegralInRange(0, list.size() - 1)); - } - - // Returns an enum value. The enum must start at 0 and be contiguous. It must - // also contain |kMaxValue| aliased to its largest (inclusive) value. Such as: - // enum class Foo { SomeValue, OtherValue, kMaxValue = OtherValue }; - template T ConsumeEnum() { - static_assert(std::is_enum::value, "|T| must be an enum type."); - return static_cast(ConsumeIntegralInRange( - 0, static_cast(T::kMaxValue))); - } - - // Returns a floating point number in the range [0.0, 1.0]. If there's no - // input data left, always returns 0. - template T ConsumeProbability() { - static_assert(std::is_floating_point::value, - "A floating point type is required."); - - // Use different integral types for different floating point types in order - // to provide better density of the resulting values. - using IntegralType = - typename std::conditional<(sizeof(T) <= sizeof(uint32_t)), uint32_t, - uint64_t>::type; - - T result = static_cast(ConsumeIntegral()); - result /= static_cast(std::numeric_limits::max()); - return result; - } - - // Returns a floating point value in the range [Type's lowest, Type's max] by - // consuming bytes from the input data. If there's no input data left, always - // returns approximately 0. - template T ConsumeFloatingPoint() { - return ConsumeFloatingPointInRange(std::numeric_limits::lowest(), - std::numeric_limits::max()); - } - - // Returns a floating point value in the given range by consuming bytes from - // the input data. If there's no input data left, returns |min|. Note that - // |min| must be less than or equal to |max|. - template T ConsumeFloatingPointInRange(T min, T max) { - if (min > max) - abort(); - - T range = .0; - T result = min; - constexpr T zero(.0); - if (max > zero && min < zero && max > min + std::numeric_limits::max()) { - // The diff |max - min| would overflow the given floating point type. Use - // the half of the diff as the range and consume a bool to decide whether - // the result is in the first of the second part of the diff. - range = (max / 2.0) - (min / 2.0); - if (ConsumeBool()) { - result += range; - } - } else { - range = max - min; - } - - return result + range * ConsumeProbability(); - } + // Writes data to the given destination and returns number of bytes written. + size_t ConsumeData(void *destination, size_t num_bytes); // Reports the remaining bytes available for fuzzed input. size_t remaining_bytes() { return remaining_bytes_; } @@ -245,62 +84,305 @@ class FuzzedDataProvider { FuzzedDataProvider(const FuzzedDataProvider &) = delete; FuzzedDataProvider &operator=(const FuzzedDataProvider &) = delete; - void Advance(size_t num_bytes) { - if (num_bytes > remaining_bytes_) - abort(); + void CopyAndAdvance(void *destination, size_t num_bytes); - data_ptr_ += num_bytes; - remaining_bytes_ -= num_bytes; - } + void Advance(size_t num_bytes); template - std::vector ConsumeBytes(size_t size, size_t num_bytes_to_consume) { - static_assert(sizeof(T) == sizeof(uint8_t), "Incompatible data type."); + std::vector ConsumeBytes(size_t size, size_t num_bytes); - // The point of using the size-based constructor below is to increase the - // odds of having a vector object with capacity being equal to the length. - // That part is always implementation specific, but at least both libc++ and - // libstdc++ allocate the requested number of bytes in that constructor, - // which seems to be a natural choice for other implementations as well. - // To increase the odds even more, we also call |shrink_to_fit| below. - std::vector result(size); - if (size == 0) { - if (num_bytes_to_consume != 0) - abort(); - return result; - } - - std::memcpy(result.data(), data_ptr_, num_bytes_to_consume); - Advance(num_bytes_to_consume); - - // Even though |shrink_to_fit| is also implementation specific, we expect it - // to provide an additional assurance in case vector's constructor allocated - // a buffer which is larger than the actual amount of data we put inside it. - result.shrink_to_fit(); - return result; - } - - template TS ConvertUnsignedToSigned(TU value) { - static_assert(sizeof(TS) == sizeof(TU), "Incompatible data types."); - static_assert(!std::numeric_limits::is_signed, - "Source type must be unsigned."); - - // TODO(Dor1s): change to `if constexpr` once C++17 becomes mainstream. - if (std::numeric_limits::is_modulo) - return static_cast(value); - - // Avoid using implementation-defined unsigned to signer conversions. - // To learn more, see https://stackoverflow.com/questions/13150449. - if (value <= std::numeric_limits::max()) { - return static_cast(value); - } else { - constexpr auto TS_min = std::numeric_limits::min(); - return TS_min + static_cast(value - TS_min); - } - } + template TS ConvertUnsignedToSigned(TU value); const uint8_t *data_ptr_; size_t remaining_bytes_; }; +// Returns a std::vector containing |num_bytes| of input data. If fewer than +// |num_bytes| of data remain, returns a shorter std::vector containing all +// of the data that's left. Can be used with any byte sized type, such as +// char, unsigned char, uint8_t, etc. +template +std::vector FuzzedDataProvider::ConsumeBytes(size_t num_bytes) { + num_bytes = std::min(num_bytes, remaining_bytes_); + return ConsumeBytes(num_bytes, num_bytes); +} + +// Similar to |ConsumeBytes|, but also appends the terminator value at the end +// of the resulting vector. Useful, when a mutable null-terminated C-string is +// needed, for example. But that is a rare case. Better avoid it, if possible, +// and prefer using |ConsumeBytes| or |ConsumeBytesAsString| methods. +template +std::vector FuzzedDataProvider::ConsumeBytesWithTerminator(size_t num_bytes, + T terminator) { + num_bytes = std::min(num_bytes, remaining_bytes_); + std::vector result = ConsumeBytes(num_bytes + 1, num_bytes); + result.back() = terminator; + return result; +} + +// Returns a std::vector containing all remaining bytes of the input data. +template +std::vector FuzzedDataProvider::ConsumeRemainingBytes() { + return ConsumeBytes(remaining_bytes_); +} + +// Returns a std::string containing |num_bytes| of input data. Using this and +// |.c_str()| on the resulting string is the best way to get an immutable +// null-terminated C string. If fewer than |num_bytes| of data remain, returns +// a shorter std::string containing all of the data that's left. +inline std::string FuzzedDataProvider::ConsumeBytesAsString(size_t num_bytes) { + static_assert(sizeof(std::string::value_type) == sizeof(uint8_t), + "ConsumeBytesAsString cannot convert the data to a string."); + + num_bytes = std::min(num_bytes, remaining_bytes_); + std::string result( + reinterpret_cast(data_ptr_), num_bytes); + Advance(num_bytes); + return result; +} + +// Returns a std::string of length from 0 to |max_length|. When it runs out of +// input data, returns what remains of the input. Designed to be more stable +// with respect to a fuzzer inserting characters than just picking a random +// length and then consuming that many bytes with |ConsumeBytes|. +inline std::string +FuzzedDataProvider::ConsumeRandomLengthString(size_t max_length) { + // Reads bytes from the start of |data_ptr_|. Maps "\\" to "\", and maps "\" + // followed by anything else to the end of the string. As a result of this + // logic, a fuzzer can insert characters into the string, and the string + // will be lengthened to include those new characters, resulting in a more + // stable fuzzer than picking the length of a string independently from + // picking its contents. + std::string result; + + // Reserve the anticipated capaticity to prevent several reallocations. + result.reserve(std::min(max_length, remaining_bytes_)); + for (size_t i = 0; i < max_length && remaining_bytes_ != 0; ++i) { + char next = ConvertUnsignedToSigned(data_ptr_[0]); + Advance(1); + if (next == '\\' && remaining_bytes_ != 0) { + next = ConvertUnsignedToSigned(data_ptr_[0]); + Advance(1); + if (next != '\\') + break; + } + result += next; + } + + result.shrink_to_fit(); + return result; +} + +// Returns a std::string of length from 0 to |remaining_bytes_|. +inline std::string FuzzedDataProvider::ConsumeRandomLengthString() { + return ConsumeRandomLengthString(remaining_bytes_); +} + +// Returns a std::string containing all remaining bytes of the input data. +// Prefer using |ConsumeRemainingBytes| unless you actually need a std::string +// object. +inline std::string FuzzedDataProvider::ConsumeRemainingBytesAsString() { + return ConsumeBytesAsString(remaining_bytes_); +} + +// Returns a number in the range [Type's min, Type's max]. The value might +// not be uniformly distributed in the given range. If there's no input data +// left, always returns |min|. +template T FuzzedDataProvider::ConsumeIntegral() { + return ConsumeIntegralInRange(std::numeric_limits::min(), + std::numeric_limits::max()); +} + +// Returns a number in the range [min, max] by consuming bytes from the +// input data. The value might not be uniformly distributed in the given +// range. If there's no input data left, always returns |min|. |min| must +// be less than or equal to |max|. +template +T FuzzedDataProvider::ConsumeIntegralInRange(T min, T max) { + static_assert(std::is_integral::value, "An integral type is required."); + static_assert(sizeof(T) <= sizeof(uint64_t), "Unsupported integral type."); + + if (min > max) + abort(); + + // Use the biggest type possible to hold the range and the result. + uint64_t range = static_cast(max) - min; + uint64_t result = 0; + size_t offset = 0; + + while (offset < sizeof(T) * CHAR_BIT && (range >> offset) > 0 && + remaining_bytes_ != 0) { + // Pull bytes off the end of the seed data. Experimentally, this seems to + // allow the fuzzer to more easily explore the input space. This makes + // sense, since it works by modifying inputs that caused new code to run, + // and this data is often used to encode length of data read by + // |ConsumeBytes|. Separating out read lengths makes it easier modify the + // contents of the data that is actually read. + --remaining_bytes_; + result = (result << CHAR_BIT) | data_ptr_[remaining_bytes_]; + offset += CHAR_BIT; + } + + // Avoid division by 0, in case |range + 1| results in overflow. + if (range != std::numeric_limits::max()) + result = result % (range + 1); + + return static_cast(min + result); +} + +// Returns a floating point value in the range [Type's lowest, Type's max] by +// consuming bytes from the input data. If there's no input data left, always +// returns approximately 0. +template T FuzzedDataProvider::ConsumeFloatingPoint() { + return ConsumeFloatingPointInRange(std::numeric_limits::lowest(), + std::numeric_limits::max()); +} + +// Returns a floating point value in the given range by consuming bytes from +// the input data. If there's no input data left, returns |min|. Note that +// |min| must be less than or equal to |max|. +template +T FuzzedDataProvider::ConsumeFloatingPointInRange(T min, T max) { + if (min > max) + abort(); + + T range = .0; + T result = min; + constexpr T zero(.0); + if (max > zero && min < zero && max > min + std::numeric_limits::max()) { + // The diff |max - min| would overflow the given floating point type. Use + // the half of the diff as the range and consume a bool to decide whether + // the result is in the first of the second part of the diff. + range = (max / 2.0) - (min / 2.0); + if (ConsumeBool()) { + result += range; + } + } else { + range = max - min; + } + + return result + range * ConsumeProbability(); +} + +// Returns a floating point number in the range [0.0, 1.0]. If there's no +// input data left, always returns 0. +template T FuzzedDataProvider::ConsumeProbability() { + static_assert(std::is_floating_point::value, + "A floating point type is required."); + + // Use different integral types for different floating point types in order + // to provide better density of the resulting values. + using IntegralType = + typename std::conditional<(sizeof(T) <= sizeof(uint32_t)), uint32_t, + uint64_t>::type; + + T result = static_cast(ConsumeIntegral()); + result /= static_cast(std::numeric_limits::max()); + return result; +} + +// Reads one byte and returns a bool, or false when no data remains. +inline bool FuzzedDataProvider::ConsumeBool() { + return 1 & ConsumeIntegral(); +} + +// Returns an enum value. The enum must start at 0 and be contiguous. It must +// also contain |kMaxValue| aliased to its largest (inclusive) value. Such as: +// enum class Foo { SomeValue, OtherValue, kMaxValue = OtherValue }; +template T FuzzedDataProvider::ConsumeEnum() { + static_assert(std::is_enum::value, "|T| must be an enum type."); + return static_cast( + ConsumeIntegralInRange(0, static_cast(T::kMaxValue))); +} + +// Returns a copy of the value selected from the given fixed-size |array|. +template +T FuzzedDataProvider::PickValueInArray(const T (&array)[size]) { + static_assert(size > 0, "The array must be non empty."); + return array[ConsumeIntegralInRange(0, size - 1)]; +} + +template +T FuzzedDataProvider::PickValueInArray(std::initializer_list list) { + // TODO(Dor1s): switch to static_assert once C++14 is allowed. + if (!list.size()) + abort(); + + return *(list.begin() + ConsumeIntegralInRange(0, list.size() - 1)); +} + +// Writes |num_bytes| of input data to the given destination pointer. If there +// is not enough data left, writes all remaining bytes. Return value is the +// number of bytes written. +// In general, it's better to avoid using this function, but it may be useful +// in cases when it's necessary to fill a certain buffer or object with +// fuzzing data. +inline size_t FuzzedDataProvider::ConsumeData(void *destination, + size_t num_bytes) { + num_bytes = std::min(num_bytes, remaining_bytes_); + CopyAndAdvance(destination, num_bytes); + return num_bytes; +} + +// Private methods. +inline void FuzzedDataProvider::CopyAndAdvance(void *destination, + size_t num_bytes) { + std::memcpy(destination, data_ptr_, num_bytes); + Advance(num_bytes); +} + +inline void FuzzedDataProvider::Advance(size_t num_bytes) { + if (num_bytes > remaining_bytes_) + abort(); + + data_ptr_ += num_bytes; + remaining_bytes_ -= num_bytes; +} + +template +std::vector FuzzedDataProvider::ConsumeBytes(size_t size, size_t num_bytes) { + static_assert(sizeof(T) == sizeof(uint8_t), "Incompatible data type."); + + // The point of using the size-based constructor below is to increase the + // odds of having a vector object with capacity being equal to the length. + // That part is always implementation specific, but at least both libc++ and + // libstdc++ allocate the requested number of bytes in that constructor, + // which seems to be a natural choice for other implementations as well. + // To increase the odds even more, we also call |shrink_to_fit| below. + std::vector result(size); + if (size == 0) { + if (num_bytes != 0) + abort(); + return result; + } + + CopyAndAdvance(result.data(), num_bytes); + + // Even though |shrink_to_fit| is also implementation specific, we expect it + // to provide an additional assurance in case vector's constructor allocated + // a buffer which is larger than the actual amount of data we put inside it. + result.shrink_to_fit(); + return result; +} + +template +TS FuzzedDataProvider::ConvertUnsignedToSigned(TU value) { + static_assert(sizeof(TS) == sizeof(TU), "Incompatible data types."); + static_assert(!std::numeric_limits::is_signed, + "Source type must be unsigned."); + + // TODO(Dor1s): change to `if constexpr` once C++17 becomes mainstream. + if (std::numeric_limits::is_modulo) + return static_cast(value); + + // Avoid using implementation-defined unsigned to signed conversions. + // To learn more, see https://stackoverflow.com/questions/13150449. + if (value <= std::numeric_limits::max()) { + return static_cast(value); + } else { + constexpr auto TS_min = std::numeric_limits::min(); + return TS_min + static_cast(value - TS_min); + } +} + #endif // LLVM_FUZZER_FUZZED_DATA_PROVIDER_H_ From 9256eacadfd717e02c7e7f43791893e1e5945a21 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Thu, 31 Dec 2020 08:50:08 +0100 Subject: [PATCH 66/84] fuzz: Bump FuzzedDataProvider.h Latest version from https://raw.githubusercontent.com/llvm/llvm-project/70de7e0d9a95b7fcd7c105b06bd90fdf4e01f563/compiler-rt/include/fuzzer/FuzzedDataProvider.h Github-Pull: #20812 Rebased-From: fafce49336e18033b26948886bbd7342c779b246 (cherry picked from commit 14e3f2a1c916fccf375a6570e58072c4d007fc3c) --- src/test/fuzz/FuzzedDataProvider.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/test/fuzz/FuzzedDataProvider.h b/src/test/fuzz/FuzzedDataProvider.h index 208f551bd8..e40a619b89 100644 --- a/src/test/fuzz/FuzzedDataProvider.h +++ b/src/test/fuzz/FuzzedDataProvider.h @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -72,6 +73,8 @@ class FuzzedDataProvider { // Returns a value from the given array. template T PickValueInArray(const T (&array)[size]); + template + T PickValueInArray(const std::array &array); template T PickValueInArray(std::initializer_list list); // Writes data to the given destination and returns number of bytes written. @@ -302,6 +305,12 @@ T FuzzedDataProvider::PickValueInArray(const T (&array)[size]) { return array[ConsumeIntegralInRange(0, size - 1)]; } +template +T FuzzedDataProvider::PickValueInArray(const std::array &array) { + static_assert(size > 0, "The array must be non empty."); + return array[ConsumeIntegralInRange(0, size - 1)]; +} + template T FuzzedDataProvider::PickValueInArray(std::initializer_list list) { // TODO(Dor1s): switch to static_assert once C++14 is allowed. From d92fb9693f9aae92dd8b8c406b8db44df552e40c Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 9 Mar 2021 13:06:14 +0100 Subject: [PATCH 67/84] fuzz: Bump FuzzedDataProvider.h Latest version from https://github.com/llvm/llvm-project/blob/0cccccf0d2cbd707503263785f9a0407d3e2bd5e/compiler-rt/include/fuzzer/FuzzedDataProvider.h Github-Pull: #21397 Rebased-From: fa7dc7ae9595ea49a2b31a3baef9af674d8def60 (cherry picked from commit 8426e3a8a1aad2e1ea794158ffb9a587f476d8d3) --- src/test/fuzz/FuzzedDataProvider.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/fuzz/FuzzedDataProvider.h b/src/test/fuzz/FuzzedDataProvider.h index e40a619b89..b2ea86097f 100644 --- a/src/test/fuzz/FuzzedDataProvider.h +++ b/src/test/fuzz/FuzzedDataProvider.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include From d135a860cf6ca5010fc60149a869a625620ca3be Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Tue, 2 Mar 2021 22:14:18 +0200 Subject: [PATCH 68/84] doc: Remove outdated comment The removed commit is wrong since v0.21.0. Github-Pull: #21342 Rebased-From: f1f63ac3f833e14badac6edf88ed09d0161e18f7 (cherry picked from commit 5a2d98c640cf308d3c7e85ba51fbb7e84f99322a) --- doc/build-windows.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/build-windows.md b/doc/build-windows.md index 28b6aceb3c..d1b84eef42 100644 --- a/doc/build-windows.md +++ b/doc/build-windows.md @@ -103,7 +103,7 @@ Build using: cd depends make HOST=x86_64-w64-mingw32 cd .. - ./autogen.sh # not required when building from tarball + ./autogen.sh CONFIG_SITE=$PWD/depends/x86_64-w64-mingw32/share/config.site ./configure --prefix=/ make sudo bash -c "echo 1 > /proc/sys/fs/binfmt_misc/status" # Enable WSL support for Win32 applications. From f8237b8d5033fb190f91e1b20987e56792ba850e Mon Sep 17 00:00:00 2001 From: fanquake Date: Sat, 20 Mar 2021 17:57:43 +0800 Subject: [PATCH 69/84] rand: only try and use freeifaddrs if available Github-Pull: #21486 Rebased-From: 87deac66aa747481e6f34fc80599e1e490de3ea0 (cherry picked from commit e99d6d0c7cbdbb23f966e50c045bbd525ba8daf0) --- src/randomenv.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/randomenv.cpp b/src/randomenv.cpp index 07122b7f6d..79ab8daf6a 100644 --- a/src/randomenv.cpp +++ b/src/randomenv.cpp @@ -38,7 +38,7 @@ #include #include #endif -#if HAVE_DECL_GETIFADDRS +#if HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS #include #endif #if HAVE_SYSCTL @@ -361,7 +361,7 @@ void RandAddStaticEnv(CSHA512& hasher) hasher.Write((const unsigned char*)hname, strnlen(hname, 256)); } -#if HAVE_DECL_GETIFADDRS +#if HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS // Network interfaces struct ifaddrs *ifad = NULL; getifaddrs(&ifad); From 33eaeada30c573e5cd8ef7676386282d7974734f Mon Sep 17 00:00:00 2001 From: fanquake Date: Sun, 21 Mar 2021 08:41:26 +0800 Subject: [PATCH 70/84] build: check if -lsocket is required with *ifaddrs Github-Pull: #21486 Rebased-From: 879215e665a9f348c8d3fa92701c34065bc86a69 (cherry picked from commit f6896dfde73bb37f4f0f0f9bfe9855d4fe9e9fe5) --- build-aux/m4/l_socket.m4 | 36 ++++++++++++++++++++++++++++++++++++ configure.ac | 2 +- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 build-aux/m4/l_socket.m4 diff --git a/build-aux/m4/l_socket.m4 b/build-aux/m4/l_socket.m4 new file mode 100644 index 0000000000..38923a98fc --- /dev/null +++ b/build-aux/m4/l_socket.m4 @@ -0,0 +1,36 @@ +# Illumos/SmartOS requires linking with -lsocket if +# using getifaddrs & freeifaddrs + +m4_define([_CHECK_SOCKET_testbody], [[ + #include + #include + + int main() { + struct ifaddrs *ifaddr; + getifaddrs(&ifaddr); + freeifaddrs(ifaddr); + } +]]) + +AC_DEFUN([CHECK_SOCKET], [ + + AC_LANG_PUSH(C++) + + AC_MSG_CHECKING([whether ifaddrs funcs can be used without link library]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([_CHECK_SOCKET_testbody])],[ + AC_MSG_RESULT([yes]) + ],[ + AC_MSG_RESULT([no]) + LIBS="$LIBS -lsocket" + AC_MSG_CHECKING([whether getifaddrs needs -lsocket]) + AC_LINK_IFELSE([AC_LANG_SOURCE([_CHECK_SOCKET_testbody])],[ + AC_MSG_RESULT([yes]) + ],[ + AC_MSG_RESULT([no]) + AC_MSG_FAILURE([cannot figure out how to use getifaddrs]) + ]) + ]) + + AC_LANG_POP +]) diff --git a/configure.ac b/configure.ac index 6bbdcaaee8..ff91684ca4 100644 --- a/configure.ac +++ b/configure.ac @@ -878,7 +878,7 @@ fi AC_CHECK_HEADERS([endian.h sys/endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h sys/sysctl.h vm/vm_param.h sys/vmmeter.h sys/resources.h]) -AC_CHECK_DECLS([getifaddrs, freeifaddrs],,, +AC_CHECK_DECLS([getifaddrs, freeifaddrs],[CHECK_SOCKET],, [#include #include ] ) From ad985d5c2326394e3e07c3a828e18beacf8eeb7e Mon Sep 17 00:00:00 2001 From: fanquake Date: Fri, 26 Mar 2021 12:53:05 +0800 Subject: [PATCH 71/84] net: add ifaddrs.h include Github-Pull: #21486 Rebased-From: 4783115fd4cccb46a7f8c592b34fa7c094c29410 (cherry picked from commit 1a9a2cb7dcc60781a3cbca3a7846ff153143260c) --- src/net.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/net.cpp b/src/net.cpp index 1fd913eb64..15e52de94d 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -28,6 +28,10 @@ #include #endif +#if HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS +#include +#endif + #ifdef USE_POLL #include #endif From 5f714365cb3f1af87568034ab3a14bbf9a052e2e Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Fri, 12 Feb 2021 14:18:50 -0500 Subject: [PATCH 72/84] Introduce DeferringSignatureChecker and inherit with SignatureExtractor Introduces a DeferringSignatureChecker which simply takes a BaseSignatureChecker and passes through everything. SignatureExtractorChecker now subclasses DeferringSignatureChecker. This allows for all BaseSignatureChecker functions to be implemented for SignatureExtractorChecker, while allowing for future signature checkers which opreate similarly to SignatureExtractorChecker. Github-Pull: #21166 Rebased-From: 6965456c10c9c4025c71c5e24fa5b27b15e5933a (cherry picked from commit 7de019bc619b0b2433bfb553feba5f6dc58c8db8) --- src/script/interpreter.h | 28 ++++++++++++++++++++++++++++ src/script/sign.cpp | 8 ++++---- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/script/interpreter.h b/src/script/interpreter.h index d942e45dca..7b24911b47 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -339,6 +339,34 @@ public: using TransactionSignatureChecker = GenericTransactionSignatureChecker; using MutableTransactionSignatureChecker = GenericTransactionSignatureChecker; +class DeferringSignatureChecker : public BaseSignatureChecker +{ +protected: + BaseSignatureChecker& m_checker; + +public: + DeferringSignatureChecker(BaseSignatureChecker& checker) : m_checker(checker) {} + + bool CheckECDSASignature(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode, SigVersion sigversion, unsigned int flags) const override + { + return m_checker.CheckECDSASignature(scriptSig, vchPubKey, scriptCode, sigversion, flags); + } + + bool CheckSchnorrSignature(Span sig, Span pubkey, SigVersion sigversion, const ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override + { + return m_checker.CheckSchnorrSignature(sig, pubkey, sigversion, execdata, serror); + } + + bool CheckLockTime(const CScriptNum& nLockTime) const override + { + return m_checker.CheckLockTime(nLockTime); + } + bool CheckSequence(const CScriptNum& nSequence) const override + { + return m_checker.CheckSequence(nSequence); + } +}; + bool EvalScript(std::vector >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* error = nullptr); bool EvalScript(std::vector >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* error = nullptr); bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CScriptWitness* witness, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror = nullptr); diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 83af10e1a3..35bb3d1abb 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -266,17 +266,17 @@ bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreato } namespace { -class SignatureExtractorChecker final : public BaseSignatureChecker +class SignatureExtractorChecker final : public DeferringSignatureChecker { private: SignatureData& sigdata; - BaseSignatureChecker& checker; public: - SignatureExtractorChecker(SignatureData& sigdata, BaseSignatureChecker& checker) : sigdata(sigdata), checker(checker) {} + SignatureExtractorChecker(SignatureData& sigdata, BaseSignatureChecker& checker) : DeferringSignatureChecker(checker), sigdata(sigdata) {} + bool CheckECDSASignature(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode, SigVersion sigversion, unsigned int flags) const override { - if (checker.CheckECDSASignature(scriptSig, vchPubKey, scriptCode, sigversion, flags)) { + if (m_checker.CheckECDSASignature(scriptSig, vchPubKey, scriptCode, sigversion, flags)) { CPubKey pubkey(vchPubKey); sigdata.signatures.emplace(pubkey.GetID(), SigPair(pubkey, scriptSig)); return true; From 78cd67d4de861adc7d6c6d8f19d44a28160cbc35 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Fri, 12 Feb 2021 15:38:46 -0500 Subject: [PATCH 73/84] Test that signrawtx works when a signed CSV and CLTV inputs are present Github-Pull: #21166 Rebased-From: a97a9298cea085858e1a65a5e9b20d7a9e0f7303 (cherry picked from commit f79189ca54524881d52b91679eb9035d6718ce01) --- test/functional/rpc_signrawtransaction.py | 85 +++++++++++++++++++++-- 1 file changed, 80 insertions(+), 5 deletions(-) diff --git a/test/functional/rpc_signrawtransaction.py b/test/functional/rpc_signrawtransaction.py index cbc7f0524a..6e77dfe6ed 100755 --- a/test/functional/rpc_signrawtransaction.py +++ b/test/functional/rpc_signrawtransaction.py @@ -4,23 +4,24 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test transaction signing using the signrawtransaction* RPCs.""" -from test_framework.address import check_script, script_to_p2sh +from test_framework.address import check_script, script_to_p2sh, script_to_p2wsh from test_framework.key import ECKey from test_framework.test_framework import BitcoinTestFramework from test_framework.util import assert_equal, assert_raises_rpc_error, find_vout_for_address, hex_str_to_bytes -from test_framework.messages import sha256 -from test_framework.script import CScript, OP_0, OP_CHECKSIG +from test_framework.messages import sha256, CTransaction, CTxInWitness +from test_framework.script import CScript, OP_0, OP_CHECKSIG, OP_CHECKSEQUENCEVERIFY, OP_CHECKLOCKTIMEVERIFY, OP_DROP, OP_TRUE from test_framework.script_util import key_to_p2pkh_script, script_to_p2sh_p2wsh_script, script_to_p2wsh_script from test_framework.wallet_util import bytes_to_wif -from decimal import Decimal +from decimal import Decimal, getcontext +from io import BytesIO class SignRawTransactionsTest(BitcoinTestFramework): def set_test_params(self): self.setup_clean_chain = True self.num_nodes = 3 elements_args = ["-blindedaddresses=1", "-initialfreecoins=2100000000000000", "-con_connect_genesis_outputs=1", "-anyonecanspendaremine=1", "-txindex=1"] - prefix_args = ["-pubkeyprefix=111", "-scriptprefix=196", "-secretprefix=239", "-extpubkeyprefix=043587CF", "-extprvkeyprefix=04358394", "-bech32_hrp=bcrt"] + prefix_args = ["-pubkeyprefix=111", "-scriptprefix=196", "-secretprefix=239", "-extpubkeyprefix=043587CF", "-extprvkeyprefix=04358394"] self.extra_args = [prefix_args, prefix_args, elements_args] def skip_test_if_missing_module(self): @@ -250,6 +251,78 @@ class SignRawTransactionsTest(BitcoinTestFramework): txn = self.nodes[0].signrawtransactionwithwallet(hex_str, prev_txs) assert txn["complete"] + def test_signing_with_csv(self): + self.log.info("Test signing a transaction containing a fully signed CSV input") + self.nodes[0].walletpassphrase("password", 9999) + getcontext().prec = 8 + + # Make sure CSV is active + self.nodes[0].generate(500) + + # Create a P2WSH script with CSV + script = CScript([1, OP_CHECKSEQUENCEVERIFY, OP_DROP]) + address = script_to_p2wsh(script) + + # Fund that address and make the spend + txid = self.nodes[0].sendtoaddress(address, 1) + vout = find_vout_for_address(self.nodes[0], txid, address) + self.nodes[0].generate(1) + utxo = self.nodes[0].listunspent()[0] + amt = Decimal(1) + utxo["amount"] - Decimal(0.00001) + tx = self.nodes[0].createrawtransaction( + [{"txid": txid, "vout": vout, "sequence": 1},{"txid": utxo["txid"], "vout": utxo["vout"]}], + [{self.nodes[0].getnewaddress(): amt}, {"fee": 0.00001}], + self.nodes[0].getblockcount() + ) + + # Set the witness script + ctx = CTransaction() + ctx.deserialize(BytesIO(hex_str_to_bytes(tx))) + ctx.wit.vtxinwit.append(CTxInWitness()) + ctx.wit.vtxinwit[0].scriptWitness.stack = [CScript([OP_TRUE]), script] + tx = ctx.serialize_with_witness().hex() + + # Sign and send the transaction + signed = self.nodes[0].signrawtransactionwithwallet(tx) + assert_equal(signed["complete"], True) + self.nodes[0].sendrawtransaction(signed["hex"]) + + def test_signing_with_cltv(self): + self.log.info("Test signing a transaction containing a fully signed CLTV input") + self.nodes[0].walletpassphrase("password", 9999) + getcontext().prec = 8 + + # Make sure CSV is active + self.nodes[0].generate(1500) + + # Create a P2WSH script with CLTV + script = CScript([1000, OP_CHECKLOCKTIMEVERIFY, OP_DROP]) + address = script_to_p2wsh(script) + + # Fund that address and make the spend + txid = self.nodes[0].sendtoaddress(address, 1) + vout = find_vout_for_address(self.nodes[0], txid, address) + self.nodes[0].generate(1) + utxo = self.nodes[0].listunspent()[0] + amt = Decimal(1) + utxo["amount"] - Decimal(0.00001) + tx = self.nodes[0].createrawtransaction( + [{"txid": txid, "vout": vout},{"txid": utxo["txid"], "vout": utxo["vout"]}], + [{self.nodes[0].getnewaddress(): amt}, {"fee": 0.00001}], + self.nodes[0].getblockcount() + ) + + # Set the witness script + ctx = CTransaction() + ctx.deserialize(BytesIO(hex_str_to_bytes(tx))) + ctx.wit.vtxinwit.append(CTxInWitness()) + ctx.wit.vtxinwit[0].scriptWitness.stack = [CScript([OP_TRUE]), script] + tx = ctx.serialize_with_witness().hex() + + # Sign and send the transaction + signed = self.nodes[0].signrawtransactionwithwallet(tx) + assert_equal(signed["complete"], True) + self.nodes[0].sendrawtransaction(signed["hex"]) + def witness_blind_pubkey_test(self): """Create and compare signatures in multiple ways for a valid raw transaction with one input. @@ -328,6 +401,8 @@ class SignRawTransactionsTest(BitcoinTestFramework): self.OP_1NEGATE_test() self.test_with_lock_outputs() self.test_fully_signed_tx() + self.test_signing_with_csv() + self.test_signing_with_cltv() # Blinded descriptors not supported yet if not self.options.descriptors: From 12a25655e8c35c35927b8e347e20f97e72603552 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Thu, 4 Feb 2021 18:21:26 -0500 Subject: [PATCH 74/84] wallet: Use existing feerate instead of getting a new one During each loop of CreateTransaction, instead of constantly getting a new feerate, use the feerate that we have already fetched for all fee calculations. Thix fixes a race condition where the feerate required changes during each iteration of the loop. This commit changes behavior as the "Fee estimation failed" error will now take priority over "Signing transaction failed". Github-Pull: #21083 Rebased-From: 1a6a0b0dfb90f9ebd4b86d7934c6aa5594974f5f (cherry picked from commit 48fc675163a657e615fd4b2680fc3accba12f95d) --- src/wallet/wallet.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 08b545454a..fa8a6f3231 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3455,6 +3455,11 @@ bool CWallet::CreateTransactionInternal( error = strprintf(_("Fee rate (%s) is lower than the minimum fee rate setting (%s)"), coin_control.m_feerate->ToString(FeeEstimateMode::SAT_VB), nFeeRateNeeded.ToString(FeeEstimateMode::SAT_VB)); return false; } + if (feeCalc.reason == FeeReason::FALLBACK && !m_allow_fallback_fee) { + // eventually allow a fallback fee + error = _("Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable -fallbackfee."); + return false; + } // ELEMENTS: // Start with tiny non-zero fee for issuance entropy and loop until there is enough fee @@ -3791,13 +3796,7 @@ bool CWallet::CreateTransactionInternal( txNew = blind_details->tx_unblinded_unsigned; } - nFeeNeeded = GetMinimumFee(*this, nBytes, coin_control, &feeCalc); - if (feeCalc.reason == FeeReason::FALLBACK && !m_allow_fallback_fee) { - // eventually allow a fallback fee - error = _("Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable -fallbackfee."); - return false; - } - + nFeeNeeded = coin_selection_params.effective_fee.GetFee(nBytes); if (nFeeRet >= nFeeNeeded) { // Reduce fee to only the needed amount if possible. This // prevents potential overpayment in fees if the coins @@ -3811,7 +3810,7 @@ bool CWallet::CreateTransactionInternal( // change output. Only try this once. if (nChangePosInOut == -1 && nSubtractFeeFromAmount == 0 && pick_new_inputs) { unsigned int tx_size_with_change = nBytes + coin_selection_params.change_output_size + 2; // Add 2 as a buffer in case increasing # of outputs changes compact size - CAmount fee_needed_with_change = GetMinimumFee(*this, tx_size_with_change, coin_control, nullptr); + CAmount fee_needed_with_change = coin_selection_params.effective_fee.GetFee(tx_size_with_change); CAmount minimum_value_for_change = GetDustThreshold(change_prototype_txout, discard_rate); if (nFeeRet >= fee_needed_with_change + minimum_value_for_change) { pick_new_inputs = false; From 1f58b91c4881ec112ab9ffea93f4c5080f57cef5 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Thu, 4 Feb 2021 18:23:51 -0500 Subject: [PATCH 75/84] wallet: Replace nFeeRateNeeded with effective_fee Make sure that all fee calculations use the same feerate. coin_selection_params.effective_fee is the variable we use for all fee calculations, so get rid of remaining nFeeRateNeeded usages and just directly set coin_selection_params.effective_fee. Does not change behavior. Github-Pull: #21083 Rebased-From: e2f429e6bbf7098f278c0247b954ecd3ba53cf37 (cherry picked from commit 34c89f92f34b5ca12da95d5f0b0240682c5a1c1f) --- src/wallet/wallet.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index fa8a6f3231..5718bb0c62 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3448,11 +3448,11 @@ bool CWallet::CreateTransactionInternal( CFeeRate discard_rate = GetDiscardRate(*this); // Get the fee rate to use effective values in coin selection - CFeeRate nFeeRateNeeded = GetMinimumFeeRate(*this, coin_control, &feeCalc); + coin_selection_params.effective_fee = GetMinimumFeeRate(*this, coin_control, &feeCalc); // Do not, ever, assume that it's fine to change the fee rate if the user has explicitly // provided one - if (coin_control.m_feerate && nFeeRateNeeded > *coin_control.m_feerate) { - error = strprintf(_("Fee rate (%s) is lower than the minimum fee rate setting (%s)"), coin_control.m_feerate->ToString(FeeEstimateMode::SAT_VB), nFeeRateNeeded.ToString(FeeEstimateMode::SAT_VB)); + if (coin_control.m_feerate && coin_selection_params.effective_fee > *coin_control.m_feerate) { + error = strprintf(_("Fee rate (%s) is lower than the minimum fee rate setting (%s)"), coin_control.m_feerate->ToString(FeeEstimateMode::SAT_VB), coin_selection_params.effective_fee.ToString(FeeEstimateMode::SAT_VB)); return false; } if (feeCalc.reason == FeeReason::FALLBACK && !m_allow_fallback_fee) { @@ -3577,7 +3577,6 @@ bool CWallet::CreateTransactionInternal( } else { coin_selection_params.change_spend_size = (size_t)change_spend_size; } - coin_selection_params.effective_fee = nFeeRateNeeded; if (!SelectCoins(vAvailableCoins, mapValueToSelect, setCoins, mapValueIn, coin_control, coin_selection_params, bnb_used)) { // If BnB was used, it was the first pass. No longer the first pass and continue loop with knapsack. From 300372f8bff1a47be9eb8061e43b041811e742c9 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Thu, 4 Feb 2021 18:28:45 -0500 Subject: [PATCH 76/84] wallet: Move long term feerate setting to CreateTransaction Instead of setting the long term feerate for each SelectCoinsMinConf iteration, set it once during CreateTransaction and let it be shared with each SelectCoinsMinConf through coin_selection_params.m_long_term_feerate. Does not change behavior. Github-Pull: #21083 Rebased-From: 448d04b931f86941903e855f831249ff5ec77485 (cherry picked from commit bcd716670ba8a189a2e9b8b035318abceb9ce631) --- src/bench/coin_selection.cpp | 5 ++++- src/wallet/test/coinselector_tests.cpp | 20 ++++++++++++++++---- src/wallet/wallet.cpp | 17 ++++++++--------- src/wallet/wallet.h | 11 ++++++++++- 4 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/bench/coin_selection.cpp b/src/bench/coin_selection.cpp index 36c8a3519d..8a18ab4c8a 100644 --- a/src/bench/coin_selection.cpp +++ b/src/bench/coin_selection.cpp @@ -52,7 +52,10 @@ static void CoinSelection(benchmark::Bench& bench) } const CoinEligibilityFilter filter_standard(1, 6, 0); - const CoinSelectionParams coin_selection_params(true, 34, 148, CFeeRate(0), 0); + const CoinSelectionParams coin_selection_params(/* use_bnb= */ true, /* change_output_size= */ 34, + /* change_spend_size= */ 148, /* effective_fee= */ CFeeRate(0), + /* long_term_feerate= */ CFeeRate(0), + /* tx_no_inputs_size= */ 0); bench.run([&] { std::set setCoinsRet; CAmountMap mapValueRet; diff --git a/src/wallet/test/coinselector_tests.cpp b/src/wallet/test/coinselector_tests.cpp index fc16dd406d..0974dea1c0 100644 --- a/src/wallet/test/coinselector_tests.cpp +++ b/src/wallet/test/coinselector_tests.cpp @@ -35,7 +35,10 @@ static CAmount balance = 0; CoinEligibilityFilter filter_standard(1, 6, 0); CoinEligibilityFilter filter_confirmed(1, 1, 0); CoinEligibilityFilter filter_standard_extra(6, 6, 0); -CoinSelectionParams coin_selection_params(false, 0, 0, CFeeRate(0), 0); +CoinSelectionParams coin_selection_params(/* use_bnb= */ false, /* change_output_size= */ 0, + /* change_spend_size= */ 0, /* effective_fee= */ CFeeRate(0), + /* long_term_feerate= */ CFeeRate(0), + /* tx_no_inputs_size= */ 0); // ELEMENTS: helper function wrapping a single-asset call to SelectCoinsMinConf static bool SimpleSelectCoinsMinConf(const CWallet& wallet, const CAmount& nTargetValue, const CoinEligibilityFilter& eligibility_filter, std::vector groups, @@ -277,7 +280,10 @@ BOOST_AUTO_TEST_CASE(bnb_search_test) } // Make sure that effective value is working in SelectCoinsMinConf when BnB is used - CoinSelectionParams coin_selection_params_bnb(true, 0, 0, CFeeRate(3000), 0); + CoinSelectionParams coin_selection_params_bnb(/* use_bnb= */ true, /* change_output_size= */ 0, + /* change_spend_size= */ 0, /* effective_fee= */ CFeeRate(3000), + /* long_term_feerate= */ CFeeRate(1000), + /* tx_no_inputs_size= */ 0); CoinSet setCoinsRet; CAmount nValueRet; bool bnb_used; @@ -650,8 +656,14 @@ BOOST_AUTO_TEST_CASE(SelectCoins_test) CAmount target = rand.randrange(balance - 1000) + 1000; // Perform selection - CoinSelectionParams coin_selection_params_knapsack(false, 34, 148, CFeeRate(0), 0); - CoinSelectionParams coin_selection_params_bnb(true, 34, 148, CFeeRate(0), 0); + CoinSelectionParams coin_selection_params_knapsack(/* use_bnb= */ false, /* change_output_size= */ 34, + /* change_spend_size= */ 148, /* effective_fee= */ CFeeRate(0), + /* long_term_feerate= */ CFeeRate(0), + /* tx_no_inputs_size= */ 0); + CoinSelectionParams coin_selection_params_bnb(/* use_bnb= */ true, /* change_output_size= */ 34, + /* change_spend_size= */ 148, /* effective_fee= */ CFeeRate(0), + /* long_term_feerate= */ CFeeRate(0), + /* tx_no_inputs_size= */ 0); CoinSet out_set; CAmount out_value = 0; bool bnb_used = false; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 5718bb0c62..c3fa20dbe3 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2474,12 +2474,6 @@ bool CWallet::SelectCoinsMinConf(const CAmountMap& mapTargetValue, const CoinEli } // END ELEMENTS - // Get long term estimate - FeeCalculation feeCalc; - CCoinControl temp; - temp.m_confirm_target = 1008; - CFeeRate long_term_feerate = GetMinimumFeeRate(*this, temp, &feeCalc); - // Calculate cost of change CAmount cost_of_change = GetDiscardRate(*this).GetFee(coin_selection_params.change_spend_size) + coin_selection_params.effective_fee.GetFee(coin_selection_params.change_output_size); @@ -2489,9 +2483,9 @@ bool CWallet::SelectCoinsMinConf(const CAmountMap& mapTargetValue, const CoinEli if (coin_selection_params.m_subtract_fee_outputs) { // Set the effective feerate to 0 as we don't want to use the effective value since the fees will be deducted from the output - group.SetFees(CFeeRate(0) /* effective_feerate */, long_term_feerate); + group.SetFees(CFeeRate(0) /* effective_feerate */, coin_selection_params.m_long_term_feerate); } else { - group.SetFees(coin_selection_params.effective_fee, long_term_feerate); + group.SetFees(coin_selection_params.effective_fee, coin_selection_params.m_long_term_feerate); } OutputGroup pos_group = group.GetPositiveOnlyGroup(); @@ -3461,8 +3455,13 @@ bool CWallet::CreateTransactionInternal( return false; } + // Get long term estimate + CCoinControl cc_temp; + cc_temp.m_confirm_target = chain().estimateMaxBlocks(); + coin_selection_params.m_long_term_feerate = GetMinimumFeeRate(*this, cc_temp, nullptr); + // ELEMENTS: - // Start with tiny non-zero fee for issuance entropy and loop until there is enough fee + // Start with tiny non-zero fee for issuance entropy nFeeRet = 1; bool pick_new_inputs = true; CAmountMap mapValueIn; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 92a260abc8..41cb4cd5de 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -674,11 +674,20 @@ struct CoinSelectionParams size_t change_output_size = 0; size_t change_spend_size = 0; CFeeRate effective_fee = CFeeRate(0); + CFeeRate m_long_term_feerate; size_t tx_noinputs_size = 0; //! Indicate that we are subtracting the fee from outputs bool m_subtract_fee_outputs = false; - CoinSelectionParams(bool use_bnb, size_t change_output_size, size_t change_spend_size, CFeeRate effective_fee, size_t tx_noinputs_size) : use_bnb(use_bnb), change_output_size(change_output_size), change_spend_size(change_spend_size), effective_fee(effective_fee), tx_noinputs_size(tx_noinputs_size) {} + CoinSelectionParams(bool use_bnb, size_t change_output_size, size_t change_spend_size, CFeeRate effective_fee, + CFeeRate long_term_feerate, size_t tx_noinputs_size) : + use_bnb(use_bnb), + change_output_size(change_output_size), + change_spend_size(change_spend_size), + effective_fee(effective_fee), + m_long_term_feerate(long_term_feerate), + tx_noinputs_size(tx_noinputs_size) + {} CoinSelectionParams() {} }; From f897fd9575299c578acd0581b2516952bf9345be Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Thu, 4 Feb 2021 19:11:24 -0500 Subject: [PATCH 77/84] wallet: Move discard feerate fetching to CreateTransaction Instead of fetching the discard feerate for each SelectCoinsMinConf iteration, fetch and cache it once during CreateTransaction so that it is shared for each SelectCoinsMinConf through coin_selection_params.m_discard_feerate. Does not change behavior. Github-Pull: #21083 Rebased-From: bdd0c2934b7f389ffcfae3b602ee3ecee8581acd (cherry picked from commit 5fc381e443d6d967e6f7f8bc88a4fd66e18379eb) --- src/bench/coin_selection.cpp | 2 +- src/wallet/test/coinselector_tests.cpp | 8 ++++---- src/wallet/wallet.cpp | 9 +++++---- src/wallet/wallet.h | 4 +++- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/bench/coin_selection.cpp b/src/bench/coin_selection.cpp index 8a18ab4c8a..07cb98dadb 100644 --- a/src/bench/coin_selection.cpp +++ b/src/bench/coin_selection.cpp @@ -54,7 +54,7 @@ static void CoinSelection(benchmark::Bench& bench) const CoinEligibilityFilter filter_standard(1, 6, 0); const CoinSelectionParams coin_selection_params(/* use_bnb= */ true, /* change_output_size= */ 34, /* change_spend_size= */ 148, /* effective_fee= */ CFeeRate(0), - /* long_term_feerate= */ CFeeRate(0), + /* long_term_feerate= */ CFeeRate(0), /* discard_feerate= */ CFeeRate(0), /* tx_no_inputs_size= */ 0); bench.run([&] { std::set setCoinsRet; diff --git a/src/wallet/test/coinselector_tests.cpp b/src/wallet/test/coinselector_tests.cpp index 0974dea1c0..13c20c4a2b 100644 --- a/src/wallet/test/coinselector_tests.cpp +++ b/src/wallet/test/coinselector_tests.cpp @@ -37,7 +37,7 @@ CoinEligibilityFilter filter_confirmed(1, 1, 0); CoinEligibilityFilter filter_standard_extra(6, 6, 0); CoinSelectionParams coin_selection_params(/* use_bnb= */ false, /* change_output_size= */ 0, /* change_spend_size= */ 0, /* effective_fee= */ CFeeRate(0), - /* long_term_feerate= */ CFeeRate(0), + /* long_term_feerate= */ CFeeRate(0), /* discard_feerate= */ CFeeRate(0), /* tx_no_inputs_size= */ 0); // ELEMENTS: helper function wrapping a single-asset call to SelectCoinsMinConf @@ -282,7 +282,7 @@ BOOST_AUTO_TEST_CASE(bnb_search_test) // Make sure that effective value is working in SelectCoinsMinConf when BnB is used CoinSelectionParams coin_selection_params_bnb(/* use_bnb= */ true, /* change_output_size= */ 0, /* change_spend_size= */ 0, /* effective_fee= */ CFeeRate(3000), - /* long_term_feerate= */ CFeeRate(1000), + /* long_term_feerate= */ CFeeRate(1000), /* discard_feerate= */ CFeeRate(1000), /* tx_no_inputs_size= */ 0); CoinSet setCoinsRet; CAmount nValueRet; @@ -658,11 +658,11 @@ BOOST_AUTO_TEST_CASE(SelectCoins_test) // Perform selection CoinSelectionParams coin_selection_params_knapsack(/* use_bnb= */ false, /* change_output_size= */ 34, /* change_spend_size= */ 148, /* effective_fee= */ CFeeRate(0), - /* long_term_feerate= */ CFeeRate(0), + /* long_term_feerate= */ CFeeRate(0), /* discard_feerate= */ CFeeRate(0), /* tx_no_inputs_size= */ 0); CoinSelectionParams coin_selection_params_bnb(/* use_bnb= */ true, /* change_output_size= */ 34, /* change_spend_size= */ 148, /* effective_fee= */ CFeeRate(0), - /* long_term_feerate= */ CFeeRate(0), + /* long_term_feerate= */ CFeeRate(0), /* discard_feerate= */ CFeeRate(0), /* tx_no_inputs_size= */ 0); CoinSet out_set; CAmount out_value = 0; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index c3fa20dbe3..c6c523bedb 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2475,7 +2475,7 @@ bool CWallet::SelectCoinsMinConf(const CAmountMap& mapTargetValue, const CoinEli // END ELEMENTS // Calculate cost of change - CAmount cost_of_change = GetDiscardRate(*this).GetFee(coin_selection_params.change_spend_size) + coin_selection_params.effective_fee.GetFee(coin_selection_params.change_output_size); + CAmount cost_of_change = coin_selection_params.m_discard_feerate.GetFee(coin_selection_params.change_spend_size) + coin_selection_params.effective_fee.GetFee(coin_selection_params.change_output_size); // Filter by the min conf specs and add to utxo_pool and calculate effective value for (OutputGroup& group : asset_groups) { @@ -3439,7 +3439,8 @@ bool CWallet::CreateTransactionInternal( coin_selection_params.change_output_size += (MAX_RANGEPROOF_SIZE + DEFAULT_SURJECTIONPROOF_SIZE + WITNESS_SCALE_FACTOR - 1)/WITNESS_SCALE_FACTOR; } - CFeeRate discard_rate = GetDiscardRate(*this); + // Set discard feerate + coin_selection_params.m_discard_feerate = GetDiscardRate(*this); // Get the fee rate to use effective values in coin selection coin_selection_params.effective_fee = GetMinimumFeeRate(*this, coin_control, &feeCalc); @@ -3612,7 +3613,7 @@ bool CWallet::CreateTransactionInternal( // Never create dust outputs; if we would, just // add the dust to the fee. // The nChange when BnB is used is always going to go to fees. - if (assetChange.first == policyAsset && (IsDust(newTxOut, discard_rate) || bnb_used)) + if (assetChange.first == policyAsset && (IsDust(newTxOut, coin_selection_params.m_discard_feerate) || bnb_used)) { vChangePosInOut.erase(assetChange.first); nFeeRet += assetChange.second; @@ -3809,7 +3810,7 @@ bool CWallet::CreateTransactionInternal( if (nChangePosInOut == -1 && nSubtractFeeFromAmount == 0 && pick_new_inputs) { unsigned int tx_size_with_change = nBytes + coin_selection_params.change_output_size + 2; // Add 2 as a buffer in case increasing # of outputs changes compact size CAmount fee_needed_with_change = coin_selection_params.effective_fee.GetFee(tx_size_with_change); - CAmount minimum_value_for_change = GetDustThreshold(change_prototype_txout, discard_rate); + CAmount minimum_value_for_change = GetDustThreshold(change_prototype_txout, coin_selection_params.m_discard_feerate); if (nFeeRet >= fee_needed_with_change + minimum_value_for_change) { pick_new_inputs = false; one_more_try_20347 = bnb_used; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 41cb4cd5de..88f4aaa4f0 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -675,17 +675,19 @@ struct CoinSelectionParams size_t change_spend_size = 0; CFeeRate effective_fee = CFeeRate(0); CFeeRate m_long_term_feerate; + CFeeRate m_discard_feerate; size_t tx_noinputs_size = 0; //! Indicate that we are subtracting the fee from outputs bool m_subtract_fee_outputs = false; CoinSelectionParams(bool use_bnb, size_t change_output_size, size_t change_spend_size, CFeeRate effective_fee, - CFeeRate long_term_feerate, size_t tx_noinputs_size) : + CFeeRate long_term_feerate, CFeeRate discard_feerate, size_t tx_noinputs_size) : use_bnb(use_bnb), change_output_size(change_output_size), change_spend_size(change_spend_size), effective_fee(effective_fee), m_long_term_feerate(long_term_feerate), + m_discard_feerate(discard_feerate), tx_noinputs_size(tx_noinputs_size) {} CoinSelectionParams() {} From 00fe59fd432e332d114e010c3380e0bae2aa579b Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Tue, 16 Mar 2021 16:19:03 -0400 Subject: [PATCH 78/84] Rename CoinSelectionParams::effective_fee to m_effective_feerate It's a feerate, not a fee. Also follow the style guide for member names. Github-Pull: #21083 Rebased-From: f9cd2bfbccb7a2b8ff07cec5f6d2adbeca5f07c3 (cherry picked from commit d61fb07da7c12e4a1f68cf645f32d563a657a506) --- src/bench/coin_selection.cpp | 2 +- src/wallet/test/coinselector_tests.cpp | 10 +++++----- src/wallet/wallet.cpp | 18 +++++++++--------- src/wallet/wallet.h | 6 +++--- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/bench/coin_selection.cpp b/src/bench/coin_selection.cpp index 07cb98dadb..1c341c8e0a 100644 --- a/src/bench/coin_selection.cpp +++ b/src/bench/coin_selection.cpp @@ -53,7 +53,7 @@ static void CoinSelection(benchmark::Bench& bench) const CoinEligibilityFilter filter_standard(1, 6, 0); const CoinSelectionParams coin_selection_params(/* use_bnb= */ true, /* change_output_size= */ 34, - /* change_spend_size= */ 148, /* effective_fee= */ CFeeRate(0), + /* change_spend_size= */ 148, /* effective_feerate= */ CFeeRate(0), /* long_term_feerate= */ CFeeRate(0), /* discard_feerate= */ CFeeRate(0), /* tx_no_inputs_size= */ 0); bench.run([&] { diff --git a/src/wallet/test/coinselector_tests.cpp b/src/wallet/test/coinselector_tests.cpp index 13c20c4a2b..f94ee3ef86 100644 --- a/src/wallet/test/coinselector_tests.cpp +++ b/src/wallet/test/coinselector_tests.cpp @@ -36,7 +36,7 @@ CoinEligibilityFilter filter_standard(1, 6, 0); CoinEligibilityFilter filter_confirmed(1, 1, 0); CoinEligibilityFilter filter_standard_extra(6, 6, 0); CoinSelectionParams coin_selection_params(/* use_bnb= */ false, /* change_output_size= */ 0, - /* change_spend_size= */ 0, /* effective_fee= */ CFeeRate(0), + /* change_spend_size= */ 0, /* effective_feerate= */ CFeeRate(0), /* long_term_feerate= */ CFeeRate(0), /* discard_feerate= */ CFeeRate(0), /* tx_no_inputs_size= */ 0); @@ -281,7 +281,7 @@ BOOST_AUTO_TEST_CASE(bnb_search_test) // Make sure that effective value is working in SelectCoinsMinConf when BnB is used CoinSelectionParams coin_selection_params_bnb(/* use_bnb= */ true, /* change_output_size= */ 0, - /* change_spend_size= */ 0, /* effective_fee= */ CFeeRate(3000), + /* change_spend_size= */ 0, /* effective_feerate= */ CFeeRate(3000), /* long_term_feerate= */ CFeeRate(1000), /* discard_feerate= */ CFeeRate(1000), /* tx_no_inputs_size= */ 0); CoinSet setCoinsRet; @@ -315,7 +315,7 @@ BOOST_AUTO_TEST_CASE(bnb_search_test) CCoinControl coin_control; coin_control.fAllowOtherInputs = true; coin_control.Select(COutPoint(vCoins.at(0).tx->GetHash(), vCoins.at(0).i)); - coin_selection_params_bnb.effective_fee = CFeeRate(0); + coin_selection_params_bnb.m_effective_feerate = CFeeRate(0); CAmountMap mapTargetValue; mapTargetValue[CAsset()] = 10 * CENT; CAmountMap mapValueRet; @@ -657,11 +657,11 @@ BOOST_AUTO_TEST_CASE(SelectCoins_test) // Perform selection CoinSelectionParams coin_selection_params_knapsack(/* use_bnb= */ false, /* change_output_size= */ 34, - /* change_spend_size= */ 148, /* effective_fee= */ CFeeRate(0), + /* change_spend_size= */ 148, /* effective_feerate= */ CFeeRate(0), /* long_term_feerate= */ CFeeRate(0), /* discard_feerate= */ CFeeRate(0), /* tx_no_inputs_size= */ 0); CoinSelectionParams coin_selection_params_bnb(/* use_bnb= */ true, /* change_output_size= */ 34, - /* change_spend_size= */ 148, /* effective_fee= */ CFeeRate(0), + /* change_spend_size= */ 148, /* effective_feerate= */ CFeeRate(0), /* long_term_feerate= */ CFeeRate(0), /* discard_feerate= */ CFeeRate(0), /* tx_no_inputs_size= */ 0); CoinSet out_set; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index c6c523bedb..04ec10ff6f 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2475,7 +2475,7 @@ bool CWallet::SelectCoinsMinConf(const CAmountMap& mapTargetValue, const CoinEli // END ELEMENTS // Calculate cost of change - CAmount cost_of_change = coin_selection_params.m_discard_feerate.GetFee(coin_selection_params.change_spend_size) + coin_selection_params.effective_fee.GetFee(coin_selection_params.change_output_size); + CAmount cost_of_change = coin_selection_params.m_discard_feerate.GetFee(coin_selection_params.change_spend_size) + coin_selection_params.m_effective_feerate.GetFee(coin_selection_params.change_output_size); // Filter by the min conf specs and add to utxo_pool and calculate effective value for (OutputGroup& group : asset_groups) { @@ -2485,14 +2485,14 @@ bool CWallet::SelectCoinsMinConf(const CAmountMap& mapTargetValue, const CoinEli // Set the effective feerate to 0 as we don't want to use the effective value since the fees will be deducted from the output group.SetFees(CFeeRate(0) /* effective_feerate */, coin_selection_params.m_long_term_feerate); } else { - group.SetFees(coin_selection_params.effective_fee, coin_selection_params.m_long_term_feerate); + group.SetFees(coin_selection_params.m_effective_feerate, coin_selection_params.m_long_term_feerate); } OutputGroup pos_group = group.GetPositiveOnlyGroup(); if (pos_group.effective_value > 0) utxo_pool.push_back(pos_group); } // Calculate the fees for things that aren't inputs - CAmount not_input_fees = coin_selection_params.effective_fee.GetFee(coin_selection_params.tx_noinputs_size); + CAmount not_input_fees = coin_selection_params.m_effective_feerate.GetFee(coin_selection_params.tx_noinputs_size); bnb_used = true; CAmount nValueRet; bool ret = SelectCoinsBnB(utxo_pool, nTargetValue, cost_of_change, setCoinsRet, nValueRet, not_input_fees); @@ -2598,7 +2598,7 @@ bool CWallet::SelectCoins(const std::vector& vAvailableCoins, const CAm coin_selection_params.use_bnb = false; coin.m_input_bytes = 0; } - coin.effective_value = coin.value - coin_selection_params.effective_fee.GetFee(coin.m_input_bytes); + coin.effective_value = coin.value - coin_selection_params.m_effective_feerate.GetFee(coin.m_input_bytes); if (coin_selection_params.use_bnb) { value_to_select[coin.asset] -= coin.effective_value; } else { @@ -3443,11 +3443,11 @@ bool CWallet::CreateTransactionInternal( coin_selection_params.m_discard_feerate = GetDiscardRate(*this); // Get the fee rate to use effective values in coin selection - coin_selection_params.effective_fee = GetMinimumFeeRate(*this, coin_control, &feeCalc); + coin_selection_params.m_effective_feerate = GetMinimumFeeRate(*this, coin_control, &feeCalc); // Do not, ever, assume that it's fine to change the fee rate if the user has explicitly // provided one - if (coin_control.m_feerate && coin_selection_params.effective_fee > *coin_control.m_feerate) { - error = strprintf(_("Fee rate (%s) is lower than the minimum fee rate setting (%s)"), coin_control.m_feerate->ToString(FeeEstimateMode::SAT_VB), coin_selection_params.effective_fee.ToString(FeeEstimateMode::SAT_VB)); + if (coin_control.m_feerate && coin_selection_params.m_effective_feerate > *coin_control.m_feerate) { + error = strprintf(_("Fee rate (%s) is lower than the minimum fee rate setting (%s)"), coin_control.m_feerate->ToString(FeeEstimateMode::SAT_VB), coin_selection_params.m_effective_feerate.ToString(FeeEstimateMode::SAT_VB)); return false; } if (feeCalc.reason == FeeReason::FALLBACK && !m_allow_fallback_fee) { @@ -3795,7 +3795,7 @@ bool CWallet::CreateTransactionInternal( txNew = blind_details->tx_unblinded_unsigned; } - nFeeNeeded = coin_selection_params.effective_fee.GetFee(nBytes); + nFeeNeeded = coin_selection_params.m_effective_feerate.GetFee(nBytes); if (nFeeRet >= nFeeNeeded) { // Reduce fee to only the needed amount if possible. This // prevents potential overpayment in fees if the coins @@ -3809,7 +3809,7 @@ bool CWallet::CreateTransactionInternal( // change output. Only try this once. if (nChangePosInOut == -1 && nSubtractFeeFromAmount == 0 && pick_new_inputs) { unsigned int tx_size_with_change = nBytes + coin_selection_params.change_output_size + 2; // Add 2 as a buffer in case increasing # of outputs changes compact size - CAmount fee_needed_with_change = coin_selection_params.effective_fee.GetFee(tx_size_with_change); + CAmount fee_needed_with_change = coin_selection_params.m_effective_feerate.GetFee(tx_size_with_change); CAmount minimum_value_for_change = GetDustThreshold(change_prototype_txout, coin_selection_params.m_discard_feerate); if (nFeeRet >= fee_needed_with_change + minimum_value_for_change) { pick_new_inputs = false; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 88f4aaa4f0..4e83ad5a55 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -673,19 +673,19 @@ struct CoinSelectionParams bool use_bnb = true; size_t change_output_size = 0; size_t change_spend_size = 0; - CFeeRate effective_fee = CFeeRate(0); + CFeeRate m_effective_feerate; CFeeRate m_long_term_feerate; CFeeRate m_discard_feerate; size_t tx_noinputs_size = 0; //! Indicate that we are subtracting the fee from outputs bool m_subtract_fee_outputs = false; - CoinSelectionParams(bool use_bnb, size_t change_output_size, size_t change_spend_size, CFeeRate effective_fee, + CoinSelectionParams(bool use_bnb, size_t change_output_size, size_t change_spend_size, CFeeRate effective_feerate, CFeeRate long_term_feerate, CFeeRate discard_feerate, size_t tx_noinputs_size) : use_bnb(use_bnb), change_output_size(change_output_size), change_spend_size(change_spend_size), - effective_fee(effective_fee), + m_effective_feerate(effective_feerate), m_long_term_feerate(long_term_feerate), m_discard_feerate(discard_feerate), tx_noinputs_size(tx_noinputs_size) From 79f48d69efcde168b08e6e0e2e02b8c6cff2f5f6 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 20 Jan 2021 11:26:43 +0100 Subject: [PATCH 79/84] test: use pointers in denialofservice_tests/peer_discouragement This is a non-functional change that replaces the `CNode` on-stack variables with `CNode` pointers. The reason for this is that it would allow us to add those `CNode`s to `CConnman::vNodes[]` which in turn would allow us to check that they are disconnected properly - a `CNode` object must be in `CConnman::vNodes[]` in order for its `fDisconnect` flag to be set. If we store pointers to the on-stack variables in `CConnman` then it would crash at the end, trying to `delete` them. Github-Pull: #21571 Rebased-From: 4d6e246fa46f2309e2998b542e4c104d73d29071 (cherry picked from commit dfeb6c10bba80dc91245318feb0ad1d879015a99) --- src/test/denialofservice_tests.cpp | 69 +++++++++++++++++------------- 1 file changed, 39 insertions(+), 30 deletions(-) diff --git a/src/test/denialofservice_tests.cpp b/src/test/denialofservice_tests.cpp index c399da900f..bf981fcbbf 100644 --- a/src/test/denialofservice_tests.cpp +++ b/src/test/denialofservice_tests.cpp @@ -22,6 +22,7 @@ #include +#include #include #include @@ -224,43 +225,51 @@ BOOST_AUTO_TEST_CASE(peer_discouragement) auto connman = MakeUnique(0x1337, 0x1337); auto peerLogic = MakeUnique(chainparams, *connman, banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool); - banman->ClearBanned(); - CAddress addr1(ip(0xa0b0c001), NODE_NONE); - CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 0, 0, CAddress(), "", ConnectionType::INBOUND); - dummyNode1.SetCommonVersion(PROTOCOL_VERSION); - peerLogic->InitializeNode(&dummyNode1); - dummyNode1.fSuccessfullyConnected = true; - peerLogic->Misbehaving(dummyNode1.GetId(), DISCOURAGEMENT_THRESHOLD, /* message */ ""); // Should be discouraged - { - LOCK(dummyNode1.cs_sendProcessing); - BOOST_CHECK(peerLogic->SendMessages(&dummyNode1)); - } - BOOST_CHECK(banman->IsDiscouraged(addr1)); - BOOST_CHECK(!banman->IsDiscouraged(ip(0xa0b0c001|0x0000ff00))); // Different IP, not discouraged + const std::array addr{CAddress{ip(0xa0b0c001), NODE_NONE}, + CAddress{ip(0xa0b0c002), NODE_NONE}}; - CAddress addr2(ip(0xa0b0c002), NODE_NONE); - CNode dummyNode2(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr2, 1, 1, CAddress(), "", ConnectionType::INBOUND); - dummyNode2.SetCommonVersion(PROTOCOL_VERSION); - peerLogic->InitializeNode(&dummyNode2); - dummyNode2.fSuccessfullyConnected = true; - peerLogic->Misbehaving(dummyNode2.GetId(), DISCOURAGEMENT_THRESHOLD - 1, /* message */ ""); + const CNetAddr other_addr{ip(0xa0b0ff01)}; // Not any of addr[]. + + std::array nodes; + + banman->ClearBanned(); + nodes[0] = new CNode{id++, NODE_NETWORK, 0, INVALID_SOCKET, addr[0], 0, 0, CAddress(), "", ConnectionType::INBOUND}; + nodes[0]->SetCommonVersion(PROTOCOL_VERSION); + peerLogic->InitializeNode(nodes[0]); + nodes[0]->fSuccessfullyConnected = true; + peerLogic->Misbehaving(nodes[0]->GetId(), DISCOURAGEMENT_THRESHOLD, /* message */ ""); // Should be discouraged { - LOCK(dummyNode2.cs_sendProcessing); - BOOST_CHECK(peerLogic->SendMessages(&dummyNode2)); + LOCK(nodes[0]->cs_sendProcessing); + BOOST_CHECK(peerLogic->SendMessages(nodes[0])); } - BOOST_CHECK(!banman->IsDiscouraged(addr2)); // 2 not discouraged yet... - BOOST_CHECK(banman->IsDiscouraged(addr1)); // ... but 1 still should be - peerLogic->Misbehaving(dummyNode2.GetId(), 1, /* message */ ""); // 2 reaches discouragement threshold + BOOST_CHECK(banman->IsDiscouraged(addr[0])); + BOOST_CHECK(!banman->IsDiscouraged(other_addr)); // Different address, not discouraged + + nodes[1] = new CNode{id++, NODE_NETWORK, 0, INVALID_SOCKET, addr[1], 1, 1, CAddress(), "", ConnectionType::INBOUND}; + nodes[1]->SetCommonVersion(PROTOCOL_VERSION); + peerLogic->InitializeNode(nodes[1]); + nodes[1]->fSuccessfullyConnected = true; + peerLogic->Misbehaving(nodes[1]->GetId(), DISCOURAGEMENT_THRESHOLD - 1, /* message */ ""); { - LOCK(dummyNode2.cs_sendProcessing); - BOOST_CHECK(peerLogic->SendMessages(&dummyNode2)); + LOCK(nodes[1]->cs_sendProcessing); + BOOST_CHECK(peerLogic->SendMessages(nodes[1])); } - BOOST_CHECK(banman->IsDiscouraged(addr1)); // Expect both 1 and 2 - BOOST_CHECK(banman->IsDiscouraged(addr2)); // to be discouraged now + BOOST_CHECK(!banman->IsDiscouraged(addr[1])); // [1] not discouraged yet... + BOOST_CHECK(banman->IsDiscouraged(addr[0])); // ... but [0] still should be + peerLogic->Misbehaving(nodes[1]->GetId(), 1, /* message */ ""); // [1] reaches discouragement threshold + { + LOCK(nodes[1]->cs_sendProcessing); + BOOST_CHECK(peerLogic->SendMessages(nodes[1])); + } + // Expect both [0] and [1] to be discouraged now. + BOOST_CHECK(banman->IsDiscouraged(addr[0])); + BOOST_CHECK(banman->IsDiscouraged(addr[1])); bool dummy; - peerLogic->FinalizeNode(dummyNode1, dummy); - peerLogic->FinalizeNode(dummyNode2, dummy); + for (CNode* node : nodes) { + peerLogic->FinalizeNode(*node, dummy); + delete node; + } } BOOST_AUTO_TEST_CASE(DoS_bantime) From 3f396ba2296aa19a96fe4e652750d88072693f09 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 20 Jan 2021 11:40:01 +0100 Subject: [PATCH 80/84] test: also check disconnect in denialofservice_tests/peer_discouragement Use `CConnmanTest` instead of `CConnman` and add the nodes to it so that their `fDisconnect` flag is set during disconnection. Github-Pull: #21571 Rebased-From: 637bb6da368b87711005b909f451f94909400092 (cherry picked from commit b765f41164663c93d63e5a401d3b23c586a4e4fe) --- src/test/denialofservice_tests.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/test/denialofservice_tests.cpp b/src/test/denialofservice_tests.cpp index bf981fcbbf..22f1ccb2d2 100644 --- a/src/test/denialofservice_tests.cpp +++ b/src/test/denialofservice_tests.cpp @@ -222,7 +222,7 @@ BOOST_AUTO_TEST_CASE(peer_discouragement) { const CChainParams& chainparams = Params(); auto banman = MakeUnique(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME); - auto connman = MakeUnique(0x1337, 0x1337); + auto connman = MakeUnique(0x1337, 0x1337); auto peerLogic = MakeUnique(chainparams, *connman, banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool); const std::array addr{CAddress{ip(0xa0b0c001), NODE_NONE}, @@ -237,39 +237,48 @@ BOOST_AUTO_TEST_CASE(peer_discouragement) nodes[0]->SetCommonVersion(PROTOCOL_VERSION); peerLogic->InitializeNode(nodes[0]); nodes[0]->fSuccessfullyConnected = true; + connman->AddNode(*nodes[0]); peerLogic->Misbehaving(nodes[0]->GetId(), DISCOURAGEMENT_THRESHOLD, /* message */ ""); // Should be discouraged { LOCK(nodes[0]->cs_sendProcessing); BOOST_CHECK(peerLogic->SendMessages(nodes[0])); } BOOST_CHECK(banman->IsDiscouraged(addr[0])); + BOOST_CHECK(nodes[0]->fDisconnect); BOOST_CHECK(!banman->IsDiscouraged(other_addr)); // Different address, not discouraged nodes[1] = new CNode{id++, NODE_NETWORK, 0, INVALID_SOCKET, addr[1], 1, 1, CAddress(), "", ConnectionType::INBOUND}; nodes[1]->SetCommonVersion(PROTOCOL_VERSION); peerLogic->InitializeNode(nodes[1]); nodes[1]->fSuccessfullyConnected = true; + connman->AddNode(*nodes[1]); peerLogic->Misbehaving(nodes[1]->GetId(), DISCOURAGEMENT_THRESHOLD - 1, /* message */ ""); { LOCK(nodes[1]->cs_sendProcessing); BOOST_CHECK(peerLogic->SendMessages(nodes[1])); } - BOOST_CHECK(!banman->IsDiscouraged(addr[1])); // [1] not discouraged yet... - BOOST_CHECK(banman->IsDiscouraged(addr[0])); // ... but [0] still should be + // [0] is still discouraged/disconnected. + BOOST_CHECK(banman->IsDiscouraged(addr[0])); + BOOST_CHECK(nodes[0]->fDisconnect); + // [1] is not discouraged/disconnected yet. + BOOST_CHECK(!banman->IsDiscouraged(addr[1])); + BOOST_CHECK(!nodes[1]->fDisconnect); peerLogic->Misbehaving(nodes[1]->GetId(), 1, /* message */ ""); // [1] reaches discouragement threshold { LOCK(nodes[1]->cs_sendProcessing); BOOST_CHECK(peerLogic->SendMessages(nodes[1])); } - // Expect both [0] and [1] to be discouraged now. + // Expect both [0] and [1] to be discouraged/disconnected now. BOOST_CHECK(banman->IsDiscouraged(addr[0])); + BOOST_CHECK(nodes[0]->fDisconnect); BOOST_CHECK(banman->IsDiscouraged(addr[1])); + BOOST_CHECK(nodes[1]->fDisconnect); bool dummy; for (CNode* node : nodes) { peerLogic->FinalizeNode(*node, dummy); - delete node; } + connman->ClearNodes(); } BOOST_AUTO_TEST_CASE(DoS_bantime) From e98b9813780c95be55d2c5ee766a20e73fe43d14 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 20 Jan 2021 11:54:17 +0100 Subject: [PATCH 81/84] test: make sure non-IP peers get discouraged and disconnected Github-Pull: #21571 Rebased-From: 81747b21719b3fa6b0fdfc3b084c0104d64903f9 (cherry picked from commit 79cdb4a1984c90a4d9377fbb0dda7bdd61d57031) --- src/test/denialofservice_tests.cpp | 32 +++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/test/denialofservice_tests.cpp b/src/test/denialofservice_tests.cpp index 22f1ccb2d2..5cffa587e1 100644 --- a/src/test/denialofservice_tests.cpp +++ b/src/test/denialofservice_tests.cpp @@ -225,12 +225,18 @@ BOOST_AUTO_TEST_CASE(peer_discouragement) auto connman = MakeUnique(0x1337, 0x1337); auto peerLogic = MakeUnique(chainparams, *connman, banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool); - const std::array addr{CAddress{ip(0xa0b0c001), NODE_NONE}, - CAddress{ip(0xa0b0c002), NODE_NONE}}; + CNetAddr tor_netaddr; + BOOST_REQUIRE( + tor_netaddr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion")); + const CService tor_service(tor_netaddr, Params().GetDefaultPort()); + + const std::array addr{CAddress{ip(0xa0b0c001), NODE_NONE}, + CAddress{ip(0xa0b0c002), NODE_NONE}, + CAddress{tor_service, NODE_NONE}}; const CNetAddr other_addr{ip(0xa0b0ff01)}; // Not any of addr[]. - std::array nodes; + std::array nodes; banman->ClearBanned(); nodes[0] = new CNode{id++, NODE_NETWORK, 0, INVALID_SOCKET, addr[0], 0, 0, CAddress(), "", ConnectionType::INBOUND}; @@ -274,6 +280,26 @@ BOOST_AUTO_TEST_CASE(peer_discouragement) BOOST_CHECK(banman->IsDiscouraged(addr[1])); BOOST_CHECK(nodes[1]->fDisconnect); + // Make sure non-IP peers are discouraged and disconnected properly. + + nodes[2] = new CNode{id++, NODE_NETWORK, 0, INVALID_SOCKET, addr[2], 1, 1, CAddress(), "", + ConnectionType::OUTBOUND_FULL_RELAY}; + nodes[2]->SetCommonVersion(PROTOCOL_VERSION); + peerLogic->InitializeNode(nodes[2]); + nodes[2]->fSuccessfullyConnected = true; + connman->AddNode(*nodes[2]); + peerLogic->Misbehaving(nodes[2]->GetId(), DISCOURAGEMENT_THRESHOLD, /* message */ ""); + { + LOCK(nodes[2]->cs_sendProcessing); + BOOST_CHECK(peerLogic->SendMessages(nodes[2])); + } + BOOST_CHECK(banman->IsDiscouraged(addr[0])); + BOOST_CHECK(banman->IsDiscouraged(addr[1])); + BOOST_CHECK(banman->IsDiscouraged(addr[2])); + BOOST_CHECK(nodes[0]->fDisconnect); + BOOST_CHECK(nodes[1]->fDisconnect); + BOOST_CHECK(nodes[2]->fDisconnect); + bool dummy; for (CNode* node : nodes) { peerLogic->FinalizeNode(*node, dummy); From ebf6a248b84cf8d61fae630c51cf04c44b4e1ea7 Mon Sep 17 00:00:00 2001 From: Anthony Towns Date: Sun, 21 Mar 2021 10:45:17 +1000 Subject: [PATCH 82/84] fuzz: cleanups for versionbits fuzzer Github-Pull: #21489 Rebased-From: aa7f418fe32b3ec53285693a7731decd99be4528 (cherry picked from commit b8af67eeefc9fc9622f839ec8919b7391d91bf6f) --- src/test/fuzz/versionbits.cpp | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/test/fuzz/versionbits.cpp b/src/test/fuzz/versionbits.cpp index 992a5c1321..3dfdcd199e 100644 --- a/src/test/fuzz/versionbits.cpp +++ b/src/test/fuzz/versionbits.cpp @@ -49,9 +49,10 @@ public: int GetStateSinceHeightFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateSinceHeightFor(pindexPrev, dummy_params, m_cache); } BIP9Stats GetStateStatisticsFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateStatisticsFor(pindexPrev, dummy_params); } - bool Condition(int64_t version) const + bool Condition(int32_t version) const { - return ((version >> m_bit) & 1) != 0 && (version & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS; + uint32_t mask = ((uint32_t)1) << m_bit; + return (((version & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) && (version & mask) != 0); } bool Condition(const CBlockIndex* pindex) const { return Condition(pindex->nVersion); } @@ -95,17 +96,20 @@ public: }; } // namespace +std::unique_ptr g_params; + void initialize() { - SelectParams(CBaseChainParams::MAIN); + // this is actually comparatively slow, so only do it once + g_params = CreateChainParams(ArgsManager{}, CBaseChainParams::MAIN); + assert(g_params != nullptr); } -constexpr uint32_t MAX_TIME = 4102444800; // 2100-01-01 +constexpr uint32_t MAX_START_TIME = 4102444800; // 2100-01-01 void test_one_input(const std::vector& buffer) { - const CChainParams& params = Params(); - + const CChainParams& params = *g_params; const int64_t interval = params.GetConsensus().nPowTargetSpacing; assert(interval > 1); // need to be able to halve it assert(interval < std::numeric_limits::max()); @@ -122,9 +126,9 @@ void test_one_input(const std::vector& buffer) // too many blocks at 10min each might cause uint32_t time to overflow if // block_start_time is at the end of the range above - assert(std::numeric_limits::max() - MAX_TIME > interval * max_blocks); + assert(std::numeric_limits::max() - MAX_START_TIME > interval * max_blocks); - const int64_t block_start_time = fuzzed_data_provider.ConsumeIntegralInRange(params.GenesisBlock().nTime, MAX_TIME); + const int64_t block_start_time = fuzzed_data_provider.ConsumeIntegralInRange(params.GenesisBlock().nTime, MAX_START_TIME); // what values for version will we use to signal / not signal? const int32_t ver_signal = fuzzed_data_provider.ConsumeIntegral(); @@ -173,8 +177,10 @@ void test_one_input(const std::vector& buffer) if (checker.Condition(ver_nosignal)) return; if (ver_nosignal < 0) return; - // TOP_BITS should ensure version will be positive + // TOP_BITS should ensure version will be positive and meet min + // version requirement assert(ver_signal > 0); + assert(ver_signal >= VERSIONBITS_LAST_OLD_BLOCK_VERSION); // Now that we have chosen time and versions, setup to mine blocks Blocks blocks(block_start_time, interval, ver_signal, ver_nosignal); @@ -203,7 +209,7 @@ void test_one_input(const std::vector& buffer) } // don't risk exceeding max_blocks or times may wrap around - if (blocks.size() + period*2 > max_blocks) break; + if (blocks.size() + 2 * period > max_blocks) break; } // NOTE: fuzzed_data_provider may be fully consumed at this point and should not be used further @@ -316,7 +322,7 @@ void test_one_input(const std::vector& buffer) assert(false); } - if (blocks.size() >= max_periods * period) { + if (blocks.size() >= period * max_periods) { // we chose the timeout (and block times) so that by the time we have this many blocks it's all over assert(state == ThresholdState::ACTIVE || state == ThresholdState::FAILED); } From b221f4e624e79e7d9ab0a3ac74a9a3ffdf2ca010 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Wed, 22 Sep 2021 16:42:40 +0000 Subject: [PATCH 83/84] doc: update manpages for 0.21.0 Basically I just ran for bin in elements-cli elementsd elements-tx elements-wallet do help2man ./src/$bin > ./doc/man/$bin.1 echo "Done $bin" done --- doc/man/elements-cli.1 | 130 +++++++-- doc/man/elements-tx.1 | 107 +++++-- doc/man/elements-wallet.1 | 181 ++++++++++-- doc/man/elementsd.1 | 568 ++++++++++++++++++++++++++++++++------ 4 files changed, 820 insertions(+), 166 deletions(-) diff --git a/doc/man/elements-cli.1 b/doc/man/elements-cli.1 index 1f0b48904d..55c21d0e59 100644 --- a/doc/man/elements-cli.1 +++ b/doc/man/elements-cli.1 @@ -1,7 +1,7 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.10. -.TH ELEMENTS-CLI "1" "May 2019" "elements-cli v0.17.0.1" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.48.3. +.TH ELEMENTS-CLI "1" "September 2021" "elements-cli elements-0.21.0_rc1" "User Commands" .SH NAME -elements-cli \- manual page for elements-cli v0.17.0.1 +elements-cli \- manual page for elements-cli elements-0.21.0_rc1 .SH SYNOPSIS .B elements-cli [\fI\,options\/\fR] \fI\, \/\fR[\fI\,params\/\fR] \fI\,Send command to Elements Core\/\fR @@ -15,7 +15,7 @@ elements-cli \- manual page for elements-cli v0.17.0.1 .B elements-cli [\fI\,options\/\fR] \fI\,help Get help for a command\/\fR .SH DESCRIPTION -Elements Core RPC client version v0.17.0.1\-dirty +Elements Core RPC client version elements\-0.21.0_rc1 .SH OPTIONS .HP \-? @@ -31,6 +31,15 @@ location. (default: elements.conf) .IP Specify data directory .HP +\fB\-generate\fR +.IP +Generate blocks immediately, equivalent to RPC generatenewaddress +followed by RPC generatetoaddress. Optional positional integer +arguments are number of blocks to generate (default: 1) and +maximum iterations to try (default: 1000000), equivalent to RPC +generatetoaddress nblocks and maxtries arguments. Example: +bitcoin\-cli \fB\-generate\fR 4 1000 +.HP \fB\-getinfo\fR .IP Get general information from the remote server. Note that unlike @@ -43,6 +52,12 @@ be as of a different block from the chain state reported) .IP Pass named instead of positional arguments (default: false) .HP +\fB\-netinfo\fR +.IP +Get network peer connection information from the remote server. An +optional integer argument from 0 to 4 can be passed for different +peers listings (default: 0). +.HP \fB\-rpcclienttimeout=\fR .IP Timeout in seconds during HTTP requests, or 0 for no timeout. (default: @@ -63,8 +78,8 @@ Password for JSON\-RPC connections .HP \fB\-rpcport=\fR .IP -Connect to JSON\-RPC on (default: 8332, testnet: 18332, regtest: -18443) +Connect to JSON\-RPC on (default: 7041, testnet: 18332, signet: +38332, regtest: 18443) .HP \fB\-rpcuser=\fR .IP @@ -77,7 +92,7 @@ Wait for RPC server to start \fB\-rpcwallet=\fR .IP Send RPC for non\-default wallet on RPC server (needs to exactly match -corresponding \fB\-wallet\fR option passed to the daemon). This changes +corresponding \fB\-wallet\fR option passed to elementsd). This changes the RPC endpoint used, e.g. http://127.0.0.1:8332/wallet/ .HP @@ -92,18 +107,28 @@ is used for the RPC password. .IP Read RPC password from standard input as a single line. When combined with \fB\-stdin\fR, the first line from standard input is used for the -RPC password. +RPC password. When combined with \fB\-stdinwalletpassphrase\fR, +\fB\-stdinrpcpass\fR consumes the first line, and \fB\-stdinwalletpassphrase\fR +consumes the second. +.HP +\fB\-stdinwalletpassphrase\fR +.IP +Read wallet passphrase from standard input as a single line. When +combined with \fB\-stdin\fR, the first line from standard input is used +for the wallet passphrase. .HP \fB\-version\fR .IP Print version and exit .PP +Debugging/Testing options: +.PP Chain selection options: .HP \fB\-chain=\fR .IP -Use the chain (default: main). Reserved values: main, test, -regtest +Use the chain (default: liquidv1). Reserved values: main, test, +signet, regtest, liquidv1, liquidv1test .HP \fB\-con_blockheightinheader\fR .IP @@ -136,7 +161,8 @@ signatures are necessary to solve it. .HP \fB\-fedpegscript\fR .IP -The script for the federated peg. +The script for the federated peg enforce from genesis block. This script +may stop being enforced once dynamic federations activates. .HP \fB\-parentgenesisblockhash\fR .IP @@ -147,9 +173,27 @@ The genesis blockhash of the parent chain. Signed blockchain enumberance. Only active when `\-con_signed_blocks` set to true. .HP +\fB\-signet\fR +.IP +Use the signet chain. Equivalent to \fB\-chain\fR=\fI\,signet\/\fR. Note that the network +is defined by the \fB\-signetchallenge\fR parameter +.HP +\fB\-signetchallenge\fR +.IP +Blocks must satisfy the given script to be considered valid (only for +signet networks; defaults to the global default signet test +network challenge) +.HP +\fB\-signetseednode\fR +.IP +Specify a seed node for the signet network, in the hostname[:port] +format, e.g. sig.net:1234 (may be used multiple times to specify +multiple seed nodes; defaults to the global default signet test +network seed node(s)) +.HP \fB\-testnet\fR .IP -Use the test chain +Use the test chain. Equivalent to \fB\-chain\fR=\fI\,test\/\fR. .PP Elements Options: .HP @@ -158,7 +202,7 @@ Elements Options: Defines the amount of block subsidy to start with, at genesis block, in satoshis. .HP -\fB\-con_connect_coinbase\fR +\fB\-con_connect_genesis_outputs\fR .IP Connect outputs in genesis block to utxo database. .HP @@ -167,6 +211,18 @@ Connect outputs in genesis block to utxo database. Starting height for CSV deployment. (default: \fB\-1\fR, which means ACTIVE from genesis) .HP +\fB\-con_dyna_deploy_signal\fR +.IP +Whether to signal for the Dynamic Federations deployment (default: +false). +.HP +\fB\-con_dyna_deploy_start\fR +.IP +Starting height for Dynamic Federations deployment. Once active, +signblockscript becomes a BIP141 WSH scriptPubKey of the original +signblockscript. All other dynamic parameters stay +constant.(default: \fB\-1\fR, which means ACTIVE from genesis) +.HP \fB\-con_elementsmode\fR .TP Use Elements\-like instead of Core\-like witness encoding. @@ -179,27 +235,45 @@ required for CA/CT. (default: true) All non\-zero valued coinbase outputs must go to this scriptPubKey, if set. .HP +\fB\-con_taproot_signal_start\fR +.IP +Whether, and at what blockheight, to start signalling for Taproot +activation (default: false) (regtest, Liquid testnet, or custom +only). +.HP +\fB\-dynamic_epoch_length\fR +.IP +Per\-chain parameter that sets how many blocks dynamic federation voting +and enforcement are in effect for. +.HP \fB\-enforce_pak\fR .IP Causes standardness checks to enforce Pegout Authorization Key(PAK) -validation, and miner to include PAK commitments when configured. -Can not be set when acceptnonstdtx is set to true. +validation before dynamic federations, and consensus enforcement +after. .HP \fB\-multi_data_permitted\fR .IP -Allow relay of multiple OP_RETURN outputs. (default: true) +Allow relay of multiple OP_RETURN outputs. (default: \fB\-enforce_pak\fR) .HP \fB\-pak\fR .IP -Entries in the PAK list. Order of entries matter. -.SH COPYRIGHT -Copyright (C) 2009-2019 The Elements Project developers -Copyright (C) 2009-2019 The Bitcoin Core developers - -Please contribute if you find Elements Core useful. Visit - for further information about the software. -The source code is available from . - -This is experimental software. -Distributed under the MIT software license, see the accompanying file COPYING -or +Sets the 'first extension space' field to the pak entries ala +pre\-dynamic federations. Only used for testing in custom chains. +.HP +\fB\-total_valid_epochs\fR +.IP +Per\-chain parameter that sets how long a particular fedpegscript is in +effect for. +.SH "SEE ALSO" +The full documentation for +.B elements-cli +is maintained as a Texinfo manual. If the +.B info +and +.B elements-cli +programs are properly installed at your site, the command +.IP +.B info elements-cli +.PP +should give you access to the complete manual. diff --git a/doc/man/elements-tx.1 b/doc/man/elements-tx.1 index d22150ed69..c758e3291f 100644 --- a/doc/man/elements-tx.1 +++ b/doc/man/elements-tx.1 @@ -1,7 +1,7 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.10. -.TH ELEMENTS-TX "1" "May 2019" "elements-tx v0.17.0.1" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.48.3. +.TH ELEMENTS-TX "1" "September 2021" "elements-tx elements-0.21.0_rc1" "User Commands" .SH NAME -elements-tx \- manual page for elements-tx v0.17.0.1 +elements-tx \- manual page for elements-tx elements-0.21.0_rc1 .SH SYNOPSIS .B elements-tx [\fI\,options\/\fR] \fI\, \/\fR[\fI\,commands\/\fR] \fI\,Update hex-encoded bitcoin transaction\/\fR @@ -9,12 +9,12 @@ elements-tx \- manual page for elements-tx v0.17.0.1 .B elements-tx [\fI\,options\/\fR] \fI\,-create \/\fR[\fI\,commands\/\fR] \fI\,Create hex-encoded bitcoin transaction\/\fR .SH DESCRIPTION -Elements Core elements\-tx utility version v0.17.0.1\-dirty +Elements Core elements\-tx utility version elements\-0.21.0_rc1 .SH OPTIONS .HP \-? .IP -This help message +Print this help message and exit .HP \fB\-create\fR .IP @@ -28,12 +28,14 @@ Select JSON output .IP Output only the hex\-encoded transaction id of the resultant transaction. .PP +Debugging/Testing options: +.PP Chain selection options: .HP \fB\-chain=\fR .IP -Use the chain (default: main). Reserved values: main, test, -regtest +Use the chain (default: liquidv1). Reserved values: main, test, +signet, regtest, liquidv1, liquidv1test .HP \fB\-con_blockheightinheader\fR .IP @@ -66,7 +68,8 @@ signatures are necessary to solve it. .HP \fB\-fedpegscript\fR .IP -The script for the federated peg. +The script for the federated peg enforce from genesis block. This script +may stop being enforced once dynamic federations activates. .HP \fB\-parentgenesisblockhash\fR .IP @@ -77,17 +80,36 @@ The genesis blockhash of the parent chain. Signed blockchain enumberance. Only active when `\-con_signed_blocks` set to true. .HP +\fB\-signet\fR +.IP +Use the signet chain. Equivalent to \fB\-chain\fR=\fI\,signet\/\fR. Note that the network +is defined by the \fB\-signetchallenge\fR parameter +.HP +\fB\-signetchallenge\fR +.IP +Blocks must satisfy the given script to be considered valid (only for +signet networks; defaults to the global default signet test +network challenge) +.HP +\fB\-signetseednode\fR +.IP +Specify a seed node for the signet network, in the hostname[:port] +format, e.g. sig.net:1234 (may be used multiple times to specify +multiple seed nodes; defaults to the global default signet test +network seed node(s)) +.HP \fB\-testnet\fR .IP -Use the test chain +Use the test chain. Equivalent to \fB\-chain\fR=\fI\,test\/\fR. .PP Elements Options: .HP \fB\-con_blocksubsidy\fR .IP -Defines the amount of block subsidy to start with, at genesis block. +Defines the amount of block subsidy to start with, at genesis block, in +satoshis. .HP -\fB\-con_connect_coinbase\fR +\fB\-con_connect_genesis_outputs\fR .IP Connect outputs in genesis block to utxo database. .HP @@ -96,6 +118,18 @@ Connect outputs in genesis block to utxo database. Starting height for CSV deployment. (default: \fB\-1\fR, which means ACTIVE from genesis) .HP +\fB\-con_dyna_deploy_signal\fR +.IP +Whether to signal for the Dynamic Federations deployment (default: +false). +.HP +\fB\-con_dyna_deploy_start\fR +.IP +Starting height for Dynamic Federations deployment. Once active, +signblockscript becomes a BIP141 WSH scriptPubKey of the original +signblockscript. All other dynamic parameters stay +constant.(default: \fB\-1\fR, which means ACTIVE from genesis) +.HP \fB\-con_elementsmode\fR .TP Use Elements\-like instead of Core\-like witness encoding. @@ -108,19 +142,36 @@ required for CA/CT. (default: true) All non\-zero valued coinbase outputs must go to this scriptPubKey, if set. .HP +\fB\-con_taproot_signal_start\fR +.IP +Whether, and at what blockheight, to start signalling for Taproot +activation (default: false) (regtest, Liquid testnet, or custom +only). +.HP +\fB\-dynamic_epoch_length\fR +.IP +Per\-chain parameter that sets how many blocks dynamic federation voting +and enforcement are in effect for. +.HP \fB\-enforce_pak\fR .IP Causes standardness checks to enforce Pegout Authorization Key(PAK) -validation, and miner to include PAK commitments when configured. -Can not be set when acceptnonstdtx is set to true. +validation before dynamic federations, and consensus enforcement +after. .HP \fB\-multi_data_permitted\fR .IP -Allow relay of multiple OP_RETURN outputs. (default: true) +Allow relay of multiple OP_RETURN outputs. (default: \fB\-enforce_pak\fR) .HP \fB\-pak\fR .IP -Entries in the PAK list. Order of entries matter. +Sets the 'first extension space' field to the pak entries ala +pre\-dynamic federations. Only used for testing in custom chains. +.HP +\fB\-total_valid_epochs\fR +.IP +Per\-chain parameter that sets how long a particular fedpegscript is in +effect for. .PP Commands: .IP @@ -180,7 +231,7 @@ sign=SIGHASH\-FLAGS .IP Add zero or more signatures to transaction. This command requires JSON registers:prevtxs=JSON object, privatekeys=JSON object. See -signrawtransaction docs for format of sighash flags, JSON +signrawtransactionwithkey docs for format of sighash flags, JSON objects. .PP Register Commands: @@ -197,15 +248,15 @@ Load JSON file FILENAME into register NAME set=NAME:JSON\-STRING .IP Set register NAME to given JSON\-STRING -.SH COPYRIGHT -Copyright (C) 2009-2019 The Elements Project developers -Copyright (C) 2009-2019 The Bitcoin Core developers - -Please contribute if you find Elements Core useful. Visit - for further information about the software. -The source code is available from . - -This is experimental software. -Distributed under the MIT software license, see the accompanying file COPYING -or - +.SH "SEE ALSO" +The full documentation for +.B elements-tx +is maintained as a Texinfo manual. If the +.B info +and +.B elements-tx +programs are properly installed at your site, the command +.IP +.B info elements-tx +.PP +should give you access to the complete manual. diff --git a/doc/man/elements-wallet.1 b/doc/man/elements-wallet.1 index b6bc88cf58..cb888494aa 100644 --- a/doc/man/elements-wallet.1 +++ b/doc/man/elements-wallet.1 @@ -1,12 +1,12 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.6. -.TH ELEMENTS-WALLET "1" "February 2019" "elements-wallet v0.17.99.0" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.48.3. +.TH ELEMENTS-WALLET "1" "September 2021" "elements-wallet elements-0.21.0_rc1" "User Commands" .SH NAME -elements-wallet \- manual page for elements-wallet v0.17.99.0 +elements-wallet \- manual page for elements-wallet elements-0.21.0_rc1 .SH DESCRIPTION -Elements Core elements\-wallet version v0.17.99.0 +Elements Core elements\-wallet version elements\-0.21.0_rc1 .PP -wallet\-tool is an offline tool for creating and interacting with Elements Core wallet files. -By default wallet\-tool will act on wallets in the default mainnet wallet directory in the datadir. +elements\-wallet is an offline tool for creating and interacting with Elements Core wallet files. +By default elements\-wallet will act on wallets in the default mainnet wallet directory in the datadir. To change the target wallet, use the \fB\-datadir\fR, \fB\-wallet\fR and \fB\-testnet\fR/\-regtest arguments. .SS "Usage:" .IP @@ -34,13 +34,150 @@ Output debugging information (default: 0). \fB\-printtoconsole\fR .IP Send trace/debug info to console (default: 1 when no \fB\-debug\fR is true, 0 -otherwise. +otherwise). .PP Chain selection options: .HP +\fB\-chain=\fR +.IP +Use the chain (default: liquidv1). Reserved values: main, test, +signet, regtest, liquidv1, liquidv1test +.HP +\fB\-con_blockheightinheader\fR +.IP +Whether the chain includes the block height directly in the header, for +easier validation of block height in low\-resource environments. +(default: true) +.HP +\fB\-con_has_parent_chain\fR +.IP +Whether or not there is a parent chain. +.HP +\fB\-con_max_block_sig_size\fR +.IP +Max allowed witness data for the signed block header. +.HP +\fB\-con_parent_chain_signblockscript\fR +.IP +Whether parent chain uses pow or signed blocks. If the parent chain uses +signed blocks, the challenge (scriptPubKey) script. If not, an +empty string. (default: empty script [ie parent uses pow]) +.HP +\fB\-con_parentpowlimit\fR +.IP +The proof\-of\-work limit value for the parent chain. +.HP +\fB\-con_signed_blocks\fR +.IP +Signed blockchain. Uses input of `\-signblockscript` to define what +signatures are necessary to solve it. +.HP +\fB\-fedpegscript\fR +.IP +The script for the federated peg enforce from genesis block. This script +may stop being enforced once dynamic federations activates. +.HP +\fB\-parentgenesisblockhash\fR +.IP +The genesis blockhash of the parent chain. +.HP +\fB\-signblockscript\fR +.IP +Signed blockchain enumberance. Only active when `\-con_signed_blocks` set +to true. +.HP +\fB\-signet\fR +.IP +Use the signet chain. Equivalent to \fB\-chain\fR=\fI\,signet\/\fR. Note that the network +is defined by the \fB\-signetchallenge\fR parameter +.HP +\fB\-signetchallenge\fR +.IP +Blocks must satisfy the given script to be considered valid (only for +signet networks; defaults to the global default signet test +network challenge) +.HP +\fB\-signetseednode\fR +.IP +Specify a seed node for the signet network, in the hostname[:port] +format, e.g. sig.net:1234 (may be used multiple times to specify +multiple seed nodes; defaults to the global default signet test +network seed node(s)) +.HP \fB\-testnet\fR .IP -Use the test chain +Use the test chain. Equivalent to \fB\-chain\fR=\fI\,test\/\fR. +.PP +Elements Options: +.HP +\fB\-con_blocksubsidy\fR +.IP +Defines the amount of block subsidy to start with, at genesis block, in +satoshis. +.HP +\fB\-con_connect_genesis_outputs\fR +.IP +Connect outputs in genesis block to utxo database. +.HP +\fB\-con_csv_deploy_start\fR +.IP +Starting height for CSV deployment. (default: \fB\-1\fR, which means ACTIVE +from genesis) +.HP +\fB\-con_dyna_deploy_signal\fR +.IP +Whether to signal for the Dynamic Federations deployment (default: +false). +.HP +\fB\-con_dyna_deploy_start\fR +.IP +Starting height for Dynamic Federations deployment. Once active, +signblockscript becomes a BIP141 WSH scriptPubKey of the original +signblockscript. All other dynamic parameters stay +constant.(default: \fB\-1\fR, which means ACTIVE from genesis) +.HP +\fB\-con_elementsmode\fR +.TP +Use Elements\-like instead of Core\-like witness encoding. +This is +.IP +required for CA/CT. (default: true) +.HP +\fB\-con_mandatorycoinbase\fR +.IP +All non\-zero valued coinbase outputs must go to this scriptPubKey, if +set. +.HP +\fB\-con_taproot_signal_start\fR +.IP +Whether, and at what blockheight, to start signalling for Taproot +activation (default: false) (regtest, Liquid testnet, or custom +only). +.HP +\fB\-dynamic_epoch_length\fR +.IP +Per\-chain parameter that sets how many blocks dynamic federation voting +and enforcement are in effect for. +.HP +\fB\-enforce_pak\fR +.IP +Causes standardness checks to enforce Pegout Authorization Key(PAK) +validation before dynamic federations, and consensus enforcement +after. +.HP +\fB\-multi_data_permitted\fR +.IP +Allow relay of multiple OP_RETURN outputs. (default: \fB\-enforce_pak\fR) +.HP +\fB\-pak\fR +.IP +Sets the 'first extension space' field to the pak entries ala +pre\-dynamic federations. Only used for testing in custom chains. +.HP +\fB\-total_valid_epochs\fR +.IP +Per\-chain parameter that sets how long a particular fedpegscript is in +effect for. .PP Commands: .IP @@ -51,14 +188,20 @@ Create new wallet file info .IP Get wallet info -.SH COPYRIGHT -Copyright (C) 2009-2020 The Elements Project developers -Copyright (C) 2009-2019 The Bitcoin Core developers - -Please contribute if you find Bitcoin Core useful. Visit - for further information about the software. -The source code is available from . - -This is experimental software. -Distributed under the MIT software license, see the accompanying file COPYING -or +.IP +salvage +.IP +Attempt to recover private keys from a corrupt wallet. Warning: +\&'salvage' is experimental. +.SH "SEE ALSO" +The full documentation for +.B elements-wallet +is maintained as a Texinfo manual. If the +.B info +and +.B elements-wallet +programs are properly installed at your site, the command +.IP +.B info elements-wallet +.PP +should give you access to the complete manual. diff --git a/doc/man/elementsd.1 b/doc/man/elementsd.1 index c81693970a..b1ac8ee050 100644 --- a/doc/man/elementsd.1 +++ b/doc/man/elementsd.1 @@ -1,12 +1,12 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.6. -.TH ELEMENTSD "1" "February 2019" "elementsd v0.17.99.0" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.48.3. +.TH ELEMENTSD "1" "September 2021" "elementsd elements-0.21.0_rc1" "User Commands" .SH NAME -elementsd \- manual page for elementsd v0.17.99.0 +elementsd \- manual page for elementsd elements-0.21.0_rc1 .SH SYNOPSIS .B elementsd -[\fI\,options\/\fR] \fI\,Start Elements Core Daemon\/\fR +[\fI\,options\/\fR] \fI\,Start Elements Core\/\fR .SH DESCRIPTION -Elements Core Daemon version v0.17.99.0 +Elements Core version elements\-0.21.0_rc1 .SH OPTIONS .HP \-? @@ -23,9 +23,17 @@ long fork (%s in cmd is replaced by message) If this block is in the chain assume that it and its ancestors are valid and potentially skip their script verification (0 to verify all, default: -0000000000000000002e63058c023a9a1de233554f28c7b21380b6c9003f36a8, +0000000000000000000000000000000000000000000000000000000000000000, testnet: -0000000000000037a8cd3e06cd5edbfe9dd1dbcc5dacab279376ef7cfc2b4c75) +000000000000006433d1efec504c53ca332b64963c425395515b01977bd7b3b0, +signet: +0000002a1de0f46379358c1fd09906f7ac59adf3712323ed90eb59e4c183c020) +.HP +\fB\-blockfilterindex=\fR +.IP +Maintain an index of compact filters by block (default: 0, values: +basic). If is not supplied or if = 1, indexes for +all known types are enabled. .HP \fB\-blocknotify=\fR .IP @@ -39,12 +47,20 @@ Extra transactions to keep in memory for compact block reconstructions .HP \fB\-blocksdir=\fR .IP -Specify blocks directory (default: /blocks) +Specify directory to hold blocks subdirectory for *.dat files (default: +) +.HP +\fB\-blocksonly\fR +.IP +Whether to reject transactions from network peers. Automatic broadcast +and rebroadcast of any transactions from inbound peers is +disabled, unless the peer has the 'forcerelay' permission. RPC +transactions are not affected. (default: 0) .HP \fB\-conf=\fR .IP -Specify configuration file. Relative paths will be prefixed by datadir -location. (default: elements.conf) +Specify path to read\-only configuration file. Relative paths will be +prefixed by datadir location. (default: elements.conf) .HP \fB\-daemon\fR .IP @@ -56,7 +72,9 @@ Specify data directory .HP \fB\-dbcache=\fR .IP -Set database cache size in MiB (4 to 16384, default: 450) +Maximum database cache size MiB (4 to 16384, default: 450). In +addition, unused mempool memory is shared for this cache (see +\fB\-maxmempool\fR). .HP \fB\-debuglogfile=\fR .IP @@ -71,7 +89,7 @@ Specify additional configuration file, relative to the \fB\-datadir\fR path .HP \fB\-loadblock=\fR .IP -Imports blocks from external blk000??.dat file on startup +Imports blocks from external file on startup .HP \fB\-maxmempool=\fR .IP @@ -88,7 +106,7 @@ Do not keep transactions in the mempool longer than hours (default: .HP \fB\-par=\fR .IP -Set the number of script verification threads (\fB\-8\fR to 16, 0 = auto, <0 = +Set the number of script verification threads (\fB\-64\fR to 15, 0 = auto, <0 = leave that many cores free, default: 0) .HP \fB\-persistmempool\fR @@ -122,6 +140,18 @@ Rebuild chain state from the currently indexed blocks. When in pruning mode or if blocks on disk might be corrupted, use full \fB\-reindex\fR instead. .HP +\fB\-settings=\fR +.IP +Specify path to dynamic settings data file. Can be disabled with +\fB\-nosettings\fR. File is written at runtime and not meant to be +edited by users (use elements.conf instead for custom settings). +Relative paths will be prefixed by datadir location. (default: +settings.json) +.HP +\fB\-startupnotify=\fR +.IP +Execute command on startup. +.HP \fB\-sysperms\fR .IP Create new files with system default permissions, instead of umask 077 @@ -144,19 +174,24 @@ Add a node to connect to and attempt to keep the connection open (see the `addnode` RPC command help for more info). This option can be specified multiple times to add multiple nodes. .HP -\fB\-banscore=\fR +\fB\-asmap=\fR .IP -Threshold for disconnecting misbehaving peers (default: 100) +Specify asn mapping used for bucketing of the peers (default: +ip_asn.map). Relative paths will be prefixed by the net\-specific +datadir location. .HP \fB\-bantime=\fR .IP -Number of seconds to keep misbehaving peers from reconnecting (default: +Default duration (in seconds) of manually configured bans (default: 86400) .HP -\fB\-bind=\fR +\fB\-bind=\fR[:][=onion] .IP -Bind to given address and always listen on it. Use [host]:port notation -for IPv6 +Bind to given address and always listen on it (default: 0.0.0.0). Use +[host]:port notation for IPv6. Append =onion to tag any incoming +connections to that address and port as incoming Tor connections +(default: 127.0.0.1:37041=onion, testnet: 127.0.0.1:18334=onion, +signet: 127.0.0.1:38334=onion, regtest: 127.0.0.1:18445=onion) .HP \fB\-connect=\fR .IP @@ -193,7 +228,7 @@ Accept connections from outside (default: 1 if no \fB\-proxy\fR or \fB\-connect\ .HP \fB\-listenonion\fR .IP -Automatically create Tor hidden service (default: 1) +Automatically create Tor onion service (default: 1) .HP \fB\-maxconnections=\fR .IP @@ -215,12 +250,18 @@ amount. (default: 4200 seconds) .HP \fB\-maxuploadtarget=\fR .IP -Tries to keep outbound traffic under the given target (in MiB per 24h), -0 = no limit (default: 0) +Tries to keep outbound traffic under the given target (in MiB per 24h). +Limit does not apply to peers with 'download' permission. 0 = no +limit (default: 0) +.HP +\fB\-networkactive\fR +.IP +Enable all P2P network activity (default: 1). Can be changed by the +setnetworkactive RPC command .HP \fB\-onion=\fR .IP -Use separate SOCKS5 proxy to reach peers via Tor hidden services, set +Use separate SOCKS5 proxy to reach peers via Tor onion services, set \fB\-noonion\fR to disable (default: \fB\-proxy\fR) .HP \fB\-onlynet=\fR @@ -230,10 +271,14 @@ onion). Incoming connections are not affected by this option. This option can be specified multiple times to allow multiple networks. .HP +\fB\-peerblockfilters\fR +.IP +Serve compact block filters to peers per BIP 157 (default: 0) +.HP \fB\-peerbloomfilters\fR .IP Support filtering of blocks and transaction with bloom filters (default: -1) +0) .HP \fB\-permitbaremultisig\fR .IP @@ -241,8 +286,9 @@ Relay non\-P2SH multisig (default: 1) .HP \fB\-port=\fR .IP -Listen for connections on (default: 8333, testnet: 18333, -regtest: 18444) +Listen for connections on . Nodes not using the default ports +(default: 7042, testnet: 18333, signet: 38333, regtest: 18444) +are unlikely to get incoming connections. .HP \fB\-proxy=\fR .IP @@ -273,29 +319,35 @@ Tor control port to use if onion listening enabled (default: .IP Tor control port password (default: empty) .HP -\fB\-upnp\fR +\fB\-whitebind=\fR<[permissions@]addr> .IP -Use UPnP to map the listening port (default: 0) +Bind to the given address and add permission flags to the peers +connecting to it. Use [host]:port notation for IPv6. Allowed +permissions: bloomfilter (allow requesting BIP37 filtered blocks +and transactions), noban (do not ban for misbehavior; implies +download), forcerelay (relay transactions that are already in the +mempool; implies relay), relay (relay even in \fB\-blocksonly\fR mode, +and unlimited transaction announcements), mempool (allow +requesting BIP35 mempool contents), download (allow getheaders +during IBD, no disconnect after maxuploadtarget limit), addr +(responses to GETADDR avoid hitting the cache and contain random +records with the most up\-to\-date info). Specify multiple +permissions separated by commas (default: +download,noban,mempool,relay). Can be specified multiple times. .HP -\fB\-whitebind=\fR +\fB\-whitelist=\fR<[permissions@]IP address or network> .IP -Bind to given address and whitelist peers connecting to it. Use -[host]:port notation for IPv6 -.HP -\fB\-whitelist=\fR -.IP -Whitelist peers connecting from the given IP address (e.g. 1.2.3.4) or -CIDR notated network (e.g. 1.2.3.0/24). Can be specified multiple -times. Whitelisted peers cannot be DoS banned and their -transactions are always relayed, even if they are already in the -mempool, useful e.g. for a gateway +Add permission flags to the peers connecting from the given IP address +(e.g. 1.2.3.4) or CIDR\-notated network (e.g. 1.2.3.0/24). Uses +the same permissions as \fB\-whitebind\fR. Can be specified multiple +times. .PP Wallet options: .HP \fB\-addresstype\fR .IP What type of addresses to use ("legacy", "p2sh\-segwit", or "bech32", -default: "p2sh\-segwit") +default: "bech32") .HP \fB\-avoidpartialspends\fR .IP @@ -303,7 +355,8 @@ Group outputs by address, selecting all or none, instead of selecting on a per\-output basis. Privacy is improved as an address is only used once (unless someone sends to it after spending from it), but may result in slightly higher fees as suboptimal coin -selection may result due to the added limitation (default: 0) +selection may result due to the added limitation (default: 0 +(always enabled for wallets with "avoid_reuse" enabled)) .HP \fB\-changetype\fR .IP @@ -327,16 +380,25 @@ limited by the fee estimate for the longest target \fB\-fallbackfee=\fR .IP A fee rate (in BTC/kB) that will be used when fee estimation has -insufficient data (default: 0.0002) +insufficient data. 0 to entirely disable the fallbackfee feature. +(default: 0.00) .HP \fB\-keypool=\fR .IP -Set key pool size to (default: 1000) +Set key pool size to (default: 1000). Warning: Smaller sizes may +increase the risk of losing funds when restoring from an old +backup, if none of the addresses in the original keypool have +been used. +.HP +\fB\-maxapsfee=\fR +.IP +Spend up to this amount in additional (absolute) fees (in BTC) if it +allows the use of partial spend avoidance (default: 0.00) .HP \fB\-mintxfee=\fR .IP Fees (in BTC/kB) smaller than this are considered zero fee for -transaction creation (default: 0.00001) +transaction creation (default: 0.000001) .HP \fB\-paytxfee=\fR .IP @@ -346,10 +408,6 @@ Fee (in BTC/kB) to add to transactions you send (default: 0.00) .IP Rescan the block chain for missing wallet transactions on startup .HP -\fB\-salvagewallet\fR -.IP -Attempt to recover private keys from a corrupt wallet on startup -.HP \fB\-spendzeroconfchange\fR .IP Spend unconfirmed change when sending transactions (default: 1) @@ -359,18 +417,15 @@ Spend unconfirmed change when sending transactions (default: 1) If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: 6) .HP -\fB\-upgradewallet\fR -.IP -Upgrade wallet to latest format on startup -.HP \fB\-wallet=\fR .IP -Specify wallet database path. Can be specified multiple times to load -multiple wallets. Path is interpreted relative to if -it is not absolute, and will be created if it does not exist (as -a directory containing a wallet.dat file and log files). For -backwards compatibility this will also accept names of existing -data files in .) +Specify wallet path to load at startup. Can be used multiple times to +load multiple wallets. Path is to a directory containing wallet +data and log files. If the path is not absolute, it is +interpreted relative to . This only loads existing +wallets and does not create new ones. For backwards compatibility +this also accepts names of existing top\-level data files in +. .HP \fB\-walletbroadcast\fR .IP @@ -383,18 +438,15 @@ exists, otherwise ) .HP \fB\-walletnotify=\fR .IP -Execute command when a wallet transaction changes (%s in cmd is replaced -by TxID) +Execute command when a wallet transaction changes. %s in cmd is replaced +by TxID and %w is replaced by wallet name. %w is not currently +implemented on windows. On systems where %w is supported, it +should NOT be quoted because this would break shell escaping used +to invoke the command. .HP \fB\-walletrbf\fR .IP -Send transactions with full\-RBF opt\-in enabled (RPC only, default: 0) -.HP -\fB\-zapwallettxes=\fR -.IP -Delete all wallet transactions and only recover those parts of the -blockchain through \fB\-rescan\fR on startup (1 = keep tx meta data e.g. -payment request information, 2 = drop tx meta data) +Send transactions with full\-RBF opt\-in enabled (RPC only, default: 1) .PP ZeroMQ notification options: .HP @@ -402,17 +454,43 @@ ZeroMQ notification options: .IP Enable publish hash block in
.HP +\fB\-zmqpubhashblockhwm=\fR +.IP +Set publish hash block outbound message high water mark (default: 1000) +.HP \fB\-zmqpubhashtx=\fR
.IP Enable publish hash transaction in
.HP +\fB\-zmqpubhashtxhwm=\fR +.IP +Set publish hash transaction outbound message high water mark (default: +1000) +.HP \fB\-zmqpubrawblock=\fR
.IP Enable publish raw block in
.HP +\fB\-zmqpubrawblockhwm=\fR +.IP +Set publish raw block outbound message high water mark (default: 1000) +.HP \fB\-zmqpubrawtx=\fR
.IP Enable publish raw transaction in
+.HP +\fB\-zmqpubrawtxhwm=\fR +.IP +Set publish raw transaction outbound message high water mark (default: +1000) +.HP +\fB\-zmqpubsequence=\fR
+.IP +Enable publish hash block and tx sequence in
+.HP +\fB\-zmqpubsequencehwm=\fR +.IP +Set publish hash sequence message high water mark (default: 1000) .PP Debugging/Testing options: .HP @@ -421,9 +499,9 @@ Debugging/Testing options: Output debugging information (default: \fB\-nodebug\fR, supplying is optional). If is not supplied or if = 1, output all debugging information. can be: net, tor, -mempool, http, bench, zmq, db, rpc, estimatefee, addrman, +mempool, http, bench, zmq, walletdb, rpc, estimatefee, addrman, selectcoins, reindex, cmpctblock, rand, prune, proxy, mempoolrej, -libevent, coindb, qt, leveldb. +libevent, coindb, qt, leveldb, validation. .HP \fB\-debugexclude=\fR .IP @@ -439,15 +517,19 @@ Print help message with debugging options and exit .IP Include IP addresses in debug output (default: 0) .HP +\fB\-logthreadnames\fR +.IP +Prepend debug output with name of the originating thread (only available +on platforms supporting thread_local) (default: 0) +.HP \fB\-logtimestamps\fR .IP Prepend debug output with timestamp (default: 1) .HP \fB\-maxtxfee=\fR .IP -Maximum total fees (in BTC) to use in a single wallet transaction or raw -transaction; setting this too low may abort large transactions -(default: 0.10) +Maximum total fees (in BTC) to use in a single wallet transaction; +setting this too low may abort large transactions (default: 0.10) .HP \fB\-printtoconsole\fR .IP @@ -464,9 +546,158 @@ Append comment to the user agent string .PP Chain selection options: .HP +\fB\-bech32_hrp\fR +.IP +The human\-readable part of the chain's bech32 encoding. (default: ex) +.HP +\fB\-blech32_hrp\fR +.IP +The human\-readable part of the chain's blech32 encoding. Used in +confidential addresses.(default: lq) +.HP +\fB\-chain=\fR +.IP +Use the chain (default: liquidv1). Reserved values: main, test, +signet, regtest, liquidv1, liquidv1test +.HP +\fB\-con_blockheightinheader\fR +.IP +Whether the chain includes the block height directly in the header, for +easier validation of block height in low\-resource environments. +(default: true) +.HP +\fB\-con_has_parent_chain\fR +.IP +Whether or not there is a parent chain. +.HP +\fB\-con_max_block_sig_size\fR +.IP +Max allowed witness data for the signed block header. +.HP +\fB\-con_parent_chain_signblockscript\fR +.IP +Whether parent chain uses pow or signed blocks. If the parent chain uses +signed blocks, the challenge (scriptPubKey) script. If not, an +empty string. (default: empty script [ie parent uses pow]) +.HP +\fB\-con_parent_pegged_asset=\fR +.IP +Asset ID (hex) for pegged asset for when parent chain has CA. (default: +0x00) +.HP +\fB\-con_parentpowlimit\fR +.IP +The proof\-of\-work limit value for the parent chain. +.HP +\fB\-con_signed_blocks\fR +.IP +Signed blockchain. Uses input of `\-signblockscript` to define what +signatures are necessary to solve it. +.HP +\fB\-ct_bits\fR +.IP +The default number of hiding bits in a rangeproof. Will be exceeded to +cover amounts exceeding the maximum hiding value. (default: 52) +.HP +\fB\-ct_exponent\fR +.IP +The hiding exponent. (default: 0) +.HP +\fB\-extprvkeyprefix\fR +.IP +The 4\-byte prefix, in hex, of the chain's base58 extended private key +encoding. (default: 0488ade4) +.HP +\fB\-extpubkeyprefix\fR +.IP +The 4\-byte prefix, in hex, of the chain's base58 extended public key +encoding. (default: 0488b21e) +.HP +\fB\-fedpegscript\fR +.IP +The script for the federated peg enforce from genesis block. This script +may stop being enforced once dynamic federations activates. +.HP +\fB\-feeasset=\fR +.IP +Asset ID (hex) for mempool/relay fees (default: +6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d) +.HP +\fB\-initialreissuancetokens=\fR +.IP +The amount of reissuance tokens created in the genesis block. (default: +0) +.HP +\fB\-parent_bech32_hrp\fR +.IP +The human\-readable part of the parent chain's bech32 encoding. (default: +bc) +.HP +\fB\-parent_blech32_hrp\fR +.IP +The human\-readable part of the parent chain's blech32 encoding. +(default: bc) +.HP +\fB\-parentgenesisblockhash\fR +.IP +The genesis blockhash of the parent chain. +.HP +\fB\-parentpubkeyprefix\fR +.IP +The byte prefix, in decimal, of the parent chain's base58 pubkey +address. (default: 111) +.HP +\fB\-parentscriptprefix\fR +.IP +The byte prefix, in decimal, of the parent chain's base58 script +address. (default: 196) +.HP +\fB\-pubkeyprefix\fR +.IP +The byte prefix, in decimal, of the chain's base58 pubkey address. +(default: 57) +.HP +\fB\-scriptprefix\fR +.IP +The byte prefix, in decimal, of the chain's base58 script address. +(default: 39) +.HP +\fB\-secretprefix\fR +.IP +The byte prefix, in decimal, of the chain's base58 secret key encoding. +(default: 128) +.HP +\fB\-signblockscript\fR +.IP +Signed blockchain enumberance. Only active when `\-con_signed_blocks` set +to true. +.HP +\fB\-signet\fR +.IP +Use the signet chain. Equivalent to \fB\-chain\fR=\fI\,signet\/\fR. Note that the network +is defined by the \fB\-signetchallenge\fR parameter +.HP +\fB\-signetchallenge\fR +.IP +Blocks must satisfy the given script to be considered valid (only for +signet networks; defaults to the global default signet test +network challenge) +.HP +\fB\-signetseednode\fR +.IP +Specify a seed node for the signet network, in the hostname[:port] +format, e.g. sig.net:1234 (may be used multiple times to specify +multiple seed nodes; defaults to the global default signet test +network seed node(s)) +.HP +\fB\-subsidyasset=\fR +.IP +Asset ID (hex) for the block subsidy (default: +6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d) +.HP \fB\-testnet\fR .IP -Use the test chain +Use the test chain. Equivalent to \fB\-chain\fR=\fI\,test\/\fR. .PP Node relay options: .HP @@ -487,17 +718,19 @@ Maximum size of data in data carrier transactions we relay and mine \fB\-minrelaytxfee=\fR .IP Fees (in BTC/kB) smaller than this are considered zero fee for relaying, -mining and transaction creation (default: 0.00001) +mining and transaction creation (default: 0.000001) .HP \fB\-whitelistforcerelay\fR .IP -Force relay of transactions from whitelisted peers even if they violate -local relay policy (default: 0) +Add 'forcerelay' permission to whitelisted inbound peers with default +permissions. This will relay transactions even if the +transactions were already in the mempool. (default: 0) .HP \fB\-whitelistrelay\fR .IP -Accept relayed transactions received from whitelisted peers even when -not relaying transactions (default: 1) +Add 'relay' permission to whitelisted inbound peers with default +permissions. This will accept relayed transactions even when not +relaying transactions (default: 1) .PP Block creation options: .HP @@ -508,7 +741,7 @@ Set maximum BIP141 block weight (default: 3996000) \fB\-blockmintxfee=\fR .IP Set lowest fee rate (in BTC/kB) for transactions to be included in block -creation. (default: 0.00001) +creation. (default: 0.000001) .PP RPC server options: .HP @@ -552,8 +785,8 @@ Password for JSON\-RPC connections .HP \fB\-rpcport=\fR .IP -Listen for JSON\-RPC connections on (default: 8332, testnet: -18332, regtest: 18443) +Listen for JSON\-RPC connections on (default: 7041, testnet: +18332, signet: 38332, regtest: 18443) .HP \fB\-rpcserialversion\fR .IP @@ -568,16 +801,169 @@ Set the number of threads to service RPC calls (default: 4) .IP Username for JSON\-RPC connections .HP +\fB\-rpcwhitelist=\fR +.IP +Set a whitelist to filter incoming RPC calls for a specific user. The +field comes in the format: :,,...,. If multiple whitelists are set for a given user, +they are set\-intersected. See \fB\-rpcwhitelistdefault\fR documentation +for information on default whitelist behavior. +.HP +\fB\-rpcwhitelistdefault\fR +.IP +Sets default behavior for rpc whitelisting. Unless rpcwhitelistdefault +is set to 0, if any \fB\-rpcwhitelist\fR is set, the rpc server acts as +if all rpc users are subject to empty\-unless\-otherwise\-specified +whitelists. If rpcwhitelistdefault is set to 1 and no +\fB\-rpcwhitelist\fR is set, rpc server acts as if all rpc users are +subject to empty whitelists. +.HP \fB\-server\fR .IP Accept command line and JSON\-RPC commands -.SH COPYRIGHT -Copyright (C) 2009-2019 The Bitcoin Core developers - -Please contribute if you find Bitcoin Core useful. Visit - for further information about the software. -The source code is available from . - -This is experimental software. -Distributed under the MIT software license, see the accompanying file COPYING -or +.PP +Elements Options: +.HP +\fB\-assetdir\fR +.IP +Entries of pet names of assets, in this format:asset=: