Skip to content

Commit 22f13c1

Browse files
author
MarcoFalke
committed
Merge #19776: net, rpc: expose high bandwidth mode state via getpeerinfo
343dc47 test: add test for high-bandwidth mode states in getpeerinfo (Sebastian Falbesoner) dab6583 doc: release note for new getpeerinfo fields "bip152_hb_{from,to}" (Sebastian Falbesoner) a7ed00f rpc: expose high-bandwidth mode states via getpeerinfo (Sebastian Falbesoner) 30bc8fa net: save high-bandwidth mode states in CNodeStats (Sebastian Falbesoner) Pull request description: Fixes #19676, "_For every peer expose through getpeerinfo RPC whether or not we selected them as HB peers, and whether or not they selected us as HB peers._" See [BIP152](https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki), in particular the [protocol flow diagram](https://github.com/bitcoin/bips/raw/master/bip-0152/protocol-flow.png). The newly introduced states are changed on the following places in the code: * on reception of a `SENDCMPCT` message with valid version, the field `m_highbandwidth_from` is changed depending on the first integer parameter in the message (1=high bandwidth, 0=low bandwidth), i.e. it just mirrors the field `CNodeState.fPreferHeaderAndIDs`. * after adding a `SENDCMPCT` message to the send queue, the field `m_highbandwidth_to` is changed depending on how the first integer parameter is set (same as above) Note that after receiving `VERACK`, the node also sends `SENDCMPCT`, but that is only to announce the preferred version and never selects high-bandwidth mode, hence there is no need to change the state variables there, which are initialized to `false` anyways. ACKs for top commit: naumenkogs: reACK 343dc47 jonatack: re-ACK 343dc47 per `git range-diff 7ea6499 4df1d12 343dc47` Tree-SHA512: f4999e6a935266812c2259a9b5dc459710037d3c9e938006d282557cc225e56128f72965faffb207fc60c6531fab1206db976dd8729a69e8ca29d4835317b99f
2 parents f5b2ea3 + 343dc47 commit 22f13c1

File tree

6 files changed

+61
-1
lines changed

6 files changed

+61
-1
lines changed

