The current fee estimation algorithm suffers from a number of issues that make it hard to use in the real world:
- Because it’s solely based on historical data (looking at how long mempool transactions take to confirm), it cannot react quickly to changing conditions.
- Because it’s aiming to match seen behavior rather than requirement, if some non-negligible fraction of users keeps paying a certain high feerate, it may try to match that, even if unnecessary for confirmation.
There exist alternative sources of information which could mitigate some of these issues, but they are not used for various reasons:
- We could look at the feerate histogram of the current mempool, which can react much faster, though lacks information about the rate/feerate of transactions being added. It is not used, because in the presence of diverging network policy, it may give permanently and wildly wrong results. For example, a pre-taproot node won’t see taproot transactions entirely, and thus miss any feerate pressure they provide. In the other direction, If local policy is more lax than the network’s, our mempool may contain unconfirmable high-fee things that incorrectly are accounted for.
- We could look at the rate and feerate of transactions entering the mempool currently, rather than only account for them when they confirm. This gives better predictive value, but suffers from the same problems as the previous point when policies differ.
- We could look at the feerate of transactions in blocks, but this is trivially gameable by miners.
I wonder if it wouldn’t be possible to take the mempool-based approaches into account, but subjecting them to a sanity checks based on confirmation. More concretely:
- We can look at what percentage of high-feerate mempool transactions confirm within a reasonable period of time. If that percentage is high, it’s unlikely we have a significantly diverging policy from the network’s aggregate policy. If it is too low, we may want to disable mempool-based fee estimation entirely.
- We can keep a counter on transactions in the mempool that tracks how often we’d have expected it to be seen in a block, but didn’t. If that counter goes too high for a certain transaction, we could exclude it from feerate calculations. This can reduce issues with too lax local policy, but not the other way around.
Even with these safeguards, I don’t think it’s reasonable to use as a default feerate estimate (at least not for automatic feerate decisions without human intervention, like sendtoaddress
and friends), but it could be a separately selectable estimation mode.
This issue is the result of a discussion with @Xekyo, @achow101, @adamjonas, and @mzumsande.