mining: Increase minimum feerate as the block fills up - #338
Open
kwsantiago wants to merge 4 commits into
Open
Conversation
kwsantiago
force-pushed
the
block-min-feerate-ramp
branch
from
July 19, 2026 16:07
3c4cb35 to
060a29c
Compare
kwsantiago
force-pushed
the
block-min-feerate-ramp
branch
from
July 19, 2026 17:28
060a29c to
dd4a7c5
Compare
Ari4ka
approved these changes
Aug 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #59.
Satoshi's client raised the fee a transaction had to pay as the block filled up, so a block was only extended when the space was paid for:
This was never deliberately dropped. c555400 (2012) reworked
CreateNewBlockto sort the paid area by fee-per-kb, and in the process replaced the size-dependent minimum with a flat one, which is theblockMinFeeRatecheck still inaddPackageTxstoday. The ramp survived unused inGetMinFeeuntil 87cce04 (2013) removed it as dead code, correctly so by then: its only remaining caller passed a constantnBlockSizeof 1000, far below the threshold that would trigger it.Behavior
Past
-blockmintxfeerampstartpercent full, a package's minimum fee is scaled by(limit - ramp_start) / (limit - used), so it is unchanged at the ramp start, grows without bound as the block fills, and reachesMAX_MONEYwhen full. Fullness is measured against whichever of-blockmaxsizeor-blockmaxweightis tighter, since only one of the two may be set.The default is 50, where the original engaged. Setting it to 100 disables the scaling. It scales
-blockmintxfee, so a-blockmintxfeeof 0 also disables it. The option is also on the Mining tab, and can be overridden pergetblocktemplaterequest alongsideminfeerate.Two things differ from the original. The multiplier is continuous instead of integer steps that jump straight to 2x at the halfway mark. And fullness excludes the candidate transaction: making the threshold depend on the candidate's own size would break the assumption in
addPackageTxsthat a package failing the check cannot be followed by one that passes, which is what lets it return instead of scanning the rest of the mempool. The threshold lags by at most one transaction as a result.Coin-age priority transactions are exempt from
-blockmintxfeeand are selected first, so they advance the fullness counter and can start the fee pass partway up the ramp, as they did originally. At the defaults the priority area is 100000 of 300000 bytes, below the 50% start, so this only engages if-blockprioritysizeis raised past-blockmintxfeerampstartpercent of the block. Where it is, free transactions from aged UTXOs raise the floor for fee-paying ones.The default
Turning the ramp on by default is the part worth arguing about. With
-blockmintxfee=1000, a package paying 2 sat/vB is admitted while the block is under 75% full, so a mempool whose marginal transactions sit at that feerate leaves a quarter of the block empty; measured at a full 4M weight block, 75% against 99% with the ramp off. How much that costs depends on the mempool, since selection stops where the falling feerate curve meets the rising threshold: a steep fee distribution is barely affected, a flat low-fee one fully. 50 is what the original used, and shipping it off would leave the issue unaddressed for anyone who does not go looking for the option.Testing
ScaledBlockMinFeeis covered inminer_testsat every ramp value, including across the saturation boundary, asserting that the fee demanded never decreases as the block fills, which is the property the early return relies on.mining_blockmintxfeerampstart.pydrives the option end to end against expected transaction counts, covering the size-limited path,-blockprioritysize, CPFP packages priced as whole ancestor sets, thegetblocktemplateoverride, and startup validation, and mines a block to check its contents.Enabling the ramp by default adds roughly 15% to functional test runtime, since smaller blocks mean the tests mine more of them.
GUI