mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-07-28 14:02:53 +02:00
Merge bitcoin/bitcoin#26661: wallet: Coin Selection, return accurate error messages
76dc547ee7
gui: create tx, launch error dialog if backend throws runtime_error (furszy)f4d79477ff
wallet: coin selection, add duplicated inputs checks (furszy)0aa065b14e
wallet: return accurate error messages from Coin Selection (furszy)7e8340ab1a
wallet: make SelectCoins flow return util::Result (furszy)e5e147fe97
wallet: refactor eight consecutive 'AttemptSelection' calls into a loop (furszy) Pull request description: Work decoupled from #25806, which cleanup and improves the Coin Selection flow further. Adding the capability to propagate specific error messages from the Coin Selection process to the user. Instead of always returning the general "Insufficient funds" message which is not always accurate to what happened internally. Letting us instruct the user how to proceed under certain circumstances. The following error messages were added: 1) If the selection result exceeds the maximum transaction weight, we now will return: -> "The inputs size exceeds the maximum weight. Please try sending a smaller amount or manually consolidating your wallet's UTXOs". 2) If the user pre-selected inputs and disallowed the automatic coin selection process (no other inputs are allowed), we now will return: -> "The preselected coins total amount does not cover the transaction target. Please allow other inputs to be automatically selected or include more coins manually". 3) The double-counted preset inputs during Coin Selection error will now throw an "internal bug detected" message instead of crashing the node. The essence of this work comes from several comments: 1. https://github.com/bitcoin/bitcoin/pull/26560#discussion_r1037395665 2. https://github.com/bitcoin/bitcoin/pull/25729#discussion_r940619491 3. https://github.com/bitcoin/bitcoin/pull/25269#pullrequestreview-1135240825 4. https://github.com/bitcoin/bitcoin/issues/23144 (which is connected to #24845) ACKs for top commit: ishaanam: crACK76dc547ee7
achow101: ACK76dc547ee7
aureleoules: ACK76dc547ee7
theStack: ACK76dc547ee7
🌇 Tree-SHA512: 9de30792d7a5849cae77747aa978e70390b66ee9d082779a56088a024f82e725b0af050e6603aece0ac8229f6d73bc471ba97b4ab69dc7eddf419f5f56ae89a5
This commit is contained in:
@@ -27,6 +27,8 @@ from test_framework.util import (
|
||||
)
|
||||
from test_framework.wallet_util import bytes_to_wif
|
||||
|
||||
ERR_NOT_ENOUGH_PRESET_INPUTS = "The preselected coins total amount does not cover the transaction target. " \
|
||||
"Please allow other inputs to be automatically selected or include more coins manually"
|
||||
|
||||
def get_unspent(listunspent, amount):
|
||||
for utx in listunspent:
|
||||
@@ -328,7 +330,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
assert_equal("00", dec_tx['vin'][0]['scriptSig']['hex'])
|
||||
|
||||
# Should fail without add_inputs:
|
||||
assert_raises_rpc_error(-4, "Insufficient funds", self.nodes[2].fundrawtransaction, rawtx, {"add_inputs": False})
|
||||
assert_raises_rpc_error(-4, ERR_NOT_ENOUGH_PRESET_INPUTS, self.nodes[2].fundrawtransaction, rawtx, {"add_inputs": False})
|
||||
# add_inputs is enabled by default
|
||||
rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
|
||||
|
||||
@@ -360,7 +362,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
|
||||
|
||||
# Should fail without add_inputs:
|
||||
assert_raises_rpc_error(-4, "Insufficient funds", self.nodes[2].fundrawtransaction, rawtx, {"add_inputs": False})
|
||||
assert_raises_rpc_error(-4, ERR_NOT_ENOUGH_PRESET_INPUTS, self.nodes[2].fundrawtransaction, rawtx, {"add_inputs": False})
|
||||
rawtxfund = self.nodes[2].fundrawtransaction(rawtx, {"add_inputs": True})
|
||||
|
||||
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
|
||||
@@ -394,7 +396,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
|
||||
|
||||
# Should fail without add_inputs:
|
||||
assert_raises_rpc_error(-4, "Insufficient funds", self.nodes[2].fundrawtransaction, rawtx, {"add_inputs": False})
|
||||
assert_raises_rpc_error(-4, ERR_NOT_ENOUGH_PRESET_INPUTS, self.nodes[2].fundrawtransaction, rawtx, {"add_inputs": False})
|
||||
rawtxfund = self.nodes[2].fundrawtransaction(rawtx, {"add_inputs": True})
|
||||
|
||||
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
|
||||
@@ -989,7 +991,9 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
outputs[recipient.getnewaddress()] = 0.1
|
||||
wallet.sendmany("", outputs)
|
||||
self.generate(self.nodes[0], 10)
|
||||
assert_raises_rpc_error(-4, "Insufficient funds", recipient.fundrawtransaction, rawtx)
|
||||
assert_raises_rpc_error(-4, "The inputs size exceeds the maximum weight. "
|
||||
"Please try sending a smaller amount or manually consolidating your wallet's UTXOs",
|
||||
recipient.fundrawtransaction, rawtx)
|
||||
self.nodes[0].unloadwallet("large")
|
||||
|
||||
def test_external_inputs(self):
|
||||
@@ -1130,7 +1134,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
}
|
||||
]
|
||||
}
|
||||
assert_raises_rpc_error(-4, "Insufficient funds", wallet.send, outputs=[{addr1: 8}], options=options)
|
||||
assert_raises_rpc_error(-4, ERR_NOT_ENOUGH_PRESET_INPUTS, wallet.send, outputs=[{addr1: 8}], options=options)
|
||||
|
||||
# Case (3), Explicit add_inputs=true and preset inputs (with preset inputs not-covering the target amount)
|
||||
options["add_inputs"] = True
|
||||
@@ -1158,7 +1162,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
|
||||
# 6. Explicit add_inputs=false, no preset inputs:
|
||||
options = {"add_inputs": False}
|
||||
assert_raises_rpc_error(-4, "Insufficient funds", wallet.send, outputs=[{addr1: 3}], options=options)
|
||||
assert_raises_rpc_error(-4, ERR_NOT_ENOUGH_PRESET_INPUTS, wallet.send, outputs=[{addr1: 3}], options=options)
|
||||
|
||||
################################################
|
||||
|
||||
@@ -1175,7 +1179,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
"vout": 1 # change position was hardcoded to index 0
|
||||
}]
|
||||
outputs = {self.nodes[1].getnewaddress(): 8}
|
||||
assert_raises_rpc_error(-4, "Insufficient funds", wallet.walletcreatefundedpsbt, inputs=inputs, outputs=outputs)
|
||||
assert_raises_rpc_error(-4, ERR_NOT_ENOUGH_PRESET_INPUTS, wallet.walletcreatefundedpsbt, inputs=inputs, outputs=outputs)
|
||||
|
||||
# Case (3), Explicit add_inputs=true and preset inputs (with preset inputs not-covering the target amount)
|
||||
options["add_inputs"] = True
|
||||
@@ -1202,7 +1206,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
|
||||
# Case (6). Explicit add_inputs=false, no preset inputs:
|
||||
options = {"add_inputs": False}
|
||||
assert_raises_rpc_error(-4, "Insufficient funds", wallet.walletcreatefundedpsbt, inputs=[], outputs=outputs, options=options)
|
||||
assert_raises_rpc_error(-4, ERR_NOT_ENOUGH_PRESET_INPUTS, wallet.walletcreatefundedpsbt, inputs=[], outputs=outputs, options=options)
|
||||
|
||||
self.nodes[2].unloadwallet("test_preset_inputs")
|
||||
|
||||
|
Reference in New Issue
Block a user