Skip to content

Commit 4ced313

Browse files
committed
Allow compactblock reconstruction when block is in flight
1 parent 0a4aa87 commit 4ced313

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

src/main.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5657,6 +5657,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
56575657
CBlockHeaderAndShortTxIDs cmpctblock;
56585658
vRecv >> cmpctblock;
56595659

5660+
// Keep a CBlock for "optimistic" compactblock reconstructions (see
5661+
// below)
5662+
CBlock block;
5663+
bool fBlockReconstructed = false;
5664+
56605665
LOCK(cs_main);
56615666

56625667
if (mapBlockIndex.find(cmpctblock.header.hashPrevBlock) == mapBlockIndex.end()) {
@@ -5765,6 +5770,23 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
57655770
req.blockhash = pindex->GetBlockHash();
57665771
pfrom->PushMessage(NetMsgType::GETBLOCKTXN, req);
57675772
}
5773+
} else {
5774+
// This block is either already in flight from a different
5775+
// peer, or this peer has too many blocks outstanding to
5776+
// download from.
5777+
// Optimistically try to reconstruct anyway since we might be
5778+
// able to without any round trips.
5779+
PartiallyDownloadedBlock tempBlock(&mempool);
5780+
ReadStatus status = tempBlock.InitData(cmpctblock);
5781+
if (status != READ_STATUS_OK) {
5782+
// TODO: don't ignore failures
5783+
return true;
5784+
}
5785+
std::vector<CTransaction> dummy;
5786+
status = tempBlock.FillBlock(block, dummy);
5787+
if (status == READ_STATUS_OK) {
5788+
fBlockReconstructed = true;
5789+
}
57685790
}
57695791
} else {
57705792
if (fAlreadyInFlight) {
@@ -5785,6 +5807,33 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
57855807
}
57865808
}
57875809

5810+
if (fBlockReconstructed) {
5811+
// If we got here, we were able to optimistically reconstruct a
5812+
// block that is in flight from some other peer. However, this
5813+
// cmpctblock may be invalid. In particular, while we've checked
5814+
// that the block merkle root commits to the transaction ids, we
5815+
// haven't yet checked that tx witnesses are properly committed to
5816+
// in the coinbase witness commitment.
5817+
//
5818+
// ProcessNewBlock will call MarkBlockAsReceived(), which will
5819+
// clear any in-flight compact block state that might be present
5820+
// from some other peer. We don't want a malleated compact block
5821+
// request to interfere with block relay, so we don't want to call
5822+
// ProcessNewBlock until we've already checked that the witness
5823+
// commitment is correct.
5824+
{
5825+
LOCK(cs_main);
5826+
CValidationState dummy;
5827+
if (!ContextualCheckBlock(block, dummy, pindex->pprev)) {
5828+
// TODO: could send reject message to peer?
5829+
return true;
5830+
}
5831+
}
5832+
CValidationState state;
5833+
ProcessNewBlock(state, chainparams, pfrom, &block, true, NULL, false);
5834+
// TODO: could send reject message if block is invalid?
5835+
}
5836+
57885837
CheckBlockIndex(chainparams.GetConsensus());
57895838
}
57905839

0 commit comments

Comments
 (0)