diff --git a/src/amount.h b/src/amount.h --- a/src/amount.h +++ b/src/amount.h @@ -18,14 +18,14 @@ int64_t amount; public: - Amount() : amount(0) {} + constexpr Amount() : amount(0) {} - template Amount(T _camount) : amount(_camount) { + template constexpr Amount(T _camount) : amount(_camount) { static_assert(std::is_integral(), "Only integer types can be used as amounts"); } - Amount(const Amount &_camount) : amount(_camount.amount) {} + constexpr Amount(const Amount &_camount) : amount(_camount.amount) {} // Allow access to underlying value for non-monetary operations int64_t GetSatoshis() const { return amount; } @@ -41,44 +41,48 @@ amount -= a.amount; return *this; } - friend bool operator<(const Amount a, const Amount b) { + friend constexpr bool operator<(const Amount a, const Amount b) { return a.amount < b.amount; } - friend bool operator==(const Amount a, const Amount b) { + friend constexpr bool operator==(const Amount a, const Amount b) { return a.amount == b.amount; } - friend bool operator>(const Amount a, const Amount b) { + friend constexpr bool operator>(const Amount a, const Amount b) { return b.amount < a.amount; } - friend bool operator!=(const Amount a, const Amount b) { + friend constexpr bool operator!=(const Amount a, const Amount b) { return !(a.amount == b.amount); } - friend bool operator<=(const Amount a, const Amount b) { + friend constexpr bool operator<=(const Amount a, const Amount b) { return !(a.amount > b.amount); } - friend bool operator>=(const Amount a, const Amount b) { + friend constexpr bool operator>=(const Amount a, const Amount b) { return !(a.amount < b.amount); } - friend Amount operator+(const Amount a, const Amount b) { + friend constexpr Amount operator+(const Amount a, const Amount b) { return Amount(a.amount + b.amount); } - friend Amount operator-(const Amount a, const Amount b) { + friend constexpr Amount operator-(const Amount a, const Amount b) { return Amount(a.amount - b.amount); } // Implemented for allowing COIN as a base unit. - friend Amount operator*(const int64_t a, const Amount b) { + friend constexpr Amount operator*(const int64_t a, const Amount b) { return Amount(a * b.amount); } - friend Amount operator*(const int a, const Amount b) { + friend constexpr Amount operator*(const int a, const Amount b) { return Amount(a * b.amount); } // DO NOT IMPLEMENT - friend Amount operator*(const double a, const Amount b) = delete; - int64_t operator/(const Amount b) const { return amount / b.amount; } - Amount operator/(const int64_t b) const { return Amount(amount / b); } - Amount operator/(const int b) const { return Amount(amount / b); } + friend constexpr Amount operator*(const double a, const Amount b) = delete; + constexpr int64_t operator/(const Amount b) const { + return amount / b.amount; + } + constexpr Amount operator/(const int64_t b) const { + return Amount(amount / b); + } + constexpr Amount operator/(const int b) const { return Amount(amount / b); } // DO NOT IMPLEMENT - Amount operator/(const double b) const = delete; + constexpr Amount operator/(const double b) const = delete; // ostream support friend std::ostream &operator<<(std::ostream &stream, const Amount &ca) { diff --git a/src/policy/fees.h b/src/policy/fees.h --- a/src/policy/fees.h +++ b/src/policy/fees.h @@ -198,7 +198,7 @@ static const double SUFFICIENT_FEETXS = 1; // Minimum and Maximum values for tracking feerates -static constexpr double MIN_FEERATE = 10; +static constexpr Amount MIN_FEERATE(10); static const Amount MAX_FEERATE(int64_t(1e7)); static const Amount INF_FEERATE(MAX_MONEY); static const Amount INF_PRIORITY(int64_t(1e9) * MAX_MONEY); @@ -207,7 +207,7 @@ // able to give accurate estimates over a large range of potential feerates. // Therefore it makes sense to exponentially space the buckets /** Spacing of FeeRate buckets */ -static const int64_t FEE_SPACING_FRACTION = 10; +static const double FEE_SPACING = 1.1; /** * We want to be able to estimate feerates that are needed on tx's to be diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp --- a/src/policy/fees.cpp +++ b/src/policy/fees.cpp @@ -326,28 +326,28 @@ // are never double tracked, but it is of no harm to try to remove them again. bool CBlockPolicyEstimator::removeTx(uint256 hash) { std::map::iterator pos = mapMemPoolTxs.find(hash); - if (pos != mapMemPoolTxs.end()) { - feeStats.removeTx(pos->second.blockHeight, nBestSeenHeight, - pos->second.bucketIndex); - mapMemPoolTxs.erase(hash); - return true; - } else { + if (pos == mapMemPoolTxs.end()) { return false; } + + feeStats.removeTx(pos->second.blockHeight, nBestSeenHeight, + pos->second.bucketIndex); + mapMemPoolTxs.erase(hash); + return true; } CBlockPolicyEstimator::CBlockPolicyEstimator(const CFeeRate &_minRelayFee) : nBestSeenHeight(0), trackedTxs(0), untrackedTxs(0) { - static_assert(MIN_FEERATE > 0, "Min feerate must be nonzero"); - minTrackedFee = _minRelayFee < CFeeRate(Amount(int64_t(MIN_FEERATE))) - ? CFeeRate(Amount(int64_t(MIN_FEERATE))) - : _minRelayFee; + static_assert(MIN_FEERATE > Amount(0), "Min feerate must be nonzero"); + CFeeRate minFeeRate(MIN_FEERATE); + minTrackedFee = _minRelayFee < minFeeRate ? minFeeRate : _minRelayFee; std::vector vfeelist; - for (Amount bucketBoundary = minTrackedFee.GetFeePerK(); - bucketBoundary <= MAX_FEERATE; - bucketBoundary += bucketBoundary / FEE_SPACING_FRACTION) { - vfeelist.push_back(double(bucketBoundary.GetSatoshis())); + for (double bucketBoundary = minTrackedFee.GetFeePerK().GetSatoshis(); + bucketBoundary <= double(MAX_FEERATE.GetSatoshis()); + bucketBoundary *= FEE_SPACING) { + vfeelist.push_back(bucketBoundary); } + vfeelist.push_back(double(INF_FEERATE.GetSatoshis())); feeStats.Initialize(vfeelist, MAX_BLOCK_CONFIRMS, DEFAULT_DECAY); } @@ -562,17 +562,19 @@ Amount minFeeLimit = std::max(Amount(1), minIncrementalFee.GetFeePerK() / 2); feeset.insert(Amount(0)); - for (Amount bucketBoundary = minFeeLimit; bucketBoundary <= MAX_FEERATE; - bucketBoundary += bucketBoundary / FEE_SPACING_FRACTION) { - feeset.insert(bucketBoundary); + for (double bucketBoundary = minFeeLimit.GetSatoshis(); + bucketBoundary <= double(MAX_FEERATE.GetSatoshis()); + bucketBoundary *= FEE_SPACING) { + feeset.insert(Amount(int64_t(bucketBoundary))); } } Amount FeeFilterRounder::round(const Amount currentMinFee) { - std::set::iterator it = feeset.lower_bound(currentMinFee); + auto it = feeset.lower_bound(currentMinFee); if ((it != feeset.begin() && insecure_rand.rand32() % 3 != 0) || it == feeset.end()) { it--; } + return *it; }