From the mempool's perspective, the rollingMinimumFeeRate
is the actual minimum fee rate (the minrelayfee pertains to other parts of the codebase). It starts at 0, and is updated whenever a transaction package is evicted from the mempool due to size constraints. When the mempool reaches its configured maximum, it removes the lowest feerate package to free up space, and sets the rollingMinimumFeeRate
to the feerate the removed package paid.
But then you might wonder how the rollingMinimumFeeRate
goes down? What happens if the maximum mempool size is reached, but then transactions get confirmed and the mempool's size is reduced? The rollingMinimumFeeRate
needs to decrease eventually, and that is what GetMinFee
is doing.
GetMinFee
is the second part of updating rollingMinimumFeeRate
. It reduces it exponentially according to a schedule. If it has been more than 10 seconds since rollingMinimumFeeRate
has changed (either up or down), then it will be divided by some power of 2.
If the mempool is more than half full, and no packages are removed to increase rollingMinimumFeeRate
again, then after 12 hours, it will be half of what its original value was. That is to say, rollingMinimumFeeRate
has a half life of 12 hours when the mempool is at least half full.
This half life decreases when the mempool is between a quarter full and half full. In that case, it is 6 hours. And when the mempool is less than a quarter full, the half life is 3 hours. This is what this section does:
double halflife = ROLLING_FEE_HALFLIFE; if (DynamicMemoryUsage() < sizelimit / 4) halflife /= 4; else if (DynamicMemoryUsage() < sizelimit / 2) halflife /= 2;
To compute the reduced rollingMinimumFeeRate
, we want to figure out how much time has passed since the last update and figure out how much lower it should be given the half life that we want. That is what this line does:
rollingMinimumFeeRate = rollingMinimumFeeRate / pow(2.0, (time - lastRollingFeeUpdate) / halflife);
This is really just the half life formula: N(t) = N_0 * (1/2) ^ (t/t_1/2)
.
N_0
is the initial quantity (rollingMinimumFeeRate
), t
is the time that has passed (time - lastRollingFeeUpdate
), and t_1/2
is the half life we want (halflife
). If you move the exponent into the fraction, reduce the formula, and write it out in code, you get the aforementioned computation line.
The last piece to this update is to check whether the rollingMinimumFeeRate
is less than half of the incrementalRelayFee. If it is, then rollingMinimumFeeRate
is set to 0. This is done because exponential decay means that rollingMinimumFeeRate
would technically never reach 0 (that's how the exponential decay function works). So instead we just bound it to be no less than half of the incrementalRelayFee
. Once it reaches that, it just resets to 0 because at that point, it will be incredibly low anyways.
We use the incrementalRelayFee
as the lower bound because that is the minimum feerate a transaction needs to pay after accounting for conflicts in order to be relayed. So a transaction must be paying at least incrementalRelayFee
, so we can drop the rollingMinimumFeeRate
after it is less than incrementalRelayFee
, but to be safe, we do it at half of that value.
That last piece of GetMinFee
is at the top of the function, which is simply that the current rollingMinimumFeeRate
does not change until we find a block, and an optimization to return it when it is already 0. This first part is important because we don't want to be reducing the mempool's minimum fee when things aren't being removed from the mempool.
You can get bonuses upto $100 FREE BONUS when you:
π° Install these recommended apps:
π² SocialGood - 100% Crypto Back on Everyday Shopping
π² xPortal - The DeFi For The Next Billion
π² CryptoTab Browser - Lightweight, fast, and ready to mine!
π° Register on these recommended exchanges:
π‘ Binanceπ‘ Bitfinexπ‘ Bitmartπ‘ Bittrexπ‘ Bitget
π‘ CoinExπ‘ Crypto.comπ‘ Gate.ioπ‘ Huobiπ‘ Kucoin.
Comments