Skip to content

Commit 6ff2d42

Browse files
committed
Merge bitcoin/bitcoin#33189: rpc: followups for 33106
daa40a3 doc fixups for 33106 (glozow) c568511 test fixup for incremental feerate (glozow) 636fa21 test fixups (glozow) 9169a50 [rpc] expose blockmintxfee via getmininginfo (glozow) Pull request description: Followups from #33106: - bitcoin/bitcoin#33106 (comment) - bitcoin/bitcoin#33106 (comment) - bitcoin/bitcoin#33106 (comment) - bitcoin/bitcoin#33106 (comment) - bitcoin/bitcoin#33106 (comment) - bitcoin/bitcoin#33106 (comment) - bitcoin/bitcoin#33106 (comment) - bitcoin/bitcoin#33106 (comment) - bitcoin/bitcoin#33106 (comment) - bitcoin/bitcoin#33106 (comment) - bitcoin/bitcoin#33106 (comment) ACKs for top commit: ajtowns: ACK daa40a3 ; cursory review, seems reasonable davidgumberg: ACK bitcoin/bitcoin@daa40a3 instagibbs: ACK daa40a3 Tree-SHA512: d6f0ae5d00dadfbaf0998ac332c8536c997628de4f2b9947eb57712f05d3afa19a823c9cc007435be320640cd13a4c500db20c9606988cdd371934496dec009d
2 parents 4d54bb2 + daa40a3 commit 6ff2d42

File tree

8 files changed

+37
-24
lines changed

8 files changed

+37
-24
lines changed

doc/release-notes-33106.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ changed to 100 satoshis per kvB. They can still be changed using their respectiv
99
recommended to change both together if you decide to do so.
1010

1111
Other minimum feerates (e.g. the dust feerate, the minimum returned by the fee estimator, and all feerates used by the
12-
wallet) remain unchanged. The mempool minimum feerate still changes in response to high volume but more gradually, as a
13-
result of the change to the incremental relay feerate.
12+
wallet) remain unchanged. The mempool minimum feerate still changes in response to high volume.
1413

1514
Note that unless these lower defaults are widely adopted across the network, transactions created with lower fee rates
1615
are not guaranteed to propagate or confirm. The wallet feerates remain unchanged; `-mintxfee` must be changed before

