diff options
author | John Newbery <john@johnnewbery.com> | 2020-06-16 15:14:45 -0400 |
---|---|---|
committer | John Newbery <john@johnnewbery.com> | 2020-08-12 11:22:44 +0100 |
commit | 7cd4159ac834432dadd60a5e8ee817f3cadbee55 (patch) | |
tree | 0f6eeb9af17d21c06c17e37245072e2c47ca6edf /src | |
parent | aba03359a6e62a376ae44914f609f82a1556fc89 (diff) |
[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.
Diffstat (limited to 'src')
-rw-r--r-- | src/net_processing.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 9b40f26a80..4421ec9314 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -471,6 +471,43 @@ static CNodeState *State(NodeId pnode) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { return &it->second; } +/** + * Data structure for an individual peer. This struct is not protected by + * cs_main since it does not contain validation-critical data. + * + * Memory is owned by shared pointers and this object is destructed when + * the refcount drops to zero. + * + * TODO: move most members from CNodeState to this structure. + * TODO: move remaining application-layer data members from CNode to this structure. + */ +struct Peer { + /** Same id as the CNode object for this peer */ + const NodeId m_id{0}; + + Peer(NodeId id) : m_id(id) {} +}; + +using PeerRef = std::shared_ptr<Peer>; + +/** + * Map of all Peer objects, keyed by peer id. This map is protected + * by the global g_peer_mutex. Once a shared pointer reference is + * taken, the lock may be released. Individual fields are protected by + * their own locks. + */ +Mutex g_peer_mutex; +static std::map<NodeId, PeerRef> g_peer_map GUARDED_BY(g_peer_mutex); + +/** Get a shared pointer to the Peer object. + * May return nullptr if the Peer object can't be found. */ +static PeerRef GetPeerRef(NodeId id) +{ + LOCK(g_peer_mutex); + auto it = g_peer_map.find(id); + return it != g_peer_map.end() ? it->second : nullptr; +} + static void UpdatePreferredDownload(const CNode& node, CNodeState* state) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { nPreferredDownload -= state->fPreferredDownload; @@ -838,6 +875,11 @@ void PeerLogicValidation::InitializeNode(CNode *pnode) { LOCK(cs_main); mapNodeState.emplace_hint(mapNodeState.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple(addr, pnode->IsInboundConn(), pnode->IsManualConn())); } + { + PeerRef peer = std::make_shared<Peer>(nodeid); + LOCK(g_peer_mutex); + g_peer_map.emplace_hint(g_peer_map.end(), nodeid, std::move(peer)); + } if(!pnode->IsInboundConn()) PushNodeVersion(*pnode, *connman, GetTime()); } @@ -865,6 +907,10 @@ void PeerLogicValidation::ReattemptInitialBroadcast(CScheduler& scheduler) const void PeerLogicValidation::FinalizeNode(NodeId nodeid, bool& fUpdateConnectionTime) { fUpdateConnectionTime = false; LOCK(cs_main); + { + LOCK(g_peer_mutex); + g_peer_map.erase(nodeid); + } CNodeState *state = State(nodeid); assert(state != nullptr); |