Merge bitcoin/bitcoin#32750: refactor: CFeeRate encapsulates FeeFrac internally

d3b8a54a81 Refactor CFeeRate to use FeeFrac internally (Pol Espinasa)

Pull request description:

  The `FeeFrac` type represents a fraction, intended to be used for `sats/vbyte` or `sats/WU`. It was added to improve accuracy when evaluating fee rates in cluster mempool. [1]
  But it can also be used to fix the precision issues that the current `CFeeRate` class has now.

  At the moment, `CFeeRate` handles the fee rate as  satoshis per kilovirtualbyte: `CAmount / kvB` using an integer.
  This PR fix `CFeeRate` precision issues by encapsulating `FeeFrac` internally keeping backwards compatibility.

  This PR can also be used as a based to use multiple units on RPC calls as detailed in this issue [2].

  Some previous discussions:
  [1] https://github.com/bitcoin/bitcoin/pull/30535
  [2] https://github.com/bitcoin/bitcoin/issues/32093

ACKs for top commit:
  achow101:
    ACK d3b8a54a81
  murchandamus:
    code review, lightly tested ACK d3b8a54a81
  ismaelsadeeq:
    re-ACK d3b8a54a81 📦
  theStack:
    Code-review ACK d3b8a54a81

Tree-SHA512: 5a8149d81e82ad4e60a0e76ff6a82a5b1c4e212cf5156c1cdd16bf9acbb351e7be458eac3f0a2ae89107f331062b299c1d9ca649d3b820ad0b68e6d1a14292e5
This commit is contained in:
Ava Chow
2025-08-08 18:11:05 -07:00
11 changed files with 66 additions and 65 deletions

View File

@@ -1406,7 +1406,7 @@ bool MemPoolAccept::SubmitPackage(const ATMPArgs& args, std::vector<Workspace>&
auto iter = m_pool.GetIter(ws.m_ptx->GetHash());
Assume(iter.has_value());
const auto effective_feerate = args.m_package_feerates ? ws.m_package_feerate :
CFeeRate{ws.m_modified_fees, static_cast<uint32_t>(ws.m_vsize)};
CFeeRate{ws.m_modified_fees, static_cast<int32_t>(ws.m_vsize)};
const auto effective_feerate_wtxids = args.m_package_feerates ? all_package_wtxids :
std::vector<Wtxid>{ws.m_ptx->GetWitnessHash()};
results.emplace(ws.m_ptx->GetWitnessHash(),
@@ -1470,7 +1470,7 @@ MempoolAcceptResult MemPoolAccept::AcceptSingleTransaction(const CTransactionRef
if (!ConsensusScriptChecks(args, ws)) return MempoolAcceptResult::Failure(ws.m_state);
const CFeeRate effective_feerate{ws.m_modified_fees, static_cast<uint32_t>(ws.m_vsize)};
const CFeeRate effective_feerate{ws.m_modified_fees, static_cast<int32_t>(ws.m_vsize)};
// Tx was accepted, but not added
if (args.m_test_accept) {
return MempoolAcceptResult::Success(std::move(m_subpackage.m_replaced_transactions), ws.m_vsize,
@@ -1626,7 +1626,7 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptMultipleTransactions(const std::
}
if (args.m_test_accept) {
const auto effective_feerate = args.m_package_feerates ? ws.m_package_feerate :
CFeeRate{ws.m_modified_fees, static_cast<uint32_t>(ws.m_vsize)};
CFeeRate{ws.m_modified_fees, static_cast<int32_t>(ws.m_vsize)};
const auto effective_feerate_wtxids = args.m_package_feerates ? all_package_wtxids :
std::vector<Wtxid>{ws.m_ptx->GetWitnessHash()};
results.emplace(ws.m_ptx->GetWitnessHash(),