doc/release-notes-19776.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Updated RPCs
2+
------------
3+
4+
- The `getpeerinfo` RPC returns two new boolean fields, `bip152_hb_to` and
5+
`bip152_hb_from`, that respectively indicate whether we selected a peer to be
6+
in compact blocks high-bandwidth mode or whether a peer selected us as a
7+
compact blocks high-bandwidth peer. High-bandwidth peers send new block
8+
announcements via a `cmpctblock` message rather than the usual inv/headers
9+
announcements. See BIP 152 for more details. (#19776)

src/net.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,8 @@ void CNode::copyStats(CNodeStats &stats, const std::vector<bool> &m_asmap)
584584
}
585585
stats.fInbound = IsInboundConn();
586586
stats.m_manual_connection = IsManualConn();
587+
X(m_bip152_highbandwidth_to);
588+
X(m_bip152_highbandwidth_from);
587589
X(nStartingHeight);
588590
{
589591
LOCK(cs_vSend);

src/net.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,8 @@ class CNodeStats
697697
std::string cleanSubVer;
698698
bool fInbound;
699699
bool m_manual_connection;
700+
bool m_bip152_highbandwidth_to;
701+
bool m_bip152_highbandwidth_from;
700702
int nStartingHeight;
701703
uint64_t nSendBytes;
702704
mapMsgCmdSize mapSendBytesPerMsgCmd;
@@ -984,6 +986,10 @@ class CNode
984986
public:
985987
uint256 hashContinue;
986988
std::atomic<int> nStartingHeight{-1};
989+
// We selected peer as (compact blocks) high-bandwidth peer (BIP152)
990+
std::atomic<bool> m_bip152_highbandwidth_to{false};
991+
// Peer selected us as (compact blocks) high-bandwidth peer (BIP152)
992+
std::atomic<bool> m_bip152_highbandwidth_from{false};
987993

988994
// flood relay
989995
std::vector<CAddress> vAddrToSend;

src/net_processing.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -557,11 +557,15 @@ static void MaybeSetPeerAsAnnouncingHeaderAndIDs(NodeId nodeid, CConnman& connma
557557
// blocks using compact encodings.
558558
connman.ForNode(lNodesAnnouncingHeaderAndIDs.front(), [&connman, nCMPCTBLOCKVersion](CNode* pnodeStop){
559559
connman.PushMessage(pnodeStop, CNetMsgMaker(pnodeStop->GetCommonVersion()).Make(NetMsgType::SENDCMPCT, /*fAnnounceUsingCMPCTBLOCK=*/false, nCMPCTBLOCKVersion));
560+
// save BIP152 bandwidth state: we select peer to be low-bandwidth
561+
pnodeStop->m_bip152_highbandwidth_to = false;
560562
return true;
561563
});
562564
lNodesAnnouncingHeaderAndIDs.pop_front();
563565
}
564566
connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetCommonVersion()).Make(NetMsgType::SENDCMPCT, /*fAnnounceUsingCMPCTBLOCK=*/true, nCMPCTBLOCKVersion));
567+
// save BIP152 bandwidth state: we select peer to be high-bandwidth
568+
pfrom->m_bip152_highbandwidth_to = true;
565569
lNodesAnnouncingHeaderAndIDs.push_back(pfrom->GetId());
566570
return true;
567571
});
@@ -2603,8 +2607,12 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat
26032607
State(pfrom.GetId())->fProvidesHeaderAndIDs = true;
26042608
State(pfrom.GetId())->fWantsCmpctWitness = nCMPCTBLOCKVersion == 2;
26052609
}
2606-
if (State(pfrom.GetId())->fWantsCmpctWitness == (nCMPCTBLOCKVersion == 2)) // ignore later version announces
2610+
if (State(pfrom.GetId())->fWantsCmpctWitness == (nCMPCTBLOCKVersion == 2)) { // ignore later version announces
26072611
State(pfrom.GetId())->fPreferHeaderAndIDs = fAnnounceUsingCMPCTBLOCK;
2612+
// save whether peer selects us as BIP152 high-bandwidth peer
2613+
// (receiving sendcmpct(1) signals high-bandwidth, sendcmpct(0) low-bandwidth)
2614+
pfrom.m_bip152_highbandwidth_from = fAnnounceUsingCMPCTBLOCK;
2615+
}
26082616
if (!State(pfrom.GetId())->fSupportsDesiredCmpctVersion) {
26092617
if (pfrom.GetLocalServices() & NODE_WITNESS)
26102618
State(pfrom.GetId())->fSupportsDesiredCmpctVersion = (nCMPCTBLOCKVersion == 2);

src/rpc/net.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ static RPCHelpMan getpeerinfo()
126126
{RPCResult::Type::NUM, "version", "The peer version, such as 70001"},
127127
{RPCResult::Type::STR, "subver", "The string version"},
128128
{RPCResult::Type::BOOL, "inbound", "Inbound (true) or Outbound (false)"},
129+
{RPCResult::Type::BOOL, "bip152_hb_to", "Whether we selected peer as (compact blocks) high-bandwidth peer"},
130+
{RPCResult::Type::BOOL, "bip152_hb_from", "Whether peer selected us as (compact blocks) high-bandwidth peer"},
129131
{RPCResult::Type::BOOL, "addnode", "Whether connection was due to addnode/-connect or if it was an automatic/inbound connection\n"
130132
"(DEPRECATED, returned only if the config option -deprecatedrpc=getpeerinfo_addnode is passed)"},
131133
{RPCResult::Type::STR, "connection_type", "Type of connection: \n" + Join(CONNECTION_TYPE_DOC, ",\n") + ".\n"
@@ -216,6 +218,8 @@ static RPCHelpMan getpeerinfo()
216218
// their ver message.
217219
obj.pushKV("subver", stats.cleanSubVer);
218220
obj.pushKV("inbound", stats.fInbound);
221+
obj.pushKV("bip152_hb_to", stats.m_bip152_highbandwidth_to);
222+
obj.pushKV("bip152_hb_from", stats.m_bip152_highbandwidth_from);
219223
if (IsDeprecatedRPCEnabled("getpeerinfo_addnode")) {
220224
// addnode is deprecated in v0.21 for removal in v0.22
221225
obj.pushKV("addnode", stats.m_manual_connection);

test/functional/p2p_compactblocks.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,34 @@ def announce_cmpct_block(node, peer):
764764
stalling_peer.send_and_ping(msg)
765765
assert_equal(int(node.getbestblockhash(), 16), block.sha256)
766766

767+
def test_highbandwidth_mode_states_via_getpeerinfo(self):
768+
# create new p2p connection for a fresh state w/o any prior sendcmpct messages sent
769+
hb_test_node = self.nodes[0].add_p2p_connection(TestP2PConn(cmpct_version=2))
770+
771+
# assert the RPC getpeerinfo boolean fields `bip152_hb_{to, from}`
772+
# match the given parameters for the last peer of a given node
773+
def assert_highbandwidth_states(node, hb_to, hb_from):
774+
peerinfo = node.getpeerinfo()[-1]
775+
assert_equal(peerinfo['bip152_hb_to'], hb_to)
776+
assert_equal(peerinfo['bip152_hb_from'], hb_from)
777+
778+
# initially, neither node has selected the other peer as high-bandwidth yet
779+
assert_highbandwidth_states(self.nodes[0], hb_to=False, hb_from=False)
780+
781+
# peer requests high-bandwidth mode by sending sendcmpct(1)
782+
hb_test_node.send_and_ping(msg_sendcmpct(announce=True, version=2))
783+
assert_highbandwidth_states(self.nodes[0], hb_to=False, hb_from=True)
784+
785+
# peer generates a block and sends it to node, which should
786+
# select the peer as high-bandwidth (up to 3 peers according to BIP 152)
787+
block = self.build_block_on_tip(self.nodes[0])
788+
hb_test_node.send_and_ping(msg_block(block))
789+
assert_highbandwidth_states(self.nodes[0], hb_to=True, hb_from=True)
790+
791+
# peer requests low-bandwidth mode by sending sendcmpct(0)
792+
hb_test_node.send_and_ping(msg_sendcmpct(announce=False, version=2))
793+
assert_highbandwidth_states(self.nodes[0], hb_to=True, hb_from=False)
794+
767795
def run_test(self):
768796
# Get the nodes out of IBD
769797
self.nodes[0].generate(1)
@@ -822,6 +850,9 @@ def run_test(self):
822850
self.log.info("Testing invalid index in cmpctblock message...")
823851
self.test_invalid_cmpctblock_message()
824852

853+
self.log.info("Testing high-bandwidth mode states via getpeerinfo...")
854+
self.test_highbandwidth_mode_states_via_getpeerinfo()
855+
825856

826857
if __name__ == '__main__':
827858
CompactBlocksTest().main()

0 commit comments

Comments
 (0)