Skip to content

Commit

Permalink
policy, fees: get mempool based fee estimates periodically
Browse files Browse the repository at this point in the history
  • Loading branch information
ismaelsadeeq committed Apr 1, 2024
1 parent 4842842 commit b9fb5b7
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 5 deletions.
10 changes: 7 additions & 3 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1292,9 +1292,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
validation_signals.RegisterValidationInterface(fee_estimator);
}

assert(!node.mempool_fee_estimator);

node.mempool_fee_estimator = std::make_unique<MemPoolPolicyEstimator>();

// Check port numbers
for (const std::string port_option : {
Expand Down Expand Up @@ -1621,6 +1618,13 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)

ChainstateManager& chainman = *Assert(node.chainman);

assert(!node.mempool_fee_estimator);

node.mempool_fee_estimator = std::make_unique<MemPoolPolicyEstimator>();
MemPoolPolicyEstimator* mempool_fee_estimator = node.mempool_fee_estimator.get();
CBlockPolicyEstimator* fee_estimator = node.fee_estimator.get();
CTxMemPool& mempool = *(node.mempool.get());
node.scheduler->scheduleEvery([mempool_fee_estimator, fee_estimator, &mempool, &chainman] { mempool_fee_estimator->EstimateFeeWithMemPool(chainman, mempool, fee_estimator); }, FEE_ESTIMATE_INTERVAL);
assert(!node.peerman);
node.peerman = PeerManager::make(*node.connman, *node.addrman,
node.banman.get(), chainman,
Expand Down
20 changes: 18 additions & 2 deletions src/policy/mempool_fees.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
#include <consensus/consensus.h>
#include <logging.h>
#include <node/miner.h>
#include <policy/fees.h>
#include <policy/mempool_fees.h>
#include <policy/policy.h>

#include <validation.h>

using node::GetCustomBlockFeeRateHistogram;

Expand Down Expand Up @@ -59,10 +60,25 @@ MempoolFeeEstimationResult MemPoolPolicyEstimator::EstimateFeeWithMemPool(Chains
if (fee_rate_estimate_result.empty()) {
err_message = "Insufficient mempool transactions to perform an estimate.";
}

return fee_rate_estimate_result;
}

void MemPoolPolicyEstimator::EstimateFeeWithMemPool(const ChainstateManager& chainman, const CTxMemPool& mempool, const CBlockPolicyEstimator* fee_estimator) const
{
std::string err_message;
LOCK(cs_main);
CBlockIndex* block = chainman.ActiveTip();
MempoolFeeEstimationResult estimate = EstimateFeeWithMemPool(chainman.ActiveChainstate(), mempool, /*confTarget=*/1, /*force=*/true, err_message);
FeeCalculation feeCalc;
CFeeRate block_estimate = fee_estimator->estimateSmartFee(/*conf_target=*/1, &feeCalc, /*conservative=*/false);
if (estimate.empty()) {
LogInfo("At block %s, height %s, failed to get mempool based fee rate estimate; error: %s \n", block->phashBlock->GetHex(), block->nHeight, err_message);
} else {
LogInfo("At block %s, height %s, mempool based fee rate estimate for next block has a 75th percentile fee rate %s, 50th percentile fee rate %s, 25th percentile fee rate %s, 5th percentile fee rate %s, block estimate for next block is %s \n",
block->phashBlock->GetHex(), block->nHeight, estimate.p75.GetFeePerK(), estimate.p50.GetFeePerK(), estimate.p25.GetFeePerK(), estimate.p5.GetFeePerK(), block_estimate.GetFeePerK());
}
}

std::map<uint64_t, MempoolFeeEstimationResult> MemPoolPolicyEstimator::EstimateBlockFeeRatesWithMempool(
const std::vector<std::tuple<CFeeRate, uint64_t>>& mempool_fee_stats, unsigned int confTarget) const
{
Expand Down
5 changes: 5 additions & 0 deletions src/policy/mempool_fees.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@
#include <logging.h>
#include <policy/feerate.h>

class CBlockPolicyEstimator;
class Chainstate;
class ChainstateManager;
class CTxMemPool;

// Fee rate estimates above this confirmation target are not reliable,
// mempool condition might likely change.
static const unsigned int MAX_CONF_TARGET{1};

static constexpr std::chrono::minutes FEE_ESTIMATE_INTERVAL{1};

// Fee estimation result containing percentiles (in sat/kvB).
struct MempoolFeeEstimationResult {
CFeeRate p5; // 5th percentile
Expand Down Expand Up @@ -114,6 +118,7 @@ class MemPoolPolicyEstimator
* @return The estimated fee rates.
*/
MempoolFeeEstimationResult EstimateFeeWithMemPool(Chainstate& chainstate, const CTxMemPool& mempool, unsigned int confTarget, const bool force, std::string& err_message) const;
void EstimateFeeWithMemPool(const ChainstateManager& chainstate, const CTxMemPool& mempool, const CBlockPolicyEstimator* fee_estimator) const;

private:
mutable CachedMempoolEstimates cache;
Expand Down

0 comments on commit b9fb5b7

Please sign in to comment.