refactor: Make CFeeRate constructor architecture-independent

This commit is contained in:
MarcoFalke
2021-05-04 10:14:12 +02:00
parent c857148636
commit fafd121026
4 changed files with 16 additions and 22 deletions

View File

@@ -7,29 +7,26 @@
#include <tinyformat.h> #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())); const int64_t nSize{num_bytes};
int64_t nSize = int64_t(nBytes_);
if (nSize > 0) if (nSize > 0) {
nSatoshisPerK = nFeePaid * 1000 / nSize; nSatoshisPerK = nFeePaid * 1000 / nSize;
else } else {
nSatoshisPerK = 0; 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())); const int64_t nSize{num_bytes};
int64_t nSize = int64_t(nBytes_);
CAmount nFee = nSatoshisPerK * nSize / 1000; CAmount nFee = nSatoshisPerK * nSize / 1000;
if (nFee == 0 && nSize != 0) { if (nFee == 0 && nSize != 0) {
if (nSatoshisPerK > 0) if (nSatoshisPerK > 0) nFee = CAmount(1);
nFee = CAmount(1); if (nSatoshisPerK < 0) nFee = CAmount(-1);
if (nSatoshisPerK < 0)
nFee = CAmount(-1);
} }
return nFee; return nFee;

View File

@@ -39,20 +39,17 @@ public:
// We've previously had bugs creep in from silent double->int conversion... // 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"); 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), * e.g. (nFeePaid * 1e8 / 1e3) == (nFeePaid / 1e5),
* where 1e5 is the ratio to convert from BTC/kvB to sat/vB. * 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. * 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 * Return the fee in satoshis for a size of 1000 bytes
*/ */

View File

@@ -83,7 +83,7 @@ BOOST_AUTO_TEST_CASE(GetFeeTest)
BOOST_CHECK(CFeeRate(CAmount(26), 789) == CFeeRate(32)); BOOST_CHECK(CFeeRate(CAmount(26), 789) == CFeeRate(32));
BOOST_CHECK(CFeeRate(CAmount(27), 789) == CFeeRate(34)); BOOST_CHECK(CFeeRate(CAmount(27), 789) == CFeeRate(34));
// Maximum size in bytes, should not crash // Maximum size in bytes, should not crash
CFeeRate(MAX_MONEY, std::numeric_limits<size_t>::max() >> 1).GetFeePerK(); CFeeRate(MAX_MONEY, std::numeric_limits<uint32_t>::max()).GetFeePerK();
} }
BOOST_AUTO_TEST_CASE(BinaryOperatorTest) BOOST_AUTO_TEST_CASE(BinaryOperatorTest)

View File

@@ -20,8 +20,8 @@ FUZZ_TARGET(fee_rate)
const CFeeRate fee_rate{satoshis_per_k}; const CFeeRate fee_rate{satoshis_per_k};
(void)fee_rate.GetFeePerK(); (void)fee_rate.GetFeePerK();
const size_t bytes = fuzzed_data_provider.ConsumeIntegral<size_t>(); const auto bytes = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
if (!MultiplicationOverflow(static_cast<int64_t>(bytes), satoshis_per_k) && bytes <= static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) { if (!MultiplicationOverflow(int64_t{bytes}, satoshis_per_k)) {
(void)fee_rate.GetFee(bytes); (void)fee_rate.GetFee(bytes);
} }
(void)fee_rate.ToString(); (void)fee_rate.ToString();