From 993c7c0f90b41d723a8efd5ef5754a282503265b Mon Sep 17 00:00:00 2001 From: pasta Date: Wed, 28 Aug 2024 12:13:32 -0500 Subject: [PATCH] feat: increase the number of block headers able to be downloaded at once to 8000 in protocol version `70234` --- src/net_processing.cpp | 8 ++++---- src/rpc/blockchain.cpp | 12 ++++++------ src/validation.h | 5 ++++- src/version.h | 5 ++++- test/functional/test_framework/messages.py | 2 +- 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 3d134aa7fa..bd84493dc6 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -2952,7 +2952,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, Peer& peer, } // Consider fetching more headers. - if (nCount == MAX_HEADERS_RESULTS) { + if (nCount == (pfrom.GetCommonVersion() >= INCREASE_MAX_HEADERS_VERSION ? MAX_HEADERS_RESULTS_NEW : MAX_HEADERS_RESULTS_OLD)) { std::string msg_type = UsesCompressedHeaders(peer) ? NetMsgType::GETHEADERS2 : NetMsgType::GETHEADERS; // Headers message had its maximum size; the peer may have more headers. if (MaybeSendGetHeaders(pfrom, msg_type, m_chainman.ActiveChain().GetLocator(pindexLast), peer)) { @@ -2961,7 +2961,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, Peer& peer, } } - UpdatePeerStateForReceivedHeaders(pfrom, pindexLast, received_new_header, nCount == MAX_HEADERS_RESULTS); + UpdatePeerStateForReceivedHeaders(pfrom, pindexLast, received_new_header, nCount == (pfrom.GetCommonVersion() >= INCREASE_MAX_HEADERS_VERSION ? MAX_HEADERS_RESULTS_NEW : MAX_HEADERS_RESULTS_OLD)); // Consider immediately downloading blocks. HeadersDirectFetchBlocks(pfrom, peer, pindexLast); @@ -4056,7 +4056,7 @@ void PeerManagerImpl::ProcessMessage( } const auto send_headers = [this /* for m_connman */, &hashStop, &pindex, &nodestate, &pfrom, &msgMaker](auto msg_type, auto& v_headers, auto callback) { - int nLimit = MAX_HEADERS_RESULTS; + int nLimit = pfrom.GetCommonVersion() >= INCREASE_MAX_HEADERS_VERSION ? MAX_HEADERS_RESULTS_NEW : MAX_HEADERS_RESULTS_OLD; for (; pindex; pindex = m_chainman.ActiveChain().Next(pindex)) { v_headers.push_back(callback(pindex)); @@ -4564,7 +4564,7 @@ void PeerManagerImpl::ProcessMessage( // Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks. unsigned int nCount = ReadCompactSize(vRecv); - if (nCount > MAX_HEADERS_RESULTS) { + if (nCount > (pfrom.GetCommonVersion() >= INCREASE_MAX_HEADERS_VERSION ? MAX_HEADERS_RESULTS_NEW : MAX_HEADERS_RESULTS_OLD)) { Misbehaving(pfrom.GetId(), 20, strprintf("headers message size = %u", nCount)); return; } diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 16055175fb..5927ca215b 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -996,7 +996,7 @@ static RPCHelpMan getblockheaders() "If verbose is true, each item is an Object with information about a single blockheader.\n", { {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash"}, - {"count", RPCArg::Type::NUM, /* default */ strprintf("%s", MAX_HEADERS_RESULTS), ""}, + {"count", RPCArg::Type::NUM, /* default */ strprintf("%s", MAX_HEADERS_RESULTS_NEW), ""}, {"verbose", RPCArg::Type::BOOL, /* default */ "true", "true for a json object, false for the hex-encoded data"}, }, { @@ -1054,11 +1054,11 @@ static RPCHelpMan getblockheaders() throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); } - int nCount = MAX_HEADERS_RESULTS; + int nCount = MAX_HEADERS_RESULTS_NEW; if (!request.params[1].isNull()) nCount = request.params[1].get_int(); - if (nCount <= 0 || nCount > (int)MAX_HEADERS_RESULTS) + if (nCount <= 0 || nCount > (int)MAX_HEADERS_RESULTS_NEW) throw JSONRPCError(RPC_INVALID_PARAMETER, "Count is out of range"); bool fVerbose = true; @@ -1134,7 +1134,7 @@ static RPCHelpMan getmerkleblocks() { {"filter", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex-encoded bloom filter"}, {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash"}, - {"count", RPCArg::Type::NUM, /* default */ strprintf("%s", MAX_HEADERS_RESULTS), ""}, + {"count", RPCArg::Type::NUM, /* default */ strprintf("%s", MAX_HEADERS_RESULTS_NEW), ""}, }, RPCResult{ RPCResult::Type::ARR, "", "", @@ -1163,11 +1163,11 @@ static RPCHelpMan getmerkleblocks() throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); } - int nCount = MAX_HEADERS_RESULTS; + int nCount = MAX_HEADERS_RESULTS_NEW; if (!request.params[2].isNull()) nCount = request.params[2].get_int(); - if (nCount <= 0 || nCount > (int)MAX_HEADERS_RESULTS) { + if (nCount <= 0 || nCount > (int)MAX_HEADERS_RESULTS_NEW) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Count is out of range"); } diff --git a/src/validation.h b/src/validation.h index 8dc4d7e656..37c661853f 100644 --- a/src/validation.h +++ b/src/validation.h @@ -85,7 +85,10 @@ static const int MAX_SCRIPTCHECK_THREADS = 15; static const int DEFAULT_SCRIPTCHECK_THREADS = 0; /** Number of headers sent in one getheaders result. We rely on the assumption that if a peer sends * less than this number, we reached its tip. Changing this value is a protocol upgrade. */ -static const unsigned int MAX_HEADERS_RESULTS = 2000; +static const unsigned int MAX_HEADERS_RESULTS_OLD = 2000; +/** Introduced in protocol version INCREASE_MAX_HEADERS_VERSION */ +static const unsigned int MAX_HEADERS_RESULTS_NEW = 8000; + static const int64_t DEFAULT_MAX_TIP_AGE = 6 * 60 * 60; // ~144 blocks behind -> 2 x fork detection time, was 24 * 60 * 60 in bitcoin diff --git a/src/version.h b/src/version.h index 7b5b48e641..1eeee4b582 100644 --- a/src/version.h +++ b/src/version.h @@ -11,7 +11,7 @@ */ -static const int PROTOCOL_VERSION = 70234; +static const int PROTOCOL_VERSION = 70235; //! initial proto version, to be increased after version/verack negotiation static const int INIT_PROTO_VERSION = 209; @@ -58,6 +58,9 @@ static const int NO_LEGACY_ISLOCK_PROTO_VERSION = 70231; //! Inventory type for DSQ messages added static const int DSQ_INV_VERSION = 70234; +//! Maximum header count was increased from 2000 -> 8000 in this version +static const int INCREASE_MAX_HEADERS_VERSION = 70235; + // Make sure that none of the values above collide with `ADDRV2_FORMAT`. #endif // BITCOIN_VERSION_H diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py index 0804b87873..088f029c6c 100755 --- a/test/functional/test_framework/messages.py +++ b/test/functional/test_framework/messages.py @@ -42,7 +42,7 @@ MAX_MONEY = 21000000 * COIN BIP125_SEQUENCE_NUMBER = 0xfffffffd # Sequence number that is BIP 125 opt-in and BIP 68-opt-out MAX_PROTOCOL_MESSAGE_LENGTH = 3 * 1024 * 1024 # Maximum length of incoming protocol messages -MAX_HEADERS_RESULTS = 2000 # Number of headers sent in one getheaders result +MAX_HEADERS_RESULTS = 8000 # Number of headers sent in one getheaders result MAX_INV_SIZE = 50000 # Maximum number of entries in an 'inv' protocol message NODE_NETWORK = (1 << 0)