Changeset View
Changeset View
Standalone View
Standalone View
src/txrequest.cpp
Show First 20 Lines • Show All 345 Lines • ▼ Show 20 Lines | for (const Announcement &ann : index) { | ||||
} | } | ||||
// Also keep track of which peers this txid has an announcement for | // Also keep track of which peers this txid has an announcement for | ||||
// (so we can detect duplicates). | // (so we can detect duplicates). | ||||
info.m_peers.push_back(ann.m_peer); | info.m_peers.push_back(ann.m_peer); | ||||
} | } | ||||
return ret; | return ret; | ||||
} | } | ||||
using clearExpiredFun = const std::function<void()> &; | |||||
using emplaceExpiredFun = | |||||
const std::function<void(const NodeId &, const uint256 &)> &; | |||||
} // namespace | } // namespace | ||||
/** Actual implementation for TxRequestTracker's data structure. */ | /** Actual implementation for TxRequestTracker's data structure. */ | ||||
class TxRequestTracker::Impl { | class ImplConcrete : public Impl { | ||||
deadalnixUnsubmitted Not Done Inline Actionsdeadalnix: implconcrete | |||||
//! The current sequence number. Increases for every announcement. This is | //! The current sequence number. Increases for every announcement. This is | ||||
//! used to sort txid returned by GetRequestable in announcement order. | //! used to sort txid returned by GetRequestable in announcement order. | ||||
SequenceNumber m_current_sequence{0}; | SequenceNumber m_current_sequence{0}; | ||||
//! This tracker's priority computer. | //! This tracker's priority computer. | ||||
const PriorityComputer m_computer; | const PriorityComputer m_computer; | ||||
//! This tracker's main data structure. See SanityCheck() for the invariants | //! This tracker's main data structure. See SanityCheck() for the invariants | ||||
▲ Show 20 Lines • Show All 249 Lines • ▼ Show 20 Lines | void SetTimePoint(std::chrono::microseconds now, | ||||
State::CANDIDATE_DELAYED); | State::CANDIDATE_DELAYED); | ||||
} else { | } else { | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
public: | public: | ||||
Impl(bool deterministic) | ImplConcrete(bool deterministic) | ||||
: m_computer(deterministic), | : m_computer(deterministic), | ||||
// Explicitly initialize m_index as we need to pass a reference to | // Explicitly initialize m_index as we need to pass a reference to | ||||
// m_computer to ByTxHashViewExtractor. | // m_computer to ByTxHashViewExtractor. | ||||
m_index(boost::make_tuple( | m_index(boost::make_tuple( | ||||
boost::make_tuple(ByPeerViewExtractor(), std::less<ByPeerView>()), | boost::make_tuple(ByPeerViewExtractor(), std::less<ByPeerView>()), | ||||
boost::make_tuple(ByTxIdViewExtractor(m_computer), | boost::make_tuple(ByTxIdViewExtractor(m_computer), | ||||
std::less<ByTxIdView>()), | std::less<ByTxIdView>()), | ||||
boost::make_tuple(ByTimeViewExtractor(), | boost::make_tuple(ByTimeViewExtractor(), | ||||
std::less<ByTimeView>()))) {} | std::less<ByTimeView>()))) {} | ||||
// Disable copying and assigning (a default copy won't work due the stateful | // Disable copying and assigning (a default copy won't work due the stateful | ||||
// ByTxIdViewExtractor). | // ByTxIdViewExtractor). | ||||
Impl(const Impl &) = delete; | ImplConcrete(const ImplConcrete &) = delete; | ||||
Impl &operator=(const Impl &) = delete; | ImplConcrete &operator=(const ImplConcrete &) = delete; | ||||
void DisconnectedPeer(NodeId peer) { | void DisconnectedPeer(NodeId peer) { | ||||
auto &index = m_index.get<ByPeer>(); | auto &index = m_index.get<ByPeer>(); | ||||
auto it = | auto it = | ||||
index.lower_bound(ByPeerView{peer, false, uint256(uint256::ZERO)}); | index.lower_bound(ByPeerView{peer, false, uint256(uint256::ZERO)}); | ||||
while (it != index.end() && it->m_peer == peer) { | while (it != index.end() && it->m_peer == peer) { | ||||
// Check what to continue with after this iteration. 'it' will be | // Check what to continue with after this iteration. 'it' will be | ||||
// deleted in what follows, so we need to decide what to continue | // deleted in what follows, so we need to decide what to continue | ||||
▲ Show 20 Lines • Show All 206 Lines • ▼ Show 20 Lines | public: | ||||
uint64_t ComputePriority(const uint256 &txid, NodeId peer, | uint64_t ComputePriority(const uint256 &txid, NodeId peer, | ||||
bool preferred) const { | bool preferred) const { | ||||
// Return Priority as a uint64_t as Priority is internal. | // Return Priority as a uint64_t as Priority is internal. | ||||
return uint64_t{m_computer(txid, peer, preferred)}; | return uint64_t{m_computer(txid, peer, preferred)}; | ||||
} | } | ||||
}; | }; | ||||
std::unique_ptr<Impl> Impl::BuildImpl(bool deterministic) { | |||||
return std::unique_ptr<Impl>(new ImplConcrete(deterministic)); | |||||
deadalnixUnsubmitted Not Done Inline ActionsWhy not use make_unique ? deadalnix: Why not use make_unique ? | |||||
FabienAuthorUnsubmitted Done Inline Actionsmake_unique cannot return a unique_ptr of <Impl> by building an ImplConcrete due to the way the template is defined Fabien: make_unique cannot return a unique_ptr of <Impl> by building an ImplConcrete due to the way the… | |||||
deadalnixUnsubmitted Not Done Inline Actionsdeadalnix: So?
https://godbolt.org/z/hGo51shnd
Unless I missed something, it works. | |||||
FabienAuthorUnsubmitted Done Inline ActionsOK, no idea what I did to get a compiler error but I can't reproduce anymore so clearly I did something wrong. Will update. Fabien: OK, no idea what I did to get a compiler error but I can't reproduce anymore so clearly I did… | |||||
} | |||||
TxRequestTracker::TxRequestTracker(bool deterministic) | TxRequestTracker::TxRequestTracker(bool deterministic) | ||||
: m_impl{std::make_unique<TxRequestTracker::Impl>(deterministic)} {} | : m_impl{Impl::BuildImpl(deterministic)} {} | ||||
TxRequestTracker::~TxRequestTracker() = default; | TxRequestTracker::~TxRequestTracker() = default; | ||||
void TxRequestTracker::ForgetTxId(const TxId &txid) { | void TxRequestTracker::ForgetTxId(const TxId &txid) { | ||||
m_impl->ForgetTxId(txid); | m_impl->ForgetTxId(txid); | ||||
} | } | ||||
void TxRequestTracker::DisconnectedPeer(NodeId peer) { | void TxRequestTracker::DisconnectedPeer(NodeId peer) { | ||||
m_impl->DisconnectedPeer(peer); | m_impl->DisconnectedPeer(peer); | ||||
Show All 32 Lines | |||||
void TxRequestTracker::ReceivedResponse(NodeId peer, const TxId &txid) { | void TxRequestTracker::ReceivedResponse(NodeId peer, const TxId &txid) { | ||||
m_impl->ReceivedResponse(peer, txid); | m_impl->ReceivedResponse(peer, txid); | ||||
} | } | ||||
std::vector<TxId> TxRequestTracker::GetRequestable( | std::vector<TxId> TxRequestTracker::GetRequestable( | ||||
NodeId peer, std::chrono::microseconds now, | NodeId peer, std::chrono::microseconds now, | ||||
std::vector<std::pair<NodeId, TxId>> *expired) { | std::vector<std::pair<NodeId, TxId>> *expired) { | ||||
clearExpiredFun clearExpired = [expired]() { | Impl::clearExpiredFun clearExpired = [expired]() { | ||||
deadalnixUnsubmitted Not Done Inline ActionsYou made those protected, it doesn't seem to make a lot of sens to use them in this way. deadalnix: You made those protected, it doesn't seem to make a lot of sens to use them in this way. | |||||
if (expired) { | if (expired) { | ||||
expired->clear(); | expired->clear(); | ||||
} | } | ||||
}; | }; | ||||
emplaceExpiredFun emplaceExpired = [expired](const NodeId &nodeid, | Impl::emplaceExpiredFun emplaceExpired = [expired](const NodeId &nodeid, | ||||
const uint256 &txid) { | const uint256 &txid) { | ||||
if (expired) { | if (expired) { | ||||
expired->emplace_back(nodeid, TxId(txid)); | expired->emplace_back(nodeid, TxId(txid)); | ||||
} | } | ||||
}; | }; | ||||
std::vector<uint256> hashes = | std::vector<uint256> hashes = | ||||
m_impl->GetRequestable(peer, now, clearExpired, emplaceExpired); | m_impl->GetRequestable(peer, now, clearExpired, emplaceExpired); | ||||
return std::vector<TxId>(hashes.begin(), hashes.end()); | return std::vector<TxId>(hashes.begin(), hashes.end()); | ||||
} | } | ||||
uint64_t TxRequestTracker::ComputePriority(const TxId &txid, NodeId peer, | uint64_t TxRequestTracker::ComputePriority(const TxId &txid, NodeId peer, | ||||
bool preferred) const { | bool preferred) const { | ||||
return m_impl->ComputePriority(txid, peer, preferred); | return m_impl->ComputePriority(txid, peer, preferred); | ||||
} | } |