Skip to content

Commit dac53b5

Browse files
committed
Modify getblocktxn handler not to drop requests for old blocks
The current getblocktxn implementation drops and ignores requests for old blocks, which causes occasional sync_block timeouts during the p2p-compactblocks.py test as reported in bitcoin/bitcoin#8842. The p2p-compactblocks.py test setup creates many new blocks in a short period of time, which can lead to getblocktxn requests for blocks below the hardcoded depth limit of 10 blocks. This commit changes the getblocktxn handler not to ignore these requests, so the peer nodes in the test setup will reliably be able to sync. The protocol change is documented in BIP-152 update "Allow block responses to getblocktxn requests" at bitcoin/bips#469. The protocol change is not expected to affect nodes running outside the test environment, because there shouldn't normally be lots of new blocks being rapidly added that need to be synced.
1 parent 55bfddc commit dac53b5

File tree

2 files changed

+21
-3
lines changed

2 files changed

+21
-3
lines changed

qa/rpc-tests/p2p-compactblocks.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -589,8 +589,8 @@ def test_incorrect_blocktxn_response(self, node, test_node, version):
589589
assert_equal(int(node.getbestblockhash(), 16), block.sha256)
590590

591591
def test_getblocktxn_handler(self, node, test_node, version):
592-
# bitcoind won't respond for blocks whose height is more than 15 blocks
593-
# deep.
592+
# bitcoind will not send blocktxn responses for blocks whose height is
593+
# more than 10 blocks deep.
594594
MAX_GETBLOCKTXN_DEPTH = 10
595595
chain_height = node.getblockcount()
596596
current_height = chain_height
@@ -623,11 +623,17 @@ def test_getblocktxn_handler(self, node, test_node, version):
623623
test_node.last_blocktxn = None
624624
current_height -= 1
625625

626-
# Next request should be ignored, as we're past the allowed depth.
626+
# Next request should send a full block response, as we're past the
627+
# allowed depth for a blocktxn response.
627628
block_hash = node.getblockhash(current_height)
628629
msg.block_txn_request = BlockTransactionsRequest(int(block_hash, 16), [0])
630+
with mininode_lock:
631+
test_node.last_block = None
632+
test_node.last_blocktxn = None
629633
test_node.send_and_ping(msg)
630634
with mininode_lock:
635+
test_node.last_block.block.calc_sha256()
636+
assert_equal(test_node.last_block.block.sha256, int(block_hash, 16))
631637
assert_equal(test_node.last_blocktxn, None)
632638

633639
def test_compactblocks_not_at_tip(self, node, test_node):

src/main.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5450,7 +5450,19 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
54505450
}
54515451

54525452
if (it->second->nHeight < chainActive.Height() - MAX_BLOCKTXN_DEPTH) {
5453+
// If an older block is requested (should never happen in practice,
5454+
// but can happen in tests) send a block response instead of a
5455+
// blocktxn response. Sending a full block response instead of a
5456+
// small blocktxn response is preferable in the case where a peer
5457+
// might maliciously send lots of getblocktxn requests to trigger
5458+
// expensive disk reads, because it will require the peer to
5459+
// actually receive all the data read from disk over the network.
54535460
LogPrint("net", "Peer %d sent us a getblocktxn for a block > %i deep", pfrom->id, MAX_BLOCKTXN_DEPTH);
5461+
CInv vInv;
5462+
vInv.type = State(pfrom->GetId())->fWantsCmpctWitness ? MSG_WITNESS_BLOCK : MSG_BLOCK;
5463+
vInv.hash = req.blockhash;
5464+
pfrom->vRecvGetData.push_back(vInv);
5465+
ProcessGetData(pfrom, chainparams.GetConsensus(), connman);
54545466
return true;
54555467
}
54565468

0 commit comments

Comments
 (0)