diff options
author | Suhas Daftuar <sdaftuar@gmail.com> | 2022-08-12 10:05:22 -0400 |
---|---|---|
committer | Suhas Daftuar <sdaftuar@gmail.com> | 2022-08-29 08:10:35 -0400 |
commit | 03712dddfbb9fe0dc7a2ead53c65106189f5c803 (patch) | |
tree | 26fa9f85ab867705e094f9b4a7826e7553021dfe | |
parent | 150a5486db50ff77c91765392149000029c8a309 (diff) |
Expose HeadersSyncState::m_current_height in getpeerinfo()
-rw-r--r-- | src/headerssync.h | 3 | ||||
-rw-r--r-- | src/net_processing.cpp | 6 | ||||
-rw-r--r-- | src/net_processing.h | 1 | ||||
-rw-r--r-- | src/rpc/net.cpp | 2 | ||||
-rwxr-xr-x | test/functional/p2p_headers_sync_with_minchainwork.py | 51 |
5 files changed, 63 insertions, 0 deletions
diff --git a/src/headerssync.h b/src/headerssync.h index b694407792..01d55eb44e 100644 --- a/src/headerssync.h +++ b/src/headerssync.h @@ -118,6 +118,9 @@ public: /** Return the current state of our download */ State GetState() const { return m_download_state; } + /** Return the height reached during the PRESYNC phase */ + int64_t GetPresyncHeight() const { return m_current_height; } + /** Construct a HeadersSyncState object representing a headers sync via this * download-twice mechanism). * diff --git a/src/net_processing.cpp b/src/net_processing.cpp index ac19593b0f..f471e96b50 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1566,6 +1566,12 @@ bool PeerManagerImpl::GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) c stats.m_addr_processed = peer->m_addr_processed.load(); stats.m_addr_rate_limited = peer->m_addr_rate_limited.load(); stats.m_addr_relay_enabled = peer->m_addr_relay_enabled.load(); + { + LOCK(peer->m_headers_sync_mutex); + if (peer->m_headers_sync) { + stats.presync_height = peer->m_headers_sync->GetPresyncHeight(); + } + } return true; } diff --git a/src/net_processing.h b/src/net_processing.h index bcda9614d4..0a882b1e53 100644 --- a/src/net_processing.h +++ b/src/net_processing.h @@ -35,6 +35,7 @@ struct CNodeStateStats { uint64_t m_addr_rate_limited = 0; bool m_addr_relay_enabled{false}; ServiceFlags their_services; + int64_t presync_height{-1}; }; class PeerManager : public CValidationInterface, public NetEventsInterface diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 06f46040b8..88584ff25f 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -132,6 +132,7 @@ static RPCHelpMan getpeerinfo() {RPCResult::Type::BOOL, "bip152_hb_to", "Whether we selected peer as (compact blocks) high-bandwidth peer"}, {RPCResult::Type::BOOL, "bip152_hb_from", "Whether peer selected us as (compact blocks) high-bandwidth peer"}, {RPCResult::Type::NUM, "startingheight", /*optional=*/true, "The starting height (block) of the peer"}, + {RPCResult::Type::NUM, "presynced_headers", /*optional=*/true, "The current height of header pre-synchronization with this peer, or -1 if no low-work sync is in progress"}, {RPCResult::Type::NUM, "synced_headers", /*optional=*/true, "The last header we have in common with this peer"}, {RPCResult::Type::NUM, "synced_blocks", /*optional=*/true, "The last block we have in common with this peer"}, {RPCResult::Type::ARR, "inflight", /*optional=*/true, "", @@ -226,6 +227,7 @@ static RPCHelpMan getpeerinfo() obj.pushKV("bip152_hb_from", stats.m_bip152_highbandwidth_from); if (fStateStats) { obj.pushKV("startingheight", statestats.m_starting_height); + obj.pushKV("presynced_headers", statestats.presync_height); obj.pushKV("synced_headers", statestats.nSyncHeight); obj.pushKV("synced_blocks", statestats.nCommonHeight); UniValue heights(UniValue::VARR); diff --git a/test/functional/p2p_headers_sync_with_minchainwork.py b/test/functional/p2p_headers_sync_with_minchainwork.py index 8008125ed6..997e2f62a0 100755 --- a/test/functional/p2p_headers_sync_with_minchainwork.py +++ b/test/functional/p2p_headers_sync_with_minchainwork.py @@ -6,6 +6,21 @@ from test_framework.test_framework import BitcoinTestFramework +from test_framework.p2p import ( + P2PInterface, +) + +from test_framework.messages import ( + msg_headers, +) + +from test_framework.blocktools import ( + NORMAL_GBT_REQUEST_PARAMS, + create_block, +) + +from test_framework.util import assert_equal + NODE1_BLOCKS_REQUIRED = 15 NODE2_BLOCKS_REQUIRED = 2047 @@ -23,6 +38,10 @@ class RejectLowDifficultyHeadersTest(BitcoinTestFramework): self.connect_nodes(0, 2) self.sync_all() + def disconnect_all(self): + self.disconnect_nodes(0, 1) + self.disconnect_nodes(0, 2) + def test_chains_sync_when_long_enough(self): self.log.info("Generate blocks on the node with no required chainwork, and verify nodes 1 and 2 have no new headers in their headers tree") with self.nodes[1].assert_debug_log(expected_msgs=["[net] Ignoring low-work chain (height=14)"]), self.nodes[2].assert_debug_log(expected_msgs=["[net] Ignoring low-work chain (height=14)"]): @@ -58,9 +77,41 @@ class RejectLowDifficultyHeadersTest(BitcoinTestFramework): self.log.info("Verify that node2 will sync the chain when it gets long enough") self.sync_blocks() + def test_peerinfo_includes_headers_presync_height(self): + self.log.info("Test that getpeerinfo() includes headers presync height") + + # Disconnect network, so that we can find our own peer connection more + # easily + self.disconnect_all() + + p2p = self.nodes[0].add_p2p_connection(P2PInterface()) + node = self.nodes[0] + + # Ensure we have a long chain already + current_height = self.nodes[0].getblockcount() + if (current_height < 3000): + self.generate(node, 3000-current_height, sync_fun=self.no_op) + + # Send a group of 2000 headers, forking from genesis. + new_blocks = [] + hashPrevBlock = int(node.getblockhash(0), 16) + for i in range(2000): + block = create_block(hashprev = hashPrevBlock, tmpl=node.getblocktemplate(NORMAL_GBT_REQUEST_PARAMS)) + block.solve() + new_blocks.append(block) + hashPrevBlock = block.sha256 + + headers_message = msg_headers(headers=new_blocks) + p2p.send_and_ping(headers_message) + + # getpeerinfo should show a sync in progress + assert_equal(node.getpeerinfo()[0]['presynced_headers'], 2000) + def run_test(self): self.test_chains_sync_when_long_enough() + self.test_peerinfo_includes_headers_presync_height() + if __name__ == '__main__': RejectLowDifficultyHeadersTest().main() |