|
|
|
@ -979,6 +979,13 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
@@ -979,6 +979,13 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
|
|
|
|
|
{ |
|
|
|
|
bool send = false; |
|
|
|
|
BlockMap::iterator mi = mapBlockIndex.find(inv.hash); |
|
|
|
|
std::shared_ptr<const CBlock> a_recent_block; |
|
|
|
|
std::shared_ptr<const CBlockHeaderAndShortTxIDs> a_recent_compact_block; |
|
|
|
|
{ |
|
|
|
|
LOCK(cs_most_recent_block); |
|
|
|
|
a_recent_block = most_recent_block; |
|
|
|
|
a_recent_compact_block = most_recent_compact_block; |
|
|
|
|
} |
|
|
|
|
if (mi != mapBlockIndex.end()) |
|
|
|
|
{ |
|
|
|
|
if (mi->second->nChainTx && !mi->second->IsValid(BLOCK_VALID_SCRIPTS) && |
|
|
|
@ -988,11 +995,6 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
@@ -988,11 +995,6 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
|
|
|
|
|
// before ActivateBestChain but after AcceptBlock).
|
|
|
|
|
// In this case, we need to run ActivateBestChain prior to checking the relay
|
|
|
|
|
// conditions below.
|
|
|
|
|
std::shared_ptr<const CBlock> a_recent_block; |
|
|
|
|
{ |
|
|
|
|
LOCK(cs_most_recent_block); |
|
|
|
|
a_recent_block = most_recent_block; |
|
|
|
|
} |
|
|
|
|
CValidationState dummy; |
|
|
|
|
ActivateBestChain(dummy, Params(), a_recent_block); |
|
|
|
|
} |
|
|
|
@ -1026,14 +1028,20 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
@@ -1026,14 +1028,20 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
|
|
|
|
|
// it's available before trying to send.
|
|
|
|
|
if (send && (mi->second->nStatus & BLOCK_HAVE_DATA)) |
|
|
|
|
{ |
|
|
|
|
// Send block from disk
|
|
|
|
|
CBlock block; |
|
|
|
|
if (!ReadBlockFromDisk(block, (*mi).second, consensusParams)) |
|
|
|
|
assert(!"cannot load block from disk"); |
|
|
|
|
std::shared_ptr<const CBlock> pblock; |
|
|
|
|
if (a_recent_block && a_recent_block->GetHash() == (*mi).second->GetBlockHash()) { |
|
|
|
|
pblock = a_recent_block; |
|
|
|
|
} else { |
|
|
|
|
// Send block from disk
|
|
|
|
|
std::shared_ptr<CBlock> pblockRead = std::make_shared<CBlock>(); |
|
|
|
|
if (!ReadBlockFromDisk(*pblockRead, (*mi).second, consensusParams)) |
|
|
|
|
assert(!"cannot load block from disk"); |
|
|
|
|
pblock = pblockRead; |
|
|
|
|
} |
|
|
|
|
if (inv.type == MSG_BLOCK) |
|
|
|
|
connman.PushMessage(pfrom, msgMaker.Make(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::BLOCK, block)); |
|
|
|
|
connman.PushMessage(pfrom, msgMaker.Make(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::BLOCK, *pblock)); |
|
|
|
|
else if (inv.type == MSG_WITNESS_BLOCK) |
|
|
|
|
connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::BLOCK, block)); |
|
|
|
|
connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::BLOCK, *pblock)); |
|
|
|
|
else if (inv.type == MSG_FILTERED_BLOCK) |
|
|
|
|
{ |
|
|
|
|
bool sendMerkleBlock = false; |
|
|
|
@ -1042,7 +1050,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
@@ -1042,7 +1050,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
|
|
|
|
|
LOCK(pfrom->cs_filter); |
|
|
|
|
if (pfrom->pfilter) { |
|
|
|
|
sendMerkleBlock = true; |
|
|
|
|
merkleBlock = CMerkleBlock(block, *pfrom->pfilter); |
|
|
|
|
merkleBlock = CMerkleBlock(*pblock, *pfrom->pfilter); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (sendMerkleBlock) { |
|
|
|
@ -1055,7 +1063,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
@@ -1055,7 +1063,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
|
|
|
|
|
// however we MUST always provide at least what the remote peer needs
|
|
|
|
|
typedef std::pair<unsigned int, uint256> PairType; |
|
|
|
|
BOOST_FOREACH(PairType& pair, merkleBlock.vMatchedTxn) |
|
|
|
|
connman.PushMessage(pfrom, msgMaker.Make(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::TX, *block.vtx[pair.first])); |
|
|
|
|
connman.PushMessage(pfrom, msgMaker.Make(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::TX, *pblock->vtx[pair.first])); |
|
|
|
|
} |
|
|
|
|
// else
|
|
|
|
|
// no response
|
|
|
|
@ -1069,10 +1077,15 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
@@ -1069,10 +1077,15 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
|
|
|
|
|
bool fPeerWantsWitness = State(pfrom->GetId())->fWantsCmpctWitness; |
|
|
|
|
int nSendFlags = fPeerWantsWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS; |
|
|
|
|
if (CanDirectFetch(consensusParams) && mi->second->nHeight >= chainActive.Height() - MAX_CMPCTBLOCK_DEPTH) { |
|
|
|
|
CBlockHeaderAndShortTxIDs cmpctblock(block, fPeerWantsWitness); |
|
|
|
|
connman.PushMessage(pfrom, msgMaker.Make(nSendFlags, NetMsgType::CMPCTBLOCK, cmpctblock)); |
|
|
|
|
} else |
|
|
|
|
connman.PushMessage(pfrom, msgMaker.Make(nSendFlags, NetMsgType::BLOCK, block)); |
|
|
|
|
if (fPeerWantsWitness && a_recent_compact_block && a_recent_compact_block->header.GetHash() == mi->second->GetBlockHash()) { |
|
|
|
|
connman.PushMessage(pfrom, msgMaker.Make(nSendFlags, NetMsgType::CMPCTBLOCK, *a_recent_compact_block)); |
|
|
|
|
} else { |
|
|
|
|
CBlockHeaderAndShortTxIDs cmpctblock(*pblock, fPeerWantsWitness); |
|
|
|
|
connman.PushMessage(pfrom, msgMaker.Make(nSendFlags, NetMsgType::CMPCTBLOCK, cmpctblock)); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
connman.PushMessage(pfrom, msgMaker.Make(nSendFlags, NetMsgType::BLOCK, *pblock)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Trigger the peer node to send a getblocks request for the next batch of inventory
|
|
|
|
|