|
26 | 26 | assert_equal,
|
27 | 27 | assert_greater_than,
|
28 | 28 | assert_raises_rpc_error,
|
| 29 | + get_fee, |
29 | 30 | )
|
30 | 31 | from test_framework.wallet import MiniWallet
|
31 | 32 |
|
@@ -100,6 +101,7 @@ def run_test(self):
|
100 | 101 | test_change_script_match(self, rbf_node, dest_address)
|
101 | 102 | test_settxfee(self, rbf_node, dest_address)
|
102 | 103 | test_maxtxfee_fails(self, rbf_node, dest_address)
|
| 104 | + test_feerate_checks_replaced_outputs(self, rbf_node) |
103 | 105 | # These tests wipe out a number of utxos that are expected in other tests
|
104 | 106 | test_small_output_with_feerate_succeeds(self, rbf_node, dest_address)
|
105 | 107 | test_no_more_inputs_fails(self, rbf_node, dest_address)
|
@@ -668,5 +670,30 @@ def test_no_more_inputs_fails(self, rbf_node, dest_address):
|
668 | 670 | self.clear_mempool()
|
669 | 671 |
|
670 | 672 |
|
| 673 | +def test_feerate_checks_replaced_outputs(self, rbf_node): |
| 674 | + self.log.info("Test that feerate checks use replaced outputs") |
| 675 | + outputs = [] |
| 676 | + for i in range(50): |
| 677 | + outputs.append({rbf_node.getnewaddress(address_type="bech32"): 1}) |
| 678 | + tx_res = rbf_node.send(outputs=outputs, fee_rate=5) |
| 679 | + tx_details = rbf_node.gettransaction(txid=tx_res["txid"], verbose=True) |
| 680 | + |
| 681 | + # Calculate the minimum feerate required for the bump to work. |
| 682 | + # Since the bumped tx will replace all of the outputs with a single output, we can estimate that its size will 31 * (len(outputs) - 1) bytes smaller |
| 683 | + tx_size = tx_details["decoded"]["vsize"] |
| 684 | + est_bumped_size = tx_size - (len(tx_details["decoded"]["vout"]) - 1) * 31 |
| 685 | + inc_fee_rate = max(rbf_node.getmempoolinfo()["incrementalrelayfee"], Decimal(0.00005000)) # Wallet has a fixed incremental relay fee of 5 sat/vb |
| 686 | + # RPC gives us fee as negative |
| 687 | + min_fee = (-tx_details["fee"] + get_fee(est_bumped_size, inc_fee_rate)) * Decimal(1e8) |
| 688 | + min_fee_rate = (min_fee / est_bumped_size).quantize(Decimal("1.000")) |
| 689 | + |
| 690 | + # Attempt to bumpfee and replace all outputs with a single one using a feerate slightly less than the minimum |
| 691 | + new_outputs = [{rbf_node.getnewaddress(address_type="bech32"): 49}] |
| 692 | + assert_raises_rpc_error(-8, "Insufficient total fee", rbf_node.bumpfee, tx_res["txid"], {"fee_rate": min_fee_rate - 1, "outputs": new_outputs}) |
| 693 | + |
| 694 | + # Bumpfee and replace all outputs with a single one using the minimum feerate |
| 695 | + rbf_node.bumpfee(tx_res["txid"], {"fee_rate": min_fee_rate, "outputs": new_outputs}) |
| 696 | + |
| 697 | + |
671 | 698 | if __name__ == "__main__":
|
672 | 699 | BumpFeeTest().main()
|
0 commit comments