|
|
@ -1782,6 +1782,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Keep a CBlock for "optimistic" compactblock reconstructions (see
|
|
|
|
|
|
|
|
// below)
|
|
|
|
|
|
|
|
std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>(); |
|
|
|
|
|
|
|
bool fBlockReconstructed = false; |
|
|
|
|
|
|
|
|
|
|
|
LOCK(cs_main); |
|
|
|
LOCK(cs_main); |
|
|
|
// If AcceptBlockHeader returned true, it set pindex
|
|
|
|
// If AcceptBlockHeader returned true, it set pindex
|
|
|
|
assert(pindex); |
|
|
|
assert(pindex); |
|
|
@ -1870,6 +1875,23 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, |
|
|
|
req.blockhash = pindex->GetBlockHash(); |
|
|
|
req.blockhash = pindex->GetBlockHash(); |
|
|
|
connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::GETBLOCKTXN, req)); |
|
|
|
connman.PushMessage(pfrom, msgMaker.Make(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<CTransactionRef> dummy; |
|
|
|
|
|
|
|
status = tempBlock.FillBlock(*pblock, dummy); |
|
|
|
|
|
|
|
if (status == READ_STATUS_OK) { |
|
|
|
|
|
|
|
fBlockReconstructed = true; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
if (fAlreadyInFlight) { |
|
|
|
if (fAlreadyInFlight) { |
|
|
@ -1889,6 +1911,29 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, |
|
|
|
return ProcessMessage(pfrom, NetMsgType::HEADERS, vHeadersMsg, nTimeReceived, chainparams, connman); |
|
|
|
return ProcessMessage(pfrom, NetMsgType::HEADERS, vHeadersMsg, nTimeReceived, chainparams, connman); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (fBlockReconstructed) { |
|
|
|
|
|
|
|
// If we got here, we were able to optimistically reconstruct a
|
|
|
|
|
|
|
|
// block that is in flight from some other peer.
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
LOCK(cs_main); |
|
|
|
|
|
|
|
mapBlockSource.emplace(pblock->GetHash(), std::make_pair(pfrom->GetId(), false)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
bool fNewBlock = false; |
|
|
|
|
|
|
|
ProcessNewBlock(chainparams, pblock, true, &fNewBlock); |
|
|
|
|
|
|
|
if (fNewBlock) |
|
|
|
|
|
|
|
pfrom->nLastBlockTime = GetTime(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LOCK(cs_main); // hold cs_main for CBlockIndex::IsValid()
|
|
|
|
|
|
|
|
if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS)) { |
|
|
|
|
|
|
|
// Clear download state for this block, which is in
|
|
|
|
|
|
|
|
// process from some other peer. We do this after calling
|
|
|
|
|
|
|
|
// ProcessNewBlock so that a malleated cmpctblock announcement
|
|
|
|
|
|
|
|
// can't be used to interfere with block relay.
|
|
|
|
|
|
|
|
MarkBlockAsReceived(pblock->GetHash()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
else if (strCommand == NetMsgType::BLOCKTXN && !fImporting && !fReindex) // Ignore blocks received while importing
|
|
|
|
else if (strCommand == NetMsgType::BLOCKTXN && !fImporting && !fReindex) // Ignore blocks received while importing
|
|
|
|