Merge bitcoin/bitcoin#28979: wallet, rpc: document and update sendall behavior around unconfirmed inputs

71aae72e1f test: test sendall does ancestor aware funding (ishaanam)
36757941a0 wallet, rpc: implement ancestor aware funding for sendall (ishaanam)
544131f3fb rpc, test: test sendall spends unconfirmed change and unconfirmed inputs when specified (ishaanam)

Pull request description:

  This PR:
  - Adds a functional test that `sendall` spends unconfirmed change
  - Adds a functional test that `sendall` spends regular unconfirmed inputs when specified by user
  - Adds ancestor aware funding to `sendall` by using `calculateCombinedBumpFee` and adjusting the effective value accordingly
  - Adds a functional test for ancestor aware funding in `sendall`

ACKs for top commit:
  S3RK:
    ACK 71aae72e1f
  achow101:
    ACK 71aae72e1f
  furszy:
    ACK 71aae72e1f

Tree-SHA512: acaeb7c65166ce53123a1d6cb5012197202246acc02ef9f37a28154cc93afdbd77c25e840ab79bdc7e0b88904014a43ab1ddea79d5337dc310ea210634ab61f0
This commit is contained in:
Ava Chow
2024-06-04 18:46:47 -04:00
2 changed files with 77 additions and 2 deletions

View File

@@ -379,6 +379,64 @@ class SendallTest(BitcoinTestFramework):
assert_equal(len(self.wallet.listunspent()), 1)
assert_equal(self.wallet.listunspent()[0]['confirmations'], 6)
@cleanup
def sendall_spends_unconfirmed_change(self):
self.log.info("Test that sendall spends unconfirmed change")
self.add_utxos([17])
self.wallet.sendtoaddress(self.remainder_target, 10)
assert_greater_than(self.wallet.getbalances()["mine"]["trusted"], 6)
self.test_sendall_success(sendall_args = [self.remainder_target])
assert_equal(self.wallet.getbalance(), 0)
@cleanup
def sendall_spends_unconfirmed_inputs_if_specified(self):
self.log.info("Test that sendall spends specified unconfirmed inputs")
self.def_wallet.sendtoaddress(self.wallet.getnewaddress(), 17)
self.wallet.syncwithvalidationinterfacequeue()
assert_equal(self.wallet.getbalances()["mine"]["untrusted_pending"], 17)
unspent = self.wallet.listunspent(minconf=0)[0]
self.wallet.sendall(recipients=[self.remainder_target], inputs=[unspent])
assert_equal(self.wallet.getbalance(), 0)
@cleanup
def sendall_does_ancestor_aware_funding(self):
self.log.info("Test that sendall does ancestor aware funding for unconfirmed inputs")
# higher parent feerate
self.def_wallet.sendtoaddress(address=self.wallet.getnewaddress(), amount=17, fee_rate=20)
self.wallet.syncwithvalidationinterfacequeue()
assert_equal(self.wallet.getbalances()["mine"]["untrusted_pending"], 17)
unspent = self.wallet.listunspent(minconf=0)[0]
parent_txid = unspent["txid"]
assert_equal(self.wallet.gettransaction(parent_txid)["confirmations"], 0)
res_1 = self.wallet.sendall(recipients=[self.def_wallet.getnewaddress()], inputs=[unspent], fee_rate=20, add_to_wallet=False, lock_unspents=True)
child_hex = res_1["hex"]
child_tx = self.wallet.decoderawtransaction(child_hex)
higher_parent_feerate_amount = child_tx["vout"][0]["value"]
# lower parent feerate
self.def_wallet.sendtoaddress(address=self.wallet.getnewaddress(), amount=17, fee_rate=10)
self.wallet.syncwithvalidationinterfacequeue()
assert_equal(self.wallet.getbalances()["mine"]["untrusted_pending"], 34)
unspent = self.wallet.listunspent(minconf=0)[0]
parent_txid = unspent["txid"]
assert_equal(self.wallet.gettransaction(parent_txid)["confirmations"], 0)
res_2 = self.wallet.sendall(recipients=[self.def_wallet.getnewaddress()], inputs=[unspent], fee_rate=20, add_to_wallet=False, lock_unspents=True)
child_hex = res_2["hex"]
child_tx = self.wallet.decoderawtransaction(child_hex)
lower_parent_feerate_amount = child_tx["vout"][0]["value"]
assert_greater_than(higher_parent_feerate_amount, lower_parent_feerate_amount)
# This tests needs to be the last one otherwise @cleanup will fail with "Transaction too large" error
def sendall_fails_with_transaction_too_large(self):
self.log.info("Test that sendall fails if resulting transaction is too large")
@@ -460,6 +518,15 @@ class SendallTest(BitcoinTestFramework):
# Sendall only uses outputs with less than a given number of confirmation when using minconf
self.sendall_with_maxconf()
# Sendall spends unconfirmed change
self.sendall_spends_unconfirmed_change()
# Sendall spends unconfirmed inputs if they are specified
self.sendall_spends_unconfirmed_inputs_if_specified()
# Sendall does ancestor aware funding when spending an unconfirmed UTXO
self.sendall_does_ancestor_aware_funding()
# Sendall fails when many inputs result to too large transaction
self.sendall_fails_with_transaction_too_large()