mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-03-12 10:30:08 +01:00
wallet: introduce "tx amount exceeds balance when fees are included" error
This was previously implemented at the GUI level but has been broken since #20640
This commit is contained in:
parent
a786fd2041
commit
900e5ed51b
2 changed files with 31 additions and 2 deletions
|
@ -1131,7 +1131,19 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
|
||||||
if (!select_coins_res) {
|
if (!select_coins_res) {
|
||||||
// 'SelectCoins' either returns a specific error message or, if empty, means a general "Insufficient funds".
|
// 'SelectCoins' either returns a specific error message or, if empty, means a general "Insufficient funds".
|
||||||
const bilingual_str& err = util::ErrorString(select_coins_res);
|
const bilingual_str& err = util::ErrorString(select_coins_res);
|
||||||
return util::Error{err.empty() ?_("Insufficient funds") : err};
|
if (!err.empty()) return util::Error{err};
|
||||||
|
|
||||||
|
// Check if we have enough balance but cannot cover the fees
|
||||||
|
CAmount available_balance = preset_inputs.total_amount + available_coins.GetTotalAmount();
|
||||||
|
if (available_balance >= recipients_sum) {
|
||||||
|
CAmount available_effective_balance = preset_inputs.total_amount + available_coins.GetEffectiveTotalAmount().value_or(available_coins.GetTotalAmount());
|
||||||
|
if (available_effective_balance < selection_target) {
|
||||||
|
return util::Error{_("The total transaction amount exceeds your balance when fees are included")};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// General failure description
|
||||||
|
return util::Error{_("Insufficient funds")};
|
||||||
}
|
}
|
||||||
const SelectionResult& result = *select_coins_res;
|
const SelectionResult& result = *select_coins_res;
|
||||||
TRACE5(coin_selection, selected_coins,
|
TRACE5(coin_selection, selected_coins,
|
||||||
|
|
|
@ -150,6 +150,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||||
self.test_feerate_rounding()
|
self.test_feerate_rounding()
|
||||||
self.test_input_confs_control()
|
self.test_input_confs_control()
|
||||||
self.test_duplicate_outputs()
|
self.test_duplicate_outputs()
|
||||||
|
self.test_cannot_cover_fees()
|
||||||
|
|
||||||
def test_duplicate_outputs(self):
|
def test_duplicate_outputs(self):
|
||||||
self.log.info("Test deserializing and funding a transaction with duplicate outputs")
|
self.log.info("Test deserializing and funding a transaction with duplicate outputs")
|
||||||
|
@ -1426,7 +1427,8 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||||
# To test this does not happen, we subtract 202 sats from the input value. If working correctly, this should
|
# To test this does not happen, we subtract 202 sats from the input value. If working correctly, this should
|
||||||
# fail with insufficient funds rather than bitcoind asserting.
|
# fail with insufficient funds rather than bitcoind asserting.
|
||||||
rawtx = w.createrawtransaction(inputs=[], outputs=[{self.nodes[0].getnewaddress(address_type="bech32"): 1 - 0.00000202}])
|
rawtx = w.createrawtransaction(inputs=[], outputs=[{self.nodes[0].getnewaddress(address_type="bech32"): 1 - 0.00000202}])
|
||||||
assert_raises_rpc_error(-4, "Insufficient funds", w.fundrawtransaction, rawtx, fee_rate=1.85)
|
expected_err_msg = "The total transaction amount exceeds your balance when fees are included"
|
||||||
|
assert_raises_rpc_error(-4, expected_err_msg, w.fundrawtransaction, rawtx, fee_rate=1.85)
|
||||||
|
|
||||||
def test_input_confs_control(self):
|
def test_input_confs_control(self):
|
||||||
self.nodes[0].createwallet("minconf")
|
self.nodes[0].createwallet("minconf")
|
||||||
|
@ -1489,5 +1491,20 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||||
|
|
||||||
wallet.unloadwallet()
|
wallet.unloadwallet()
|
||||||
|
|
||||||
|
def test_cannot_cover_fees(self):
|
||||||
|
self.log.info("Test tx amount exceeds available balance when fees are included")
|
||||||
|
|
||||||
|
self.nodes[1].createwallet("cannot_cover_fees")
|
||||||
|
wallet = self.nodes[1].get_wallet_rpc("cannot_cover_fees")
|
||||||
|
|
||||||
|
self.nodes[0].sendtoaddress(wallet.getnewaddress(), 0.3)
|
||||||
|
self.generate(self.nodes[0], 1)
|
||||||
|
|
||||||
|
rawtx = wallet.createrawtransaction(inputs=[], outputs=[{self.nodes[0].getnewaddress(): 0.3}])
|
||||||
|
expected_err_msg = "The total transaction amount exceeds your balance when fees are included"
|
||||||
|
assert_raises_rpc_error(-4, expected_err_msg, wallet.fundrawtransaction, rawtx)
|
||||||
|
wallet.unloadwallet()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
RawTransactionsTest().main()
|
RawTransactionsTest().main()
|
||||||
|
|
Loading…
Add table
Reference in a new issue