Backports:
And final changes for 29.3rc1
Github-Pull: #33475
Rebased-From: b807dfcdc5929c314d43b790c9e705d5bf0a86e8
Github-Pull: #33723
Rebased-From: b0c706795ce6a3a00bf068a81ee99fef2ee9bf7e
Github-Pull: #34227
Rebased-From: 194114daf385a5db50e1507fda79a1a93240d494
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/34268.
See the guideline for information on the review process.
If your review is incorrectly listed, please copy-paste <!–meta-tag:bot-skip–> into the comment that the bot should ignore.
1707+ for (const CTxIn& txin : tx.vin) {
1708+ const CWalletTx* prev = GetWalletTx(txin.prevout.hash);
1709+ if (prev && txin.prevout.n < prev->tx->vout.size() && IsMine(prev->tx->vout[txin.prevout.n])) {
1710+ return true;
1711+ }
1712+ }
Simpler to use IsMine here, but this is also acceptable. It’s basically the same process.
0 for (const CTxIn& txin : tx.vin) {
1 if (IsMine(txin.prevout)) {
2 return true;
3 }
4 }
79@@ -51,8 +80,17 @@ Credits
80
81 Thanks to everyone who directly contributed to this release:
82
83+- Anthony Towns
SatsAndSports missing here (#33723).
118@@ -114,6 +119,9 @@ def run_test(self):
119 self.run_invalid_parameters_test()
120 self.test_op_return()
121
122+ if self.options.descriptors:
123+ self.test_from_me_status_change()
In f70a3dded750b30d66f98126c12dff1fd96b5799 “test: Test wallet ‘from me’ status change”
Instead of disabling this test for legacy wallets, the following diff can adapt it to be usable for both wallet types:
0diff --git a/test/functional/wallet_listtransactions.py b/test/functional/wallet_listtransactions.py
1index 5c2cfbf85d1..6a76bcc5e7c 100755
2--- a/test/functional/wallet_listtransactions.py
3+++ b/test/functional/wallet_listtransactions.py
4@@ -119,8 +119,7 @@ class ListTransactionsTest(BitcoinTestFramework):
5 self.run_invalid_parameters_test()
6 self.test_op_return()
7
8- if self.options.descriptors:
9- self.test_from_me_status_change()
10+ self.test_from_me_status_change()
11
12 def run_rbf_opt_in_test(self):
13 """Test the opt-in-rbf flag for sent and received transactions."""
14@@ -345,8 +344,7 @@ class ListTransactionsTest(BitcoinTestFramework):
15 # Run twice, once for a transaction in the mempool, again when it confirms
16 for confirm in [False, True]:
17 key = get_generate_key()
18- descriptor = descsum_create(f"wpkh({key.privkey})")
19- default_wallet.importdescriptors([{"desc": descriptor, "timestamp": "now"}])
20+ default_wallet.importprivkey(key.privkey)
21
22 send_res = default_wallet.send(outputs=[{key.p2wpkh_addr: 1}, {wallet.getnewaddress(): 1}])
23 assert_equal(send_res["complete"], True)
24@@ -370,8 +368,7 @@ class ListTransactionsTest(BitcoinTestFramework):
25 self.nodes[0].setmocktime(int(time.time()) + MAX_FUTURE_BLOCK_TIME + 1)
26 self.generate(self.nodes[0], 10, sync_fun=self.no_op)
27
28- import_res = wallet.importdescriptors([{"desc": descriptor, "timestamp": "now"}])
29- assert_equal(import_res[0]["success"], True)
30+ wallet.importprivkey(key.privkey)
31 # TODO: We should check that the fee matches, but since the transaction spends inputs
32 # not known to the wallet, it is incorrectly calculating the fee.
33 # assert_equal(wallet.gettransaction(txid)["fee"], fee)
63+ self.nodes[0].createwallet(wallet_name="anchor", disable_private_keys=True)
64+ wallet = self.nodes[0].get_wallet_rpc("anchor")
65+
66+ if self.options.descriptors:
67+ import_res = wallet.importdescriptors([{"desc": descsum_create(f"addr({ANCHOR_ADDRESS})"), "timestamp": "now"}])
68+ assert_equal(import_res[0]["success"], True)
In b605cc8c73a10162f47e0aeb361144e4913a2a54 “test: Add a test for anchor outputs in the wallet”
Using wallet.importaddress(ANCHOR_ADDRESS, rescan=False) instead of importdescriptors here allows this test case to work for both descriptors and legacy wallets.
116+
117+ def run_test(self):
118+ self.default_wallet = self.nodes[0].get_wallet_rpc(self.default_wallet_name)
119+ self.test_0_value_anchor_listunspent()
120+ if self.options.descriptors:
121+ self.test_cannot_sign_anchors()
In b605cc8c73a10162f47e0aeb361144e4913a2a54 “test: Add a test for anchor outputs in the wallet”
The following diff allows this test to work for both descriptors and legacy wallets
0diff --git a/test/functional/wallet_anchor.py b/test/functional/wallet_anchor.py
1index 49ec75928c0..0b08986d00d 100755
2--- a/test/functional/wallet_anchor.py
3+++ b/test/functional/wallet_anchor.py
4@@ -92,12 +92,15 @@ class WalletAnchorTest(BitcoinTestFramework):
5 for disable_privkeys in [False, True]:
6 self.nodes[0].createwallet(wallet_name=f"anchor_spend_{disable_privkeys}", disable_private_keys=disable_privkeys)
7 wallet = self.nodes[0].get_wallet_rpc(f"anchor_spend_{disable_privkeys}")
8- import_res = wallet.importdescriptors([
9- {"desc": descsum_create(f"addr({ANCHOR_ADDRESS})"), "timestamp": "now"},
10- {"desc": descsum_create(f"raw({PAY_TO_ANCHOR.hex()})"), "timestamp": "now"}
11- ])
12- assert_equal(import_res[0]["success"], disable_privkeys)
13- assert_equal(import_res[1]["success"], disable_privkeys)
14+ if self.options.descriptors:
15+ import_res = wallet.importdescriptors([
16+ {"desc": descsum_create(f"addr({ANCHOR_ADDRESS})"), "timestamp": "now"},
17+ {"desc": descsum_create(f"raw({PAY_TO_ANCHOR.hex()})"), "timestamp": "now"}
18+ ])
19+ assert_equal(import_res[0]["success"], disable_privkeys)
20+ assert_equal(import_res[1]["success"], disable_privkeys)
21+ else:
22+ wallet.importaddress(ANCHOR_ADDRESS)
23
24 anchor_txid = self.default_wallet.sendtoaddress(ANCHOR_ADDRESS, 1)
25 self.generate(self.nodes[0], 1)
26@@ -109,16 +112,19 @@ class WalletAnchorTest(BitcoinTestFramework):
27 assert_equal(utxos[0]["address"], ANCHOR_ADDRESS)
28 assert_equal(utxos[0]["amount"], 1)
29
30- assert_raises_rpc_error(-4, "Missing solving data for estimating transaction size", wallet.send, [{self.default_wallet.getnewaddress(): 0.9999}])
31+ if self.options.descriptors:
32+ assert_raises_rpc_error(-4, "Missing solving data for estimating transaction size", wallet.send, [{self.default_wallet.getnewaddress(): 0.9999}])
33+ assert_raises_rpc_error(-4, "Unable to determine the size of the transaction, the wallet contains unsolvable descriptors", wallet.sendall, recipients=[self.default_wallet.getnewaddress()])
34+ else:
35+ assert_raises_rpc_error(-4, "Insufficient funds", wallet.send, [{self.default_wallet.getnewaddress(): 0.9999}])
36+ assert_raises_rpc_error(-6, "Total value of UTXO pool too low to pay for transaction. Try using lower feerate or excluding uneconomic UTXOs with 'send_max' option.", wallet.sendall, recipients=[self.default_wallet.getnewaddress()])
37 assert_raises_rpc_error(-4, "Error: Private keys are disabled for this wallet", wallet.sendtoaddress, self.default_wallet.getnewaddress(), 0.9999)
38 assert_raises_rpc_error(-4, "Unable to determine the size of the transaction, the wallet contains unsolvable descriptors", wallet.sendall, recipients=[self.default_wallet.getnewaddress()], inputs=utxos)
39- assert_raises_rpc_error(-4, "Unable to determine the size of the transaction, the wallet contains unsolvable descriptors", wallet.sendall, recipients=[self.default_wallet.getnewaddress()])
40
41 def run_test(self):
42 self.default_wallet = self.nodes[0].get_wallet_rpc(self.default_wallet_name)
43 self.test_0_value_anchor_listunspent()
44- if self.options.descriptors:
45- self.test_cannot_sign_anchors()
46+ self.test_cannot_sign_anchors()
47
48 if __name__ == '__main__':
49 WalletAnchorTest(__file__).main()
If something is imported into the wallet, it can change the 'from me'
status of a transaction. This status is only visible through
gettransaction's "fee" field which is only shown for transactions that
are 'from me'.
Github-Pull: #33268
Rebased-From: e76c2f7a4111f87080e31539f83c21390fcd8f3b
Instead of checking whether the total amount of inputs known by the
wallet is greater than 0, we should be checking for whether the input is
known by the wallet. This enables us to determine whether a transaction
spends an of output with an amount of 0, which is necessary for marking
0-value dust outputs as spent.
Github-Pull: #33268
Rebased-From: 39a7dbdd277d1dea9a70314d8cc5ae057999ee88
Github-Pull: #33268
Rebased-From: c40dc822d74aea46e4a21774ca282e008f609c2a
Github-Pull: #33268
Rebased-From: 609d265ebc51abfe9a9ce570da647b6839dc1214
ACK b834447fb2f2073e25164a80ba197a3120610b92
Listed backported pr files are all there except for https://github.com/bitcoin/bitcoin/commit/113a4228229baedda2a730e097f2d59ad58a4b0d as stated and miner.cpp slightly deviates from the PR because of rebase with old code. Version is correctly bumped.
(Sorry the diff from the release-notes.mo threw me off, showing most was new)
ACK b834447fb2f2073e25164a80ba197a3120610b92
Reproduced locally too