Skip to content

Commit

Permalink
Allow compactblock reconstruction when block is in flight
Browse files Browse the repository at this point in the history
  • Loading branch information
sdaftuar committed Dec 14, 2016
1 parent 0a4aa87 commit 4ced313
Showing 1 changed file with 49 additions and 0 deletions.
49 changes: 49 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5657,6 +5657,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
CBlockHeaderAndShortTxIDs cmpctblock;
vRecv >> cmpctblock;

// Keep a CBlock for "optimistic" compactblock reconstructions (see
// below)
CBlock block;
bool fBlockReconstructed = false;

LOCK(cs_main);

if (mapBlockIndex.find(cmpctblock.header.hashPrevBlock) == mapBlockIndex.end()) {
Expand Down Expand Up @@ -5765,6 +5770,23 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
req.blockhash = pindex->GetBlockHash();
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 {
if (fAlreadyInFlight) {
Expand All @@ -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());
}

Expand Down

0 comments on commit 4ced313

Please sign in to comment.