src/rpc/mining.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ static RPCHelpMan getmininginfo()
429429
{RPCResult::Type::STR_HEX, "target", "The current target"},
430430
{RPCResult::Type::NUM, "networkhashps", "The network hashes per second"},
431431
{RPCResult::Type::NUM, "pooledtx", "The size of the mempool"},
432+
{RPCResult::Type::STR_AMOUNT, "blockmintxfee", "Minimum feerate of packages selected for block inclusion in " + CURRENCY_UNIT + "/kvB"},
432433
{RPCResult::Type::STR, "chain", "current network name (" LIST_CHAIN_NAMES ")"},
433434
{RPCResult::Type::STR_HEX, "signet_challenge", /*optional=*/true, "The block challenge (aka. block script), in hexadecimal (only present if the current network is a signet)"},
434435
{RPCResult::Type::OBJ, "next", "The next block",
@@ -469,6 +470,9 @@ static RPCHelpMan getmininginfo()
469470
obj.pushKV("target", GetTarget(tip, chainman.GetConsensus().powLimit).GetHex());
470471
obj.pushKV("networkhashps", getnetworkhashps().HandleRequest(request));
471472
obj.pushKV("pooledtx", (uint64_t)mempool.size());
473+
BlockAssembler::Options assembler_options;
474+
ApplyArgsManOptions(*node.args, assembler_options);
475+
obj.pushKV("blockmintxfee", ValueFromAmount(assembler_options.blockMinFeeRate.GetFeePerK()));
472476
obj.pushKV("chain", chainman.GetParams().GetChainTypeString());
473477

474478
UniValue next(UniValue::VOBJ);

src/test/miner_tests.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,8 @@ void MinerTestingSetup::TestPackageSelection(const CScript& scriptPubKey, const
218218
tx.vout[0].nValue = 5000000000LL - 100000000;
219219
tx.vout[1].nValue = 100000000; // 1BTC output
220220
// Increase size to avoid rounding errors: when the feerate is extremely small (i.e. 1sat/kvB), evaluating the fee
221-
// at a smaller transaction size gives us a rounded value of 0.
221+
// at smaller sizes gives us rounded values that are equal to each other, which means we incorrectly include
222+
// hashFreeTx2 + hashLowFeeTx2.
222223
BulkTransaction(tx, 4000);
223224
Txid hashFreeTx2 = tx.GetHash();
224225
AddToMempool(tx_mempool, entry.Fee(0).SpendsCoinbase(true).FromTx(tx));

test/functional/feature_rbf.py

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
from test_framework.test_framework import BitcoinTestFramework
1414
from test_framework.util import (
1515
assert_equal,
16-
assert_greater_than,
1716
assert_greater_than_or_equal,
1817
assert_raises_rpc_error,
1918
get_fee,
@@ -584,7 +583,7 @@ def test_replacement_relay_fee(self):
584583
tx = self.wallet.send_self_transfer(from_node=self.nodes[0])['tx']
585584

586585
# Higher fee, higher feerate, different txid, but the replacement does not provide a relay
587-
# fee conforming to node's `incrementalrelayfee` policy of 1000 sat per KB.
586+
# fee conforming to node's `incrementalrelayfee` policy of 100 sat per KB.
588587
assert_equal(self.nodes[0].getmempoolinfo()["incrementalrelayfee"], Decimal("0.000001"))
589588
tx.vout[0].nValue -= 1
590589
assert_raises_rpc_error(-26, "insufficient fee", self.nodes[0].sendrawtransaction, tx.serialize().hex())
@@ -594,7 +593,7 @@ def test_incremental_relay_feerates(self):
594593
node = self.nodes[0]
595594
for incremental_setting in (0, 5, 10, 50, 100, 234, 1000, 5000, 21000):
596595
incremental_setting_decimal = incremental_setting / Decimal(COIN)
597-
self.log.info(f"-> Test -incrementalrelayfee={incremental_setting_decimal:.8f}sat/kvB...")
596+
self.log.info(f"-> Test -incrementalrelayfee={incremental_setting:.8f}sat/kvB...")
598597
self.restart_node(0, extra_args=[f"-incrementalrelayfee={incremental_setting_decimal:.8f}", "-persistmempool=0"])
599598

600599
# When incremental relay feerate is higher than min relay feerate, min relay feerate is automatically increased.
@@ -603,23 +602,27 @@ def test_incremental_relay_feerates(self):
603602

604603
low_feerate = min_relay_feerate * 2
605604
confirmed_utxo = self.wallet.get_utxo(confirmed_only=True)
606-
replacee_tx = self.wallet.create_self_transfer(utxo_to_spend=confirmed_utxo, fee_rate=low_feerate, target_vsize=5000)
605+
# Use different versions to avoid creating an identical transaction when failed_replacement_tx is created.
606+
# Use a target vsize that is small, but something larger than the minimum so that we can create a transaction that is 1vB smaller later.
607+
replacee_tx = self.wallet.create_self_transfer(utxo_to_spend=confirmed_utxo, fee_rate=low_feerate, version=3, target_vsize=200)
607608
node.sendrawtransaction(replacee_tx['hex'])
608609

609-
replacement_placeholder_tx = self.wallet.create_self_transfer(utxo_to_spend=confirmed_utxo)
610+
replacement_placeholder_tx = self.wallet.create_self_transfer(utxo_to_spend=confirmed_utxo, target_vsize=200)
610611
replacement_expected_size = replacement_placeholder_tx['tx'].get_vsize()
611612
replacement_required_fee = get_fee(replacement_expected_size, incremental_setting_decimal) + replacee_tx['fee']
612613

613-
# Should always be required to pay additional fees
614-
if incremental_setting > 0:
615-
assert_greater_than(replacement_required_fee, replacee_tx['fee'])
616-
617-
# 1 satoshi shy of the required fee
618-
failed_replacement_tx = self.wallet.create_self_transfer(utxo_to_spend=confirmed_utxo, fee=replacement_required_fee - Decimal("0.00000001"))
614+
# Show that replacement fails when paying 1 satoshi shy of the required fee
615+
failed_replacement_tx = self.wallet.create_self_transfer(utxo_to_spend=confirmed_utxo, fee=replacement_required_fee - Decimal("0.00000001"), version=2, target_vsize=200)
619616
assert_raises_rpc_error(-26, "insufficient fee", node.sendrawtransaction, failed_replacement_tx['hex'])
617+
replacement_tx = self.wallet.create_self_transfer(utxo_to_spend=confirmed_utxo, fee=replacement_required_fee, version=2, target_vsize=200)
620618

621-
replacement_tx = self.wallet.create_self_transfer(utxo_to_spend=confirmed_utxo, fee=replacement_required_fee)
622-
node.sendrawtransaction(replacement_tx['hex'])
619+
if incremental_setting == 0:
620+
# When incremental relay feerate is 0, additional fees are not required, but higher feerate is still required.
621+
assert_raises_rpc_error(-26, "insufficient fee", node.sendrawtransaction, replacement_tx['hex'])
622+
replacement_tx_smaller = self.wallet.create_self_transfer(utxo_to_spend=confirmed_utxo, fee=replacement_required_fee, version=2, target_vsize=199)
623+
node.sendrawtransaction(replacement_tx_smaller['hex'])
624+
else:
625+
node.sendrawtransaction(replacement_tx['hex'])
623626

624627
def test_fullrbf(self):
625628
# BIP125 signaling is not respected

test/functional/mempool_package_rbf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ def test_package_rbf_additional_fees(self):
168168
failure_package_hex3, failure_package_txns3 = self.create_simple_package(coin, parent_fee=DEFAULT_FEE, child_fee=DEFAULT_CHILD_FEE + incremental_sats_short)
169169
assert_equal(package_3_size, sum([tx.get_vsize() for tx in failure_package_txns3]))
170170
pkg_results3 = node.submitpackage(failure_package_hex3)
171-
assert_equal(f"package RBF failed: insufficient anti-DoS fees, rejecting replacement {failure_package_txns3[1].txid_hex}, not enough additional fees to relay; {incremental_sats_short:8f} < {incremental_sats_required:8f}", pkg_results3["package_msg"])
171+
assert_equal(f"package RBF failed: insufficient anti-DoS fees, rejecting replacement {failure_package_txns3[1].txid_hex}, not enough additional fees to relay; {incremental_sats_short:.8f} < {incremental_sats_required:.8f}", pkg_results3["package_msg"])
172172
self.assert_mempool_contents(expected=package_txns1)
173173

174174
success_package_hex3, success_package_txns3 = self.create_simple_package(coin, parent_fee=DEFAULT_FEE, child_fee=DEFAULT_CHILD_FEE + incremental_sats_required)

test/functional/mempool_truc.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,10 @@ def test_minrelay_in_package_combos(self):
617617
assert_greater_than(get_fee(tx_v3_0fee_parent["tx"].get_vsize(), minrelayfeerate), 0)
618618
# Always need to pay at least 1 satoshi for entry, even if minimum feerate is very low
619619
assert_greater_than(total_v3_fee, 0)
620+
# Also create a version where the child is at minrelaytxfee
621+
tx_v3_child_minrelay = self.wallet.create_self_transfer(utxo_to_spend=tx_v3_0fee_parent["new_utxo"], fee_rate=minrelayfeerate, version=3)
622+
result_truc_minrelay = node.submitpackage([tx_v3_0fee_parent["hex"], tx_v3_child_minrelay["hex"]])
623+
assert_equal(result_truc_minrelay["package_msg"], "transaction failed")
620624

621625
tx_v2_0fee_parent = self.wallet.create_self_transfer(fee=0, fee_rate=0, confirmed_only=True, version=2)
622626
tx_v2_child = self.wallet.create_self_transfer(utxo_to_spend=tx_v2_0fee_parent["new_utxo"], fee_rate=high_feerate, version=2)

test/functional/mining_basic.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,18 +152,20 @@ def test_blockmintxfee_parameter(self):
152152
blockmintxfee_parameter = f"-blockmintxfee={blockmintxfee_btc_kvb:.8f}"
153153
self.log.info(f"-> Test {blockmintxfee_parameter} ({blockmintxfee_sat_kvb} sat/kvB)...")
154154
self.restart_node(0, extra_args=[blockmintxfee_parameter, '-minrelaytxfee=0', '-persistmempool=0'])
155-
self.wallet.rescan_utxos() # to avoid spending outputs of txs that are not in mempool anymore after restart
155+
assert_equal(node.getmininginfo()['blockmintxfee'], blockmintxfee_btc_kvb)
156156

157157
# submit one tx with exactly the blockmintxfee rate, and one slightly below
158158
tx_with_min_feerate = self.wallet.send_self_transfer(from_node=node, fee_rate=blockmintxfee_btc_kvb, confirmed_only=True)
159159
assert_equal(tx_with_min_feerate["fee"], get_fee(tx_with_min_feerate["tx"].get_vsize(), blockmintxfee_btc_kvb))
160-
if blockmintxfee_sat_kvb > 5:
160+
if blockmintxfee_sat_kvb >= 10:
161161
lowerfee_btc_kvb = blockmintxfee_btc_kvb - Decimal(10)/COIN # 0.01 sat/vbyte lower
162+
assert_greater_than(blockmintxfee_btc_kvb, lowerfee_btc_kvb)
163+
assert_greater_than_or_equal(lowerfee_btc_kvb, 0)
162164
tx_below_min_feerate = self.wallet.send_self_transfer(from_node=node, fee_rate=lowerfee_btc_kvb, confirmed_only=True)
163165
assert_equal(tx_below_min_feerate["fee"], get_fee(tx_below_min_feerate["tx"].get_vsize(), lowerfee_btc_kvb))
164166
else: # go below zero fee by using modified fees
165167
tx_below_min_feerate = self.wallet.send_self_transfer(from_node=node, fee_rate=blockmintxfee_btc_kvb, confirmed_only=True)
166-
node.prioritisetransaction(tx_below_min_feerate["txid"], 0, -1)
168+
node.prioritisetransaction(tx_below_min_feerate["txid"], 0, -11)
167169

168170
# check that tx below specified fee-rate is neither in template nor in the actual block
169171
block_template = node.getblocktemplate(NORMAL_GBT_REQUEST_PARAMS)

test/functional/wallet_bumpfee.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -848,12 +848,12 @@ def test_bumpfee_with_feerate_ignores_walletincrementalrelayfee(self, rbf_node,
848848
assert_raises_rpc_error(-8, "Insufficient total fee", rbf_node.bumpfee, tx["txid"], {"fee_rate": 1})
849849
assert_raises_rpc_error(-8, "Insufficient total fee", rbf_node.bumpfee, tx["txid"], {"fee_rate": 2})
850850

851-
# Ensure you can not fee bump if the fee_rate is more than original fee_rate but the total fee from new fee_rate is
852-
# less than (original fee + incrementalrelayfee)
853-
assert_raises_rpc_error(-8, "Insufficient total fee", rbf_node.bumpfee, tx["txid"], {"fee_rate": 2.05})
851+
# Ensure you can not fee bump if the fee_rate is more than original fee_rate but the additional fee does
852+
# not cover incrementalrelayfee for the size of the replacement transaction
853+
assert_raises_rpc_error(-8, "Insufficient total fee", rbf_node.bumpfee, tx["txid"], {"fee_rate": 2.09})
854854

855855
# You can fee bump as long as the new fee set from fee_rate is at least (original fee + incrementalrelayfee)
856-
rbf_node.bumpfee(tx["txid"], {"fee_rate": 3})
856+
rbf_node.bumpfee(tx["txid"], {"fee_rate": 2.1})
857857
self.clear_mempool()
858858

859859

0 commit comments

Comments
 (0)