mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-02-01 04:47:53 +01:00
Allow compactblock reconstruction when block is in flight
This commit is contained in:
49
src/main.cpp
49
src/main.cpp
@@ -5657,6 +5657,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
|||||||
CBlockHeaderAndShortTxIDs cmpctblock;
|
CBlockHeaderAndShortTxIDs cmpctblock;
|
||||||
vRecv >> cmpctblock;
|
vRecv >> cmpctblock;
|
||||||
|
|
||||||
|
// Keep a CBlock for "optimistic" compactblock reconstructions (see
|
||||||
|
// below)
|
||||||
|
CBlock block;
|
||||||
|
bool fBlockReconstructed = false;
|
||||||
|
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
|
|
||||||
if (mapBlockIndex.find(cmpctblock.header.hashPrevBlock) == mapBlockIndex.end()) {
|
if (mapBlockIndex.find(cmpctblock.header.hashPrevBlock) == mapBlockIndex.end()) {
|
||||||
@@ -5765,6 +5770,23 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
|||||||
req.blockhash = pindex->GetBlockHash();
|
req.blockhash = pindex->GetBlockHash();
|
||||||
pfrom->PushMessage(NetMsgType::GETBLOCKTXN, req);
|
pfrom->PushMessage(NetMsgType::GETBLOCKTXN, req);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// This block is either already in flight from a different
|
||||||
|
// peer, or this peer has too many blocks outstanding to
|
||||||
|
// download from.
|
||||||
|
// Optimistically try to reconstruct anyway since we might be
|
||||||
|
// able to without any round trips.
|
||||||
|
PartiallyDownloadedBlock tempBlock(&mempool);
|
||||||
|
ReadStatus status = tempBlock.InitData(cmpctblock);
|
||||||
|
if (status != READ_STATUS_OK) {
|
||||||
|
// TODO: don't ignore failures
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
std::vector<CTransaction> dummy;
|
||||||
|
status = tempBlock.FillBlock(block, dummy);
|
||||||
|
if (status == READ_STATUS_OK) {
|
||||||
|
fBlockReconstructed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (fAlreadyInFlight) {
|
if (fAlreadyInFlight) {
|
||||||
@@ -5785,6 +5807,33 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fBlockReconstructed) {
|
||||||
|
// If we got here, we were able to optimistically reconstruct a
|
||||||
|
// block that is in flight from some other peer. However, this
|
||||||
|
// cmpctblock may be invalid. In particular, while we've checked
|
||||||
|
// that the block merkle root commits to the transaction ids, we
|
||||||
|
// haven't yet checked that tx witnesses are properly committed to
|
||||||
|
// in the coinbase witness commitment.
|
||||||
|
//
|
||||||
|
// ProcessNewBlock will call MarkBlockAsReceived(), which will
|
||||||
|
// clear any in-flight compact block state that might be present
|
||||||
|
// from some other peer. We don't want a malleated compact block
|
||||||
|
// request to interfere with block relay, so we don't want to call
|
||||||
|
// ProcessNewBlock until we've already checked that the witness
|
||||||
|
// commitment is correct.
|
||||||
|
{
|
||||||
|
LOCK(cs_main);
|
||||||
|
CValidationState dummy;
|
||||||
|
if (!ContextualCheckBlock(block, dummy, pindex->pprev)) {
|
||||||
|
// TODO: could send reject message to peer?
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CValidationState state;
|
||||||
|
ProcessNewBlock(state, chainparams, pfrom, &block, true, NULL, false);
|
||||||
|
// TODO: could send reject message if block is invalid?
|
||||||
|
}
|
||||||
|
|
||||||
CheckBlockIndex(chainparams.GetConsensus());
|
CheckBlockIndex(chainparams.GetConsensus());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user