Bitcoin ABC 0.30.3
P2P Digital Currency
|
Data structure to keep track of, and schedule, inventory downloads from peers. More...
#include <invrequest.h>
Public Types | |
using | ClearExpiredFun = const std::function< void()> & |
using | EmplaceExpiredFun = const std::function< void(const NodeId &, const uint256 &)> & |
Public Member Functions | |
virtual | ~InvRequestTrackerImplInterface ()=default |
virtual void | ReceivedInv (NodeId peer, const uint256 &invid, bool preferred, std::chrono::microseconds reqtime)=0 |
virtual void | DisconnectedPeer (NodeId peer)=0 |
virtual void | ForgetInvId (const uint256 &invid)=0 |
virtual std::vector< uint256 > | GetRequestable (NodeId peer, std::chrono::microseconds now, ClearExpiredFun clearExpired, EmplaceExpiredFun emplaceExpired)=0 |
virtual void | RequestedData (NodeId peer, const uint256 &invid, std::chrono::microseconds expiry)=0 |
virtual void | ReceivedResponse (NodeId peer, const uint256 &invid)=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 &invid, NodeId peer, bool preferred) const =0 |
virtual void | SanityCheck () const =0 |
virtual void | PostGetRequestableSanityCheck (std::chrono::microseconds now) const =0 |
Static Private Member Functions | |
static std::unique_ptr< InvRequestTrackerImplInterface > | BuildImpl (bool deterministic) |
Friends | |
template<class InvId > | |
class | InvRequestTracker |
Data structure to keep track of, and schedule, inventory downloads from peers.
=== Specification ===
We keep track of which peers have announced which inventories, and use that to determine which requests should go to which peer, when, and in what order.
The following information is tracked per peer/inv combination ("announcement"):
Transaction requests are then assigned to peers, following these rules:
No inventory is requested as long as another request for the same invid is outstanding (it needs to fail first by passing expiry, or a NOTFOUND or invalid inventory has to be received for it).
Rationale: to avoid wasting bandwidth on multiple copies of the same inventory.
The same inventory is never requested twice from the same peer, unless the announcement was forgotten in between, and re-announced. Announcements are forgotten only:
Rationale: giving a peer multiple chances to announce an inventory would allow them to bias requests in their favor, worsening inventory censoring attacks. The flip side is that as long as an attacker manages to prevent us from receiving an inventory, failed announcements (including those from honest peers) will linger longer, increasing memory usage somewhat. The impact of this is limited by imposing a cap on the number of tracked announcements per peer. As failed requests in response to announcements from honest peers should be rare, this almost solely hinders attackers. Transaction censoring attacks can be done by announcing inventories quickly while not answering requests for them. See https://allquantor.at/blockchainbib/pdf/miller2015topology.pdf for more information.
Transactions are not requested from a peer until its reqtime has passed.
Rationale: enable the calling code to define a delay for less-than-ideal peers, so that (presumed) better peers have a chance to give their announcement first.
If any preferred peers are available, non-preferred peers are not considered for what follows.
Rationale: preferred peers are more trusted by us, so are less likely to be under attacker control.
Pick a uniformly random peer among the candidates.
Rationale: random assignments are hard to influence for attackers.
Together these rules strike a balance between being fast in non-adverserial conditions and minimizing susceptibility to censorship attacks. An attacker that races the network:
Complexity:
Definition at line 121 of file invrequest.h.
using InvRequestTrackerImplInterface::ClearExpiredFun = const std::function<void()> & |
Definition at line 131 of file invrequest.h.
using InvRequestTrackerImplInterface::EmplaceExpiredFun = const std::function<void(const NodeId &, const uint256 &)> & |
Definition at line 132 of file invrequest.h.
|
virtualdefault |
|
staticprivate |
Definition at line 863 of file invrequest.cpp.
|
pure virtual |
Implemented in InvRequestTrackerImpl.
|
pure virtual |
Implemented in InvRequestTrackerImpl.
|
pure virtual |
Implemented in InvRequestTrackerImpl.
|
pure virtual |
Implemented in InvRequestTrackerImpl.
|
pure virtual |
Implemented in InvRequestTrackerImpl.
|
pure virtual |
Implemented in InvRequestTrackerImpl.
|
pure virtual |
Implemented in InvRequestTrackerImpl.
|
pure virtual |
Implemented in InvRequestTrackerImpl.
|
pure virtual |
Implemented in InvRequestTrackerImpl.
|
pure virtual |
Implemented in InvRequestTrackerImpl.
|
pure virtual |
Implemented in InvRequestTrackerImpl.
|
pure virtual |
Implemented in InvRequestTrackerImpl.
|
pure virtual |
Implemented in InvRequestTrackerImpl.
|
friend |
Definition at line 122 of file invrequest.h.