Skip to content

Commit b5a9625

Browse files
committed
tests: Use manual bumps instead of bumpfee for resendwallettransactions
Bumpfee will try to increase the entire package to the target feerate, which causes repeated bumpfees to quickly shoot up in fees, causing intermittent failures when the fee is too large. We don't care about this property, just that the child is continuously replaced until we observe it's position in mapWallet is before its parent. Instead of using bumpfee, we can create raw transactions which have only pay the additional incremental relay fee, thus avoiding this problem.
1 parent c9f2882 commit b5a9625

File tree

1 file changed

+23
-3
lines changed

1 file changed

+23
-3
lines changed

test/functional/wallet_resendwallettransactions.py

+23-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
"""Test that the wallet resends transactions periodically."""
66
import time
77

8+
from decimal import Decimal
9+
810
from test_framework.blocktools import (
911
create_block,
1012
create_coinbase,
@@ -15,6 +17,8 @@
1517
from test_framework.util import (
1618
assert_equal,
1719
assert_raises_rpc_error,
20+
get_fee,
21+
try_rpc,
1822
)
1923

2024
class ResendWalletTransactionsTest(BitcoinTestFramework):
@@ -86,18 +90,34 @@ def run_test(self):
8690
# ordering of mapWallet is, if the child is not before the parent, we will create a new
8791
# child (via bumpfee) and remove the old child (via removeprunedfunds) until we get the
8892
# ordering of child before parent.
89-
child_txid = node.send(outputs=[{addr: 0.5}], inputs=[{"txid":txid, "vout":0}])["txid"]
93+
child_inputs = [{"txid": txid, "vout": 0}]
94+
child_txid = node.sendall(recipients=[addr], inputs=child_inputs)["txid"]
95+
# Get the child tx's info for manual bumping
96+
child_tx_info = node.gettransaction(txid=child_txid, verbose=True)
97+
child_output_value = child_tx_info["decoded"]["vout"][0]["value"]
98+
# Include an additional 1 vbyte buffer to handle when we have a smaller signature
99+
additional_child_fee = get_fee(child_tx_info["decoded"]["vsize"] + 1, Decimal(0.00001100))
90100
while True:
91101
txids = node.listreceivedbyaddress(minconf=0, address_filter=addr)[0]["txids"]
92102
if txids == [child_txid, txid]:
93103
break
94-
bumped = node.bumpfee(child_txid)
104+
# Manually bump the tx
105+
# The inputs and the output address stay the same, just changing the amount for the new fee
106+
child_output_value -= additional_child_fee
107+
bumped_raw = node.createrawtransaction(inputs=child_inputs, outputs=[{addr: child_output_value}])
108+
bumped = node.signrawtransactionwithwallet(bumped_raw)
109+
bumped_txid = node.decoderawtransaction(bumped["hex"])["txid"]
110+
# Sometimes we will get a signature that is a little bit shorter than we expect which causes the
111+
# feerate to be a bit higher, then the followup to be a bit lower. This results in a replacement
112+
# that can't be broadcast. We can just skip that and keep grinding.
113+
if try_rpc(-26, "insufficient fee, rejecting replacement", node.sendrawtransaction, bumped["hex"]):
114+
continue
95115
# The scheduler queue creates a copy of the added tx after
96116
# send/bumpfee and re-adds it to the wallet (undoing the next
97117
# removeprunedfunds). So empty the scheduler queue:
98118
node.syncwithvalidationinterfacequeue()
99119
node.removeprunedfunds(child_txid)
100-
child_txid = bumped["txid"]
120+
child_txid = bumped_txid
101121
entry_time = node.getmempoolentry(child_txid)["time"]
102122

103123
block_time = entry_time + 6 * 60

0 commit comments

Comments
 (0)