mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-25 02:33:24 -03:00
tx fees, policy: do not read estimates of old fee_estimates.dat
Old fee estimates could cause transactions to become stuck in the
mempool. This commit prevents the node from using stale estimates
from an old file.
Github-Pull: #27622
Rebased-From: 3eb241a141
This commit is contained in:
parent
77979e0172
commit
1c98029b39
2 changed files with 31 additions and 2 deletions
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
@ -545,9 +546,22 @@ CBlockPolicyEstimator::CBlockPolicyEstimator(const fs::path& estimation_filepath
|
|||
shortStats = std::unique_ptr<TxConfirmStats>(new TxConfirmStats(buckets, bucketMap, SHORT_BLOCK_PERIODS, SHORT_DECAY, SHORT_SCALE));
|
||||
longStats = std::unique_ptr<TxConfirmStats>(new TxConfirmStats(buckets, bucketMap, LONG_BLOCK_PERIODS, LONG_DECAY, LONG_SCALE));
|
||||
|
||||
// If the fee estimation file is present, read recorded estimations
|
||||
AutoFile est_file{fsbridge::fopen(m_estimation_filepath, "rb")};
|
||||
if (est_file.IsNull() || !Read(est_file)) {
|
||||
|
||||
// Whenever the fee estimation file is not present return early
|
||||
if (est_file.IsNull()) {
|
||||
LogPrintf("%s is not found. Continue anyway.\n", fs::PathToString(m_estimation_filepath));
|
||||
return;
|
||||
}
|
||||
|
||||
std::chrono::hours file_age = GetFeeEstimatorFileAge();
|
||||
// fee estimate file must not be too old to avoid wrong fee estimates.
|
||||
if (file_age > MAX_FILE_AGE) {
|
||||
LogPrintf("Fee estimation file %s too old (age=%lld > %lld hours) and will not be used to avoid serving stale estimates.\n", fs::PathToString(m_estimation_filepath), Ticks<std::chrono::hours>(file_age), Ticks<std::chrono::hours>(MAX_FILE_AGE));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Read(est_file)) {
|
||||
LogPrintf("Failed to read fee estimates from %s. Continue anyway.\n", fs::PathToString(m_estimation_filepath));
|
||||
}
|
||||
}
|
||||
|
@ -1016,6 +1030,13 @@ void CBlockPolicyEstimator::FlushUnconfirmed() {
|
|||
LogPrint(BCLog::ESTIMATEFEE, "Recorded %u unconfirmed txs from mempool in %gs\n", num_entries, (endclear - startclear)*0.000001);
|
||||
}
|
||||
|
||||
std::chrono::hours CBlockPolicyEstimator::GetFeeEstimatorFileAge()
|
||||
{
|
||||
auto file_time = std::filesystem::last_write_time(m_estimation_filepath);
|
||||
auto now = std::filesystem::file_time_type::clock::now();
|
||||
return std::chrono::duration_cast<std::chrono::hours>(now - file_time);
|
||||
}
|
||||
|
||||
FeeFilterRounder::FeeFilterRounder(const CFeeRate& minIncrementalFee)
|
||||
{
|
||||
CAmount minFeeLimit = std::max(CAmount(1), minIncrementalFee.GetFeePerK() / 2);
|
||||
|
|
|
@ -25,6 +25,11 @@
|
|||
// How often to flush fee estimates to fee_estimates.dat.
|
||||
static constexpr std::chrono::hours FEE_FLUSH_INTERVAL{1};
|
||||
|
||||
/** fee_estimates.dat that are more than 60 hours (2.5 days) will not be read,
|
||||
* as the estimates in the file are stale.
|
||||
*/
|
||||
static constexpr std::chrono::hours MAX_FILE_AGE{60};
|
||||
|
||||
class AutoFile;
|
||||
class CTxMemPoolEntry;
|
||||
class TxConfirmStats;
|
||||
|
@ -248,6 +253,9 @@ public:
|
|||
void FlushFeeEstimates()
|
||||
EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);
|
||||
|
||||
/** Calculates the age of the file, since last modified */
|
||||
std::chrono::hours GetFeeEstimatorFileAge();
|
||||
|
||||
private:
|
||||
mutable Mutex m_cs_fee_estimator;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue