aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Newbery <john@johnnewbery.com>2020-06-16 15:14:45 -0400
committerJohn Newbery <john@johnnewbery.com>2020-08-12 11:22:44 +0100
commit7cd4159ac834432dadd60a5e8ee817f3cadbee55 (patch)
tree0f6eeb9af17d21c06c17e37245072e2c47ca6edf /src
parentaba03359a6e62a376ae44914f609f82a1556fc89 (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.cpp46
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);