mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-31 10:41:08 +00:00
Merge bitcoin/bitcoin#33528: wallet: don't consider unconfirmed TRUC coins with ancestors
dcd42d6d8f160ae8bc12c152099a6e6473658e30 [test] wallet send 3 generation TRUC (glozow)
e753fadfd01cb8a4a8de3bddc7391481551cca89 [wallet] never try to spend from unconfirmed TRUC that already has ancestors (glozow)
Pull request description:
Addresses https://github.com/bitcoin/bitcoin/issues/33368#issuecomment-3319935660
There is not an explicit check that the to-be-created wallet transaction would be within the {TRUC, normal} ancestor limits. This means that the wallet may create a transaction that violates these limits, but fail to broadcast it in `CommitTransaction`.
This appears to be expected behavior for the normal ancestor limits (and any other situation in which the wallet creates a tx that was rejected by mempool) and AFAIK the transaction will be rebroadcast at some point after the ancestors confirm.
1ed00a0d39/test/functional/wallet_basic.py (L502-L506)
It's a bit complex to address this for the normal ancestor limit, and probably unrealistic for the wallet to check all possible mempool policies in coin selection, but it's quite trivial for TRUC: just skip any unconfirmed UTXOs that have any ancestors. I think it would be much more helpful to the user to say there are insufficient funds.
ACKs for top commit:
achow101:
ACK dcd42d6d8f160ae8bc12c152099a6e6473658e30
monlovesmango:
ACK dcd42d6d8f160ae8bc12c152099a6e6473658e30
rkrux:
lgtm ACK dcd42d6d8f160ae8bc12c152099a6e6473658e30
Tree-SHA512: b4cf9685bf0593c356dc0d6644835d53e3d7089f42b65f647795257dc7f5dac90c5ee493b41ee30a1c1beb880a859db8e049d3c64a43d5ca9b3e6482ff6bddd5
This commit is contained in:
commit
ad452a1e65
@ -403,6 +403,11 @@ CoinsResult AvailableCoins(const CWallet& wallet,
|
||||
if (wtx.tx->version != TRUC_VERSION) continue;
|
||||
// this unconfirmed v3 transaction already has a child
|
||||
if (wtx.truc_child_in_mempool.has_value()) continue;
|
||||
|
||||
// this unconfirmed v3 transaction has a parent: spending would create a third generation
|
||||
size_t ancestors, descendants;
|
||||
wallet.chain().getTransactionAncestry(wtx.tx->GetHash(), ancestors, descendants);
|
||||
if (ancestors > 1) continue;
|
||||
} else {
|
||||
if (wtx.tx->version == TRUC_VERSION) continue;
|
||||
Assume(!wtx.truc_child_in_mempool.has_value());
|
||||
|
||||
@ -119,6 +119,7 @@ class WalletV3Test(BitcoinTestFramework):
|
||||
self.sendall_truc_child_weight_limit()
|
||||
self.mix_non_truc_versions()
|
||||
self.cant_spend_multiple_unconfirmed_truc_outputs()
|
||||
self.test_spend_third_generation()
|
||||
|
||||
@cleanup
|
||||
def tx_spends_unconfirmed_tx_with_wrong_version(self, version_a, version_b):
|
||||
@ -585,5 +586,49 @@ class WalletV3Test(BitcoinTestFramework):
|
||||
{'include_unsafe' : True}
|
||||
)
|
||||
|
||||
@cleanup
|
||||
def test_spend_third_generation(self):
|
||||
self.log.info("Test that we can't spend an unconfirmed TRUC output that already has an unconfirmed parent")
|
||||
|
||||
# Generation 1: Consolidate all UTXOs into one output using sendall
|
||||
self.charlie.sendall([self.charlie.getnewaddress()], version=3)
|
||||
outputs1 = self.charlie.listunspent(minconf=0)
|
||||
assert_equal(len(outputs1), 1)
|
||||
|
||||
# Generation 2: to ensure no change address is created, do another sendall
|
||||
self.charlie.sendall([self.charlie.getnewaddress()], version=3)
|
||||
outputs2 = self.charlie.listunspent(minconf=0)
|
||||
assert_equal(len(outputs2), 1)
|
||||
total_amount = sum([utxo['amount'] for utxo in outputs2])
|
||||
|
||||
# Generation 3: try to send half of total amount to Alice
|
||||
outputs = {self.alice.getnewaddress(): total_amount / 2}
|
||||
assert_raises_rpc_error(
|
||||
-4,
|
||||
"Insufficient funds",
|
||||
self.charlie.send,
|
||||
outputs,
|
||||
version=3
|
||||
)
|
||||
|
||||
# Also doesn't work with fundrawtransaction
|
||||
raw_tx = self.charlie.createrawtransaction(inputs=[], outputs=outputs, version=3)
|
||||
assert_raises_rpc_error(
|
||||
-4,
|
||||
"Insufficient funds",
|
||||
self.charlie.fundrawtransaction,
|
||||
raw_tx,
|
||||
{'include_unsafe' : True}
|
||||
)
|
||||
|
||||
# Also doesn't work with sendall
|
||||
assert_raises_rpc_error(
|
||||
-6,
|
||||
"Total value of UTXO pool too low to pay for transaction",
|
||||
self.charlie.sendall,
|
||||
[self.alice.getnewaddress()],
|
||||
version=3
|
||||
)
|
||||
|
||||
if __name__ == '__main__':
|
||||
WalletV3Test(__file__).main()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user