aboutsummaryrefslogtreecommitdiff
path: root/src/policy
diff options
context:
space:
mode:
authorismaelsadeeq <ask4ismailsadiq@gmail.com>2023-06-14 22:32:27 +0100
committerismaelsadeeq <ask4ismailsadiq@gmail.com>2023-06-14 22:32:27 +0100
commit3eb241a141defa564c94cb95c5bbaf4c5bd9682e (patch)
tree26400572a296470d7df1c9e55397a31115ec7846 /src/policy
parent5b886f2b436eaa8c2b7de58dc4644dc6223040da (diff)
downloadbitcoin-3eb241a141defa564c94cb95c5bbaf4c5bd9682e.tar.xz
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.
Diffstat (limited to 'src/policy')
-rw-r--r--src/policy/fees.cpp25
-rw-r--r--src/policy/fees.h8
2 files changed, 31 insertions, 2 deletions
diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp
index 7bbc9b5e89..a8ca8545d3 100644
--- a/src/policy/fees.cpp
+++ b/src/policy/fees.cpp
@@ -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));
}
}
@@ -1017,6 +1031,13 @@ void CBlockPolicyEstimator::FlushUnconfirmed()
LogPrint(BCLog::ESTIMATEFEE, "Recorded %u unconfirmed txs from mempool in %gs\n", num_entries, Ticks<SecondsDouble>(endclear - startclear));
}
+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);
+}
+
static std::set<double> MakeFeeSet(const CFeeRate& min_incremental_fee,
double max_filter_fee_rate,
double fee_filter_spacing)
diff --git a/src/policy/fees.h b/src/policy/fees.h
index a6c45839b9..a348ba05d8 100644
--- a/src/policy/fees.h
+++ b/src/policy/fees.h
@@ -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;