Skip to content

Commit

Permalink
doc: add comments clarifying how local services are advertised
Browse files Browse the repository at this point in the history
Recent questions have come up regarding dynamic service registration
(see bitcoin#16442 (comment)
and the assumeutxo project, which needs to dynamically flip NODE_NETWORK).

While investigating how dynamic service registration might work, I was
confused about how we convey local services to peers. This adds some
documentation that hopefully clarifies this process.
  • Loading branch information
jamesob authored and PierreRochard committed Oct 12, 2019
1 parent 48c7c8a commit 2abefd3
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 2 deletions.
37 changes: 35 additions & 2 deletions src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,12 @@ class CConnman
bool DisconnectNode(const CNetAddr& addr);
bool DisconnectNode(NodeId id);

//! Used to convey which local services we are offering peers during node
//! connection.
//!
//! The data returned by this is used in CNode construction,
//! which is used to advertise which services we are offering
//! that peer during `net_processing.cpp:PushNodeVersion()`.
ServiceFlags GetLocalServices() const;

//!set the max outbound target in bytes
Expand Down Expand Up @@ -413,7 +419,18 @@ class CConnman
std::atomic<NodeId> nLastNodeId{0};
unsigned int nPrevNodeCount{0};

/** Services this instance offers */
/**
* Services this instance offers.
*
* This data is replicated in each CNode instance we create during peer
* connection (in ConnectNode()) under a member also called
* nLocalServices.
*
* This data is not marked const, but after being set it should not
* change. See the note in CNode::nLocalServices documentation.
*
* \sa CNode::nLocalServices
*/
ServiceFlags nLocalServices;

std::unique_ptr<CSemaphore> semOutbound;
Expand Down Expand Up @@ -786,8 +803,24 @@ class CNode
private:
const NodeId id;
const uint64_t nLocalHostNonce;
// Services offered to this peer

//! Services offered to this peer.
//!
//! This is supplied by the parent CConnman during peer connection
//! (CConnman::ConnectNode()) from its attribute of the same name.
//!
//! This is const because there is no protocol defined for renegotiating
//! services initially offered to a peer. The set of local services we
//! offer should not change after initialization.
//!
//! An interesting example of this is NODE_NETWORK and initial block
//! download: a node which starts up from scratch doesn't have any blocks
//! to serve, but still advertises NODE_NETWORK because it will eventually
//! fulfill this role after IBD completes. P2P code is written in such a
//! way that it can gracefully handle peers who don't make good on their
//! service advertisements.
const ServiceFlags nLocalServices;

const int nMyStartingHeight;
int nSendVersion{0};
NetPermissionFlags m_permissionFlags{ PF_NONE };
Expand Down
3 changes: 3 additions & 0 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,9 @@ static void UpdatePreferredDownload(CNode* node, CNodeState* state) EXCLUSIVE_LO

static void PushNodeVersion(CNode *pnode, CConnman* connman, int64_t nTime)
{
// Note that pnode->GetLocalServices() is a reflection of the local
// services we were offering when the CNode object was created for this
// peer.
ServiceFlags nLocalNodeServices = pnode->GetLocalServices();
uint64_t nonce = pnode->GetLocalNonce();
int nNodeStartingHeight = pnode->GetMyStartingHeight();
Expand Down

0 comments on commit 2abefd3

Please sign in to comment.