diff options
Diffstat (limited to 'src/policy')
-rw-r--r-- | src/policy/feerate.cpp | 21 | ||||
-rw-r--r-- | src/policy/feerate.h | 11 | ||||
-rw-r--r-- | src/policy/fees.cpp | 48 |
3 files changed, 47 insertions, 33 deletions
diff --git a/src/policy/feerate.cpp b/src/policy/feerate.cpp index 3da85fedf9..25b9282b4e 100644 --- a/src/policy/feerate.cpp +++ b/src/policy/feerate.cpp @@ -7,29 +7,26 @@ #include <tinyformat.h> -CFeeRate::CFeeRate(const CAmount& nFeePaid, size_t nBytes_) +CFeeRate::CFeeRate(const CAmount& nFeePaid, uint32_t num_bytes) { - assert(nBytes_ <= uint64_t(std::numeric_limits<int64_t>::max())); - int64_t nSize = int64_t(nBytes_); + const int64_t nSize{num_bytes}; - if (nSize > 0) + if (nSize > 0) { nSatoshisPerK = nFeePaid * 1000 / nSize; - else + } else { nSatoshisPerK = 0; + } } -CAmount CFeeRate::GetFee(size_t nBytes_) const +CAmount CFeeRate::GetFee(uint32_t num_bytes) const { - assert(nBytes_ <= uint64_t(std::numeric_limits<int64_t>::max())); - int64_t nSize = int64_t(nBytes_); + const int64_t nSize{num_bytes}; CAmount nFee = nSatoshisPerK * nSize / 1000; if (nFee == 0 && nSize != 0) { - if (nSatoshisPerK > 0) - nFee = CAmount(1); - if (nSatoshisPerK < 0) - nFee = CAmount(-1); + if (nSatoshisPerK > 0) nFee = CAmount(1); + if (nSatoshisPerK < 0) nFee = CAmount(-1); } return nFee; diff --git a/src/policy/feerate.h b/src/policy/feerate.h index 0e4f9914b8..d296d32774 100644 --- a/src/policy/feerate.h +++ b/src/policy/feerate.h @@ -39,20 +39,17 @@ public: // We've previously had bugs creep in from silent double->int conversion... static_assert(std::is_integral<I>::value, "CFeeRate should be used without floats"); } - /** Constructor for a fee rate in satoshis per kvB (sat/kvB). The size in bytes must not exceed (2^63 - 1). + /** Constructor for a fee rate in satoshis per kvB (sat/kvB). * - * Passing an nBytes value of COIN (1e8) returns a fee rate in satoshis per vB (sat/vB), + * Passing a num_bytes value of COIN (1e8) returns a fee rate in satoshis per vB (sat/vB), * e.g. (nFeePaid * 1e8 / 1e3) == (nFeePaid / 1e5), * where 1e5 is the ratio to convert from BTC/kvB to sat/vB. - * - * @param[in] nFeePaid CAmount fee rate to construct with - * @param[in] nBytes size_t bytes (units) to construct with */ - CFeeRate(const CAmount& nFeePaid, size_t nBytes); + CFeeRate(const CAmount& nFeePaid, uint32_t num_bytes); /** * Return the fee in satoshis for the given size in bytes. */ - CAmount GetFee(size_t nBytes) const; + CAmount GetFee(uint32_t num_bytes) const; /** * Return the fee in satoshis for a size of 1000 bytes */ diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp index 7da171d2e1..2ae5798ebe 100644 --- a/src/policy/fees.cpp +++ b/src/policy/fees.cpp @@ -10,6 +10,7 @@ #include <logging.h> #include <streams.h> #include <txmempool.h> +#include <util/serfloat.h> #include <util/system.h> static const char* FEE_ESTIMATES_FILENAME = "fee_estimates.dat"; @@ -26,6 +27,25 @@ std::string StringForFeeEstimateHorizon(FeeEstimateHorizon horizon) assert(false); } +namespace { + +struct EncodedDoubleFormatter +{ + template<typename Stream> void Ser(Stream &s, double v) + { + s << EncodeDouble(v); + } + + template<typename Stream> void Unser(Stream& s, double& v) + { + uint64_t encoded; + s >> encoded; + v = DecodeDouble(encoded); + } +}; + +} // namespace + /** * We will instantiate an instance of this class to track transactions that were * included in a block. We will lump transactions into a bucket according to their @@ -356,12 +376,12 @@ double TxConfirmStats::EstimateMedianVal(int confTarget, double sufficientTxVal, void TxConfirmStats::Write(CAutoFile& fileout) const { - fileout << decay; + fileout << Using<EncodedDoubleFormatter>(decay); fileout << scale; - fileout << m_feerate_avg; - fileout << txCtAvg; - fileout << confAvg; - fileout << failAvg; + fileout << Using<VectorFormatter<EncodedDoubleFormatter>>(m_feerate_avg); + fileout << Using<VectorFormatter<EncodedDoubleFormatter>>(txCtAvg); + fileout << Using<VectorFormatter<VectorFormatter<EncodedDoubleFormatter>>>(confAvg); + fileout << Using<VectorFormatter<VectorFormatter<EncodedDoubleFormatter>>>(failAvg); } void TxConfirmStats::Read(CAutoFile& filein, int nFileVersion, size_t numBuckets) @@ -372,7 +392,7 @@ void TxConfirmStats::Read(CAutoFile& filein, int nFileVersion, size_t numBuckets size_t maxConfirms, maxPeriods; // The current version will store the decay with each individual TxConfirmStats and also keep a scale factor - filein >> decay; + filein >> Using<EncodedDoubleFormatter>(decay); if (decay <= 0 || decay >= 1) { throw std::runtime_error("Corrupt estimates file. Decay must be between 0 and 1 (non-inclusive)"); } @@ -381,15 +401,15 @@ void TxConfirmStats::Read(CAutoFile& filein, int nFileVersion, size_t numBuckets throw std::runtime_error("Corrupt estimates file. Scale must be non-zero"); } - filein >> m_feerate_avg; + filein >> Using<VectorFormatter<EncodedDoubleFormatter>>(m_feerate_avg); if (m_feerate_avg.size() != numBuckets) { throw std::runtime_error("Corrupt estimates file. Mismatch in feerate average bucket count"); } - filein >> txCtAvg; + filein >> Using<VectorFormatter<EncodedDoubleFormatter>>(txCtAvg); if (txCtAvg.size() != numBuckets) { throw std::runtime_error("Corrupt estimates file. Mismatch in tx count bucket count"); } - filein >> confAvg; + filein >> Using<VectorFormatter<VectorFormatter<EncodedDoubleFormatter>>>(confAvg); maxPeriods = confAvg.size(); maxConfirms = scale * maxPeriods; @@ -402,7 +422,7 @@ void TxConfirmStats::Read(CAutoFile& filein, int nFileVersion, size_t numBuckets } } - filein >> failAvg; + filein >> Using<VectorFormatter<VectorFormatter<EncodedDoubleFormatter>>>(failAvg); if (maxPeriods != failAvg.size()) { throw std::runtime_error("Corrupt estimates file. Mismatch in confirms tracked for failures"); } @@ -504,7 +524,7 @@ CBlockPolicyEstimator::CBlockPolicyEstimator() 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 - fs::path est_filepath = GetDataDir() / FEE_ESTIMATES_FILENAME; + fs::path est_filepath = gArgs.GetDataDirNet() / FEE_ESTIMATES_FILENAME; CAutoFile est_file(fsbridge::fopen(est_filepath, "rb"), SER_DISK, CLIENT_VERSION); if (est_file.IsNull() || !Read(est_file)) { LogPrintf("Failed to read fee estimates from %s. Continue anyway.\n", est_filepath.string()); @@ -864,7 +884,7 @@ CFeeRate CBlockPolicyEstimator::estimateSmartFee(int confTarget, FeeCalculation void CBlockPolicyEstimator::Flush() { FlushUnconfirmed(); - fs::path est_filepath = GetDataDir() / FEE_ESTIMATES_FILENAME; + fs::path est_filepath = gArgs.GetDataDirNet() / FEE_ESTIMATES_FILENAME; CAutoFile est_file(fsbridge::fopen(est_filepath, "wb"), SER_DISK, CLIENT_VERSION); if (est_file.IsNull() || !Write(est_file)) { LogPrintf("Failed to write fee estimates to %s. Continue anyway.\n", est_filepath.string()); @@ -884,7 +904,7 @@ bool CBlockPolicyEstimator::Write(CAutoFile& fileout) const else { fileout << historicalFirst << historicalBest; } - fileout << buckets; + fileout << Using<VectorFormatter<EncodedDoubleFormatter>>(buckets); feeStats->Write(fileout); shortStats->Write(fileout); longStats->Write(fileout); @@ -920,7 +940,7 @@ bool CBlockPolicyEstimator::Read(CAutoFile& filein) throw std::runtime_error("Corrupt estimates file. Historical block range for estimates is invalid"); } std::vector<double> fileBuckets; - filein >> fileBuckets; + filein >> Using<VectorFormatter<EncodedDoubleFormatter>>(fileBuckets); size_t numBuckets = fileBuckets.size(); if (numBuckets <= 1 || numBuckets > 1000) { throw std::runtime_error("Corrupt estimates file. Must have between 2 and 1000 feerate buckets"); |