diff --git a/src/txrequest.h b/src/txrequest.h --- a/src/txrequest.h +++ b/src/txrequest.h @@ -117,10 +117,48 @@ * announcements, plus the number of announcements affected by an operation * (amortized O(1) per announcement). */ + +// Avoid littering this header file with implementation details. +class InvRequestTrackerImplInterface { + friend class TxRequestTracker; + + // The base class is responsible for building the child implementation. + // This is a hack that allows for hiding the concrete implementation details + // from the callsite. + static std::unique_ptr + BuildImpl(bool deterministic); + +public: + using ClearExpiredFun = const std::function &; + using EmplaceExpiredFun = + const std::function &; + + virtual ~InvRequestTrackerImplInterface() = default; + + virtual void ReceivedInv(NodeId peer, const uint256 &txid, bool preferred, + std::chrono::microseconds reqtime) = 0; + virtual void DisconnectedPeer(NodeId peer) = 0; + virtual void ForgetTxId(const uint256 &txid) = 0; + virtual std::vector + GetRequestable(NodeId peer, std::chrono::microseconds now, + ClearExpiredFun clearExpired, + EmplaceExpiredFun emplaceExpired) = 0; + virtual void RequestedTx(NodeId peer, const uint256 &txid, + std::chrono::microseconds expiry) = 0; + virtual void ReceivedResponse(NodeId peer, const uint256 &txid) = 0; + virtual size_t CountInFlight(NodeId peer) const = 0; + virtual size_t CountCandidates(NodeId peer) const = 0; + virtual size_t Count(NodeId peer) const = 0; + virtual size_t Size() const = 0; + virtual uint64_t ComputePriority(const uint256 &txid, NodeId peer, + bool preferred) const = 0; + virtual void SanityCheck() const = 0; + virtual void + PostGetRequestableSanityCheck(std::chrono::microseconds now) const = 0; +}; + class TxRequestTracker { - // Avoid littering this header file with implementation details. - class Impl; - const std::unique_ptr m_impl; + const std::unique_ptr m_impl; public: //! Construct a TxRequestTracker. diff --git a/src/txrequest.cpp b/src/txrequest.cpp --- a/src/txrequest.cpp +++ b/src/txrequest.cpp @@ -351,14 +351,10 @@ return ret; } -using clearExpiredFun = const std::function &; -using emplaceExpiredFun = - const std::function &; - } // namespace /** Actual implementation for TxRequestTracker's data structure. */ -class TxRequestTracker::Impl { +class InvRequestTrackerImpl : public InvRequestTrackerImplInterface { //! The current sequence number. Increases for every announcement. This is //! used to sort txid returned by GetRequestable in announcement order. SequenceNumber m_current_sequence{0}; @@ -587,8 +583,8 @@ //! - CANDIDATE_{READY,BEST} announcements with reqtime > now are turned //! into CANDIDATE_DELAYED. void SetTimePoint(std::chrono::microseconds now, - clearExpiredFun clearExpired, - emplaceExpiredFun emplaceExpired) { + ClearExpiredFun clearExpired, + EmplaceExpiredFun emplaceExpired) { clearExpired(); // Iterate over all CANDIDATE_DELAYED and REQUESTED from old to new, as // long as they're in the past, and convert them to CANDIDATE_READY and @@ -624,7 +620,7 @@ } public: - Impl(bool deterministic) + InvRequestTrackerImpl(bool deterministic) : m_computer(deterministic), // Explicitly initialize m_index as we need to pass a reference to // m_computer to ByTxHashViewExtractor. @@ -637,8 +633,10 @@ // Disable copying and assigning (a default copy won't work due the stateful // ByTxIdViewExtractor). - Impl(const Impl &) = delete; - Impl &operator=(const Impl &) = delete; + InvRequestTrackerImpl(const InvRequestTrackerImpl &) = delete; + InvRequestTrackerImpl &operator=(const InvRequestTrackerImpl &) = delete; + + ~InvRequestTrackerImpl() = default; void DisconnectedPeer(NodeId peer) { auto &index = m_index.get(); @@ -719,8 +717,8 @@ //! Find the TxIds to request now from peer. std::vector GetRequestable(NodeId peer, std::chrono::microseconds now, - clearExpiredFun clearExpired, - emplaceExpiredFun emplaceExpired) { + ClearExpiredFun clearExpired, + EmplaceExpiredFun emplaceExpired) { // Move time. SetTimePoint(now, clearExpired, emplaceExpired); @@ -861,8 +859,13 @@ } }; +std::unique_ptr +InvRequestTrackerImplInterface::BuildImpl(bool deterministic) { + return std::make_unique(deterministic); +} + TxRequestTracker::TxRequestTracker(bool deterministic) - : m_impl{std::make_unique(deterministic)} {} + : m_impl{InvRequestTrackerImplInterface::BuildImpl(deterministic)} {} TxRequestTracker::~TxRequestTracker() = default; @@ -911,17 +914,17 @@ std::vector TxRequestTracker::GetRequestable( NodeId peer, std::chrono::microseconds now, std::vector> *expired) { - clearExpiredFun clearExpired = [expired]() { + InvRequestTrackerImplInterface::ClearExpiredFun clearExpired = [expired]() { if (expired) { expired->clear(); } }; - emplaceExpiredFun emplaceExpired = [expired](const NodeId &nodeid, - const uint256 &txid) { - if (expired) { - expired->emplace_back(nodeid, TxId(txid)); - } - }; + InvRequestTrackerImplInterface::EmplaceExpiredFun emplaceExpired = + [expired](const NodeId &nodeid, const uint256 &txid) { + if (expired) { + expired->emplace_back(nodeid, TxId(txid)); + } + }; std::vector hashes = m_impl->GetRequestable(peer, now, clearExpired, emplaceExpired); return std::vector(hashes.begin(), hashes.end());