|
5 | 5 | """Test that the wallet resends transactions periodically."""
|
6 | 6 | import time
|
7 | 7 |
|
| 8 | +from decimal import Decimal |
| 9 | + |
8 | 10 | from test_framework.blocktools import (
|
9 | 11 | create_block,
|
10 | 12 | create_coinbase,
|
|
15 | 17 | from test_framework.util import (
|
16 | 18 | assert_equal,
|
17 | 19 | assert_raises_rpc_error,
|
| 20 | + get_fee, |
| 21 | + try_rpc, |
18 | 22 | )
|
19 | 23 |
|
20 | 24 | class ResendWalletTransactionsTest(BitcoinTestFramework):
|
@@ -86,18 +90,34 @@ def run_test(self):
|
86 | 90 | # ordering of mapWallet is, if the child is not before the parent, we will create a new
|
87 | 91 | # child (via bumpfee) and remove the old child (via removeprunedfunds) until we get the
|
88 | 92 | # 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)) |
90 | 100 | while True:
|
91 | 101 | txids = node.listreceivedbyaddress(minconf=0, address_filter=addr)[0]["txids"]
|
92 | 102 | if txids == [child_txid, txid]:
|
93 | 103 | 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 |
95 | 115 | # The scheduler queue creates a copy of the added tx after
|
96 | 116 | # send/bumpfee and re-adds it to the wallet (undoing the next
|
97 | 117 | # removeprunedfunds). So empty the scheduler queue:
|
98 | 118 | node.syncwithvalidationinterfacequeue()
|
99 | 119 | node.removeprunedfunds(child_txid)
|
100 |
| - child_txid = bumped["txid"] |
| 120 | + child_txid = bumped_txid |
101 | 121 | entry_time = node.getmempoolentry(child_txid)["time"]
|
102 | 122 |
|
103 | 123 | block_time = entry_time + 6 * 60
|
|
0 commit comments