Skip to content

Commit 7cd4159

Browse files
committed
[net processing] Add Peer
Peer is a struct for holding per-peer data. This structure is not protected by cs_main since it does not contain validation-critical data.
1 parent aba0335 commit 7cd4159

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

src/net_processing.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,43 @@ static CNodeState *State(NodeId pnode) EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
471471
return &it->second;
472472
}
473473

474+
/**
475+
* Data structure for an individual peer. This struct is not protected by
476+
* cs_main since it does not contain validation-critical data.
477+
*
478+
* Memory is owned by shared pointers and this object is destructed when
479+
* the refcount drops to zero.
480+
*
481+
* TODO: move most members from CNodeState to this structure.
482+
* TODO: move remaining application-layer data members from CNode to this structure.
483+
*/
484+
struct Peer {
485+
/** Same id as the CNode object for this peer */
486+
const NodeId m_id{0};
487+
488+
Peer(NodeId id) : m_id(id) {}
489+
};
490+
491+
using PeerRef = std::shared_ptr<Peer>;
492+
493+
/**
494+
* Map of all Peer objects, keyed by peer id. This map is protected
495+
* by the global g_peer_mutex. Once a shared pointer reference is
496+
* taken, the lock may be released. Individual fields are protected by
497+
* their own locks.
498+
*/
499+
Mutex g_peer_mutex;
500+
static std::map<NodeId, PeerRef> g_peer_map GUARDED_BY(g_peer_mutex);
501+
502+
/** Get a shared pointer to the Peer object.
503+
* May return nullptr if the Peer object can't be found. */
504+
static PeerRef GetPeerRef(NodeId id)
505+
{
506+
LOCK(g_peer_mutex);
507+
auto it = g_peer_map.find(id);
508+
return it != g_peer_map.end() ? it->second : nullptr;
509+
}
510+
474511
static void UpdatePreferredDownload(const CNode& node, CNodeState* state) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
475512
{
476513
nPreferredDownload -= state->fPreferredDownload;
@@ -838,6 +875,11 @@ void PeerLogicValidation::InitializeNode(CNode *pnode) {
838875
LOCK(cs_main);
839876
mapNodeState.emplace_hint(mapNodeState.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple(addr, pnode->IsInboundConn(), pnode->IsManualConn()));
840877
}
878+
{
879+
PeerRef peer = std::make_shared<Peer>(nodeid);
880+
LOCK(g_peer_mutex);
881+
g_peer_map.emplace_hint(g_peer_map.end(), nodeid, std::move(peer));
882+
}
841883
if(!pnode->IsInboundConn())
842884
PushNodeVersion(*pnode, *connman, GetTime());
843885
}
@@ -865,6 +907,10 @@ void PeerLogicValidation::ReattemptInitialBroadcast(CScheduler& scheduler) const
865907
void PeerLogicValidation::FinalizeNode(NodeId nodeid, bool& fUpdateConnectionTime) {
866908
fUpdateConnectionTime = false;
867909
LOCK(cs_main);
910+
{
911+
LOCK(g_peer_mutex);
912+
g_peer_map.erase(nodeid);
913+
}
868914
CNodeState *state = State(nodeid);
869915
assert(state != nullptr);
870916

0 commit comments

Comments
 (0)