mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-03-06 14:19:59 -05:00
[net processing] Add m_our_services and m_their_services to Peer
Track services offered by us and the peer in the Peer object.
This commit is contained in:
parent
31c6309cc6
commit
1f52c47d5c
6 changed files with 42 additions and 33 deletions
|
@ -1026,7 +1026,7 @@ void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr<Sock>&& sock,
|
||||||
pnode->AddRef();
|
pnode->AddRef();
|
||||||
pnode->m_permissionFlags = permissionFlags;
|
pnode->m_permissionFlags = permissionFlags;
|
||||||
pnode->m_prefer_evict = discouraged;
|
pnode->m_prefer_evict = discouraged;
|
||||||
m_msgproc->InitializeNode(pnode);
|
m_msgproc->InitializeNode(*pnode, nodeServices);
|
||||||
|
|
||||||
LogPrint(BCLog::NET, "connection from %s accepted\n", addr.ToString());
|
LogPrint(BCLog::NET, "connection from %s accepted\n", addr.ToString());
|
||||||
|
|
||||||
|
@ -1964,7 +1964,7 @@ void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai
|
||||||
if (grantOutbound)
|
if (grantOutbound)
|
||||||
grantOutbound->MoveTo(pnode->grantOutbound);
|
grantOutbound->MoveTo(pnode->grantOutbound);
|
||||||
|
|
||||||
m_msgproc->InitializeNode(pnode);
|
m_msgproc->InitializeNode(*pnode, nLocalServices);
|
||||||
{
|
{
|
||||||
LOCK(m_nodes_mutex);
|
LOCK(m_nodes_mutex);
|
||||||
m_nodes.push_back(pnode);
|
m_nodes.push_back(pnode);
|
||||||
|
|
16
src/net.h
16
src/net.h
|
@ -592,20 +592,6 @@ private:
|
||||||
std::atomic<int> m_greatest_common_version{INIT_PROTO_VERSION};
|
std::atomic<int> m_greatest_common_version{INIT_PROTO_VERSION};
|
||||||
|
|
||||||
//! 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 ServiceFlags nLocalServices;
|
||||||
|
|
||||||
std::list<CNetMessage> vRecvMsg; // Used only by SocketHandler thread
|
std::list<CNetMessage> vRecvMsg; // Used only by SocketHandler thread
|
||||||
|
@ -625,7 +611,7 @@ class NetEventsInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** Initialize a peer (setup state, queue any initial messages) */
|
/** Initialize a peer (setup state, queue any initial messages) */
|
||||||
virtual void InitializeNode(CNode* pnode) = 0;
|
virtual void InitializeNode(CNode& node, ServiceFlags our_services) = 0;
|
||||||
|
|
||||||
/** Handle removal of a peer (clear state) */
|
/** Handle removal of a peer (clear state) */
|
||||||
virtual void FinalizeNode(const CNode& node) = 0;
|
virtual void FinalizeNode(const CNode& node) = 0;
|
||||||
|
|
|
@ -207,6 +207,27 @@ struct Peer {
|
||||||
/** Same id as the CNode object for this peer */
|
/** Same id as the CNode object for this peer */
|
||||||
const NodeId m_id{0};
|
const NodeId m_id{0};
|
||||||
|
|
||||||
|
/** Services we offered to this peer.
|
||||||
|
*
|
||||||
|
* This is supplied by CConnman during peer initialization. It's 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.
|
||||||
|
*
|
||||||
|
* TODO: remove redundant CNode::nLocalServices*/
|
||||||
|
const ServiceFlags m_our_services;
|
||||||
|
/** Services this peer offered to us.
|
||||||
|
*
|
||||||
|
* TODO: remove redundant CNode::nServices */
|
||||||
|
std::atomic<ServiceFlags> m_their_services{NODE_NONE};
|
||||||
|
|
||||||
/** Protects misbehavior data members */
|
/** Protects misbehavior data members */
|
||||||
Mutex m_misbehavior_mutex;
|
Mutex m_misbehavior_mutex;
|
||||||
/** Accumulated misbehavior score for this peer */
|
/** Accumulated misbehavior score for this peer */
|
||||||
|
@ -360,8 +381,9 @@ struct Peer {
|
||||||
/** Time of the last getheaders message to this peer */
|
/** Time of the last getheaders message to this peer */
|
||||||
std::atomic<NodeClock::time_point> m_last_getheaders_timestamp{NodeSeconds{}};
|
std::atomic<NodeClock::time_point> m_last_getheaders_timestamp{NodeSeconds{}};
|
||||||
|
|
||||||
Peer(NodeId id)
|
explicit Peer(NodeId id, ServiceFlags our_services)
|
||||||
: m_id{id}
|
: m_id{id}
|
||||||
|
, m_our_services{our_services}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -482,7 +504,7 @@ public:
|
||||||
EXCLUSIVE_LOCKS_REQUIRED(!m_most_recent_block_mutex);
|
EXCLUSIVE_LOCKS_REQUIRED(!m_most_recent_block_mutex);
|
||||||
|
|
||||||
/** Implement NetEventsInterface */
|
/** Implement NetEventsInterface */
|
||||||
void InitializeNode(CNode* pnode) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
|
void InitializeNode(CNode& node, ServiceFlags our_services) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
|
||||||
void FinalizeNode(const CNode& node) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
|
void FinalizeNode(const CNode& node) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
|
||||||
bool ProcessMessages(CNode* pfrom, std::atomic<bool>& interrupt) override
|
bool ProcessMessages(CNode* pfrom, std::atomic<bool>& interrupt) override
|
||||||
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !m_recent_confirmed_transactions_mutex, !m_most_recent_block_mutex);
|
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !m_recent_confirmed_transactions_mutex, !m_most_recent_block_mutex);
|
||||||
|
@ -1299,21 +1321,21 @@ void PeerManagerImpl::UpdateLastBlockAnnounceTime(NodeId node, int64_t time_in_s
|
||||||
if (state) state->m_last_block_announcement = time_in_seconds;
|
if (state) state->m_last_block_announcement = time_in_seconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerManagerImpl::InitializeNode(CNode *pnode)
|
void PeerManagerImpl::InitializeNode(CNode& node, ServiceFlags our_services)
|
||||||
{
|
{
|
||||||
NodeId nodeid = pnode->GetId();
|
NodeId nodeid = node.GetId();
|
||||||
{
|
{
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
m_node_states.emplace_hint(m_node_states.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple(pnode->IsInboundConn()));
|
m_node_states.emplace_hint(m_node_states.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple(node.IsInboundConn()));
|
||||||
assert(m_txrequest.Count(nodeid) == 0);
|
assert(m_txrequest.Count(nodeid) == 0);
|
||||||
}
|
}
|
||||||
PeerRef peer = std::make_shared<Peer>(nodeid);
|
PeerRef peer = std::make_shared<Peer>(nodeid, our_services);
|
||||||
{
|
{
|
||||||
LOCK(m_peer_mutex);
|
LOCK(m_peer_mutex);
|
||||||
m_peer_map.emplace_hint(m_peer_map.end(), nodeid, peer);
|
m_peer_map.emplace_hint(m_peer_map.end(), nodeid, peer);
|
||||||
}
|
}
|
||||||
if (!pnode->IsInboundConn()) {
|
if (!node.IsInboundConn()) {
|
||||||
PushNodeVersion(*pnode, *peer);
|
PushNodeVersion(node, *peer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2843,6 +2865,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||||
m_connman.PushMessage(&pfrom, msg_maker.Make(NetMsgType::VERACK));
|
m_connman.PushMessage(&pfrom, msg_maker.Make(NetMsgType::VERACK));
|
||||||
|
|
||||||
pfrom.nServices = nServices;
|
pfrom.nServices = nServices;
|
||||||
|
peer->m_their_services = nServices;
|
||||||
pfrom.SetAddrLocal(addrMe);
|
pfrom.SetAddrLocal(addrMe);
|
||||||
{
|
{
|
||||||
LOCK(pfrom.m_subver_mutex);
|
LOCK(pfrom.m_subver_mutex);
|
||||||
|
|
|
@ -65,7 +65,7 @@ BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
|
||||||
/*inbound_onion=*/false};
|
/*inbound_onion=*/false};
|
||||||
dummyNode1.SetCommonVersion(PROTOCOL_VERSION);
|
dummyNode1.SetCommonVersion(PROTOCOL_VERSION);
|
||||||
|
|
||||||
peerLogic->InitializeNode(&dummyNode1);
|
peerLogic->InitializeNode(dummyNode1, dummyNode1.GetLocalServices());
|
||||||
dummyNode1.fSuccessfullyConnected = true;
|
dummyNode1.fSuccessfullyConnected = true;
|
||||||
|
|
||||||
// This test requires that we have a chain with non-zero work.
|
// This test requires that we have a chain with non-zero work.
|
||||||
|
@ -124,7 +124,7 @@ static void AddRandomOutboundPeer(NodeId& id, std::vector<CNode*>& vNodes, PeerM
|
||||||
CNode &node = *vNodes.back();
|
CNode &node = *vNodes.back();
|
||||||
node.SetCommonVersion(PROTOCOL_VERSION);
|
node.SetCommonVersion(PROTOCOL_VERSION);
|
||||||
|
|
||||||
peerLogic.InitializeNode(&node);
|
peerLogic.InitializeNode(node, node.GetLocalServices());
|
||||||
node.fSuccessfullyConnected = true;
|
node.fSuccessfullyConnected = true;
|
||||||
|
|
||||||
connman.AddTestNode(node);
|
connman.AddTestNode(node);
|
||||||
|
@ -302,7 +302,7 @@ BOOST_AUTO_TEST_CASE(peer_discouragement)
|
||||||
ConnectionType::INBOUND,
|
ConnectionType::INBOUND,
|
||||||
/*inbound_onion=*/false};
|
/*inbound_onion=*/false};
|
||||||
nodes[0]->SetCommonVersion(PROTOCOL_VERSION);
|
nodes[0]->SetCommonVersion(PROTOCOL_VERSION);
|
||||||
peerLogic->InitializeNode(nodes[0]);
|
peerLogic->InitializeNode(*nodes[0], nodes[0]->GetLocalServices());
|
||||||
nodes[0]->fSuccessfullyConnected = true;
|
nodes[0]->fSuccessfullyConnected = true;
|
||||||
connman->AddTestNode(*nodes[0]);
|
connman->AddTestNode(*nodes[0]);
|
||||||
peerLogic->UnitTestMisbehaving(nodes[0]->GetId(), DISCOURAGEMENT_THRESHOLD); // Should be discouraged
|
peerLogic->UnitTestMisbehaving(nodes[0]->GetId(), DISCOURAGEMENT_THRESHOLD); // Should be discouraged
|
||||||
|
@ -325,7 +325,7 @@ BOOST_AUTO_TEST_CASE(peer_discouragement)
|
||||||
ConnectionType::INBOUND,
|
ConnectionType::INBOUND,
|
||||||
/*inbound_onion=*/false};
|
/*inbound_onion=*/false};
|
||||||
nodes[1]->SetCommonVersion(PROTOCOL_VERSION);
|
nodes[1]->SetCommonVersion(PROTOCOL_VERSION);
|
||||||
peerLogic->InitializeNode(nodes[1]);
|
peerLogic->InitializeNode(*nodes[1], nodes[1]->GetLocalServices());
|
||||||
nodes[1]->fSuccessfullyConnected = true;
|
nodes[1]->fSuccessfullyConnected = true;
|
||||||
connman->AddTestNode(*nodes[1]);
|
connman->AddTestNode(*nodes[1]);
|
||||||
peerLogic->UnitTestMisbehaving(nodes[1]->GetId(), DISCOURAGEMENT_THRESHOLD - 1);
|
peerLogic->UnitTestMisbehaving(nodes[1]->GetId(), DISCOURAGEMENT_THRESHOLD - 1);
|
||||||
|
@ -363,7 +363,7 @@ BOOST_AUTO_TEST_CASE(peer_discouragement)
|
||||||
ConnectionType::OUTBOUND_FULL_RELAY,
|
ConnectionType::OUTBOUND_FULL_RELAY,
|
||||||
/*inbound_onion=*/false};
|
/*inbound_onion=*/false};
|
||||||
nodes[2]->SetCommonVersion(PROTOCOL_VERSION);
|
nodes[2]->SetCommonVersion(PROTOCOL_VERSION);
|
||||||
peerLogic->InitializeNode(nodes[2]);
|
peerLogic->InitializeNode(*nodes[2], nodes[2]->GetLocalServices());
|
||||||
nodes[2]->fSuccessfullyConnected = true;
|
nodes[2]->fSuccessfullyConnected = true;
|
||||||
connman->AddTestNode(*nodes[2]);
|
connman->AddTestNode(*nodes[2]);
|
||||||
peerLogic->UnitTestMisbehaving(nodes[2]->GetId(), DISCOURAGEMENT_THRESHOLD);
|
peerLogic->UnitTestMisbehaving(nodes[2]->GetId(), DISCOURAGEMENT_THRESHOLD);
|
||||||
|
@ -408,7 +408,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
|
||||||
ConnectionType::INBOUND,
|
ConnectionType::INBOUND,
|
||||||
/*inbound_onion=*/false};
|
/*inbound_onion=*/false};
|
||||||
dummyNode.SetCommonVersion(PROTOCOL_VERSION);
|
dummyNode.SetCommonVersion(PROTOCOL_VERSION);
|
||||||
peerLogic->InitializeNode(&dummyNode);
|
peerLogic->InitializeNode(dummyNode, dummyNode.GetLocalServices());
|
||||||
dummyNode.fSuccessfullyConnected = true;
|
dummyNode.fSuccessfullyConnected = true;
|
||||||
|
|
||||||
peerLogic->UnitTestMisbehaving(dummyNode.GetId(), DISCOURAGEMENT_THRESHOLD);
|
peerLogic->UnitTestMisbehaving(dummyNode.GetId(), DISCOURAGEMENT_THRESHOLD);
|
||||||
|
|
|
@ -857,7 +857,7 @@ BOOST_AUTO_TEST_CASE(initial_advertise_from_version_message)
|
||||||
*static_cast<TestChainState*>(&m_node.chainman->ActiveChainstate());
|
*static_cast<TestChainState*>(&m_node.chainman->ActiveChainstate());
|
||||||
chainstate.JumpOutOfIbd();
|
chainstate.JumpOutOfIbd();
|
||||||
|
|
||||||
m_node.peerman->InitializeNode(&peer);
|
m_node.peerman->InitializeNode(peer, peer.GetLocalServices());
|
||||||
|
|
||||||
std::atomic<bool> interrupt_dummy{false};
|
std::atomic<bool> interrupt_dummy{false};
|
||||||
std::chrono::microseconds time_received_dummy{0};
|
std::chrono::microseconds time_received_dummy{0};
|
||||||
|
|
|
@ -24,7 +24,7 @@ void ConnmanTestMsg::Handshake(CNode& node,
|
||||||
auto& connman{*this};
|
auto& connman{*this};
|
||||||
const CNetMsgMaker mm{0};
|
const CNetMsgMaker mm{0};
|
||||||
|
|
||||||
peerman.InitializeNode(&node);
|
peerman.InitializeNode(node, node.GetLocalServices());
|
||||||
|
|
||||||
CSerializedNetMsg msg_version{
|
CSerializedNetMsg msg_version{
|
||||||
mm.Make(NetMsgType::VERSION,
|
mm.Make(NetMsgType::VERSION,
|
||||||
|
|
Loading…
Add table
Reference in a new issue