Skip to content

Commit efc135f

Browse files
committed
Use cached [compact] blocks to respond to getdata messages
1 parent 1c2edd9 commit efc135f

File tree

1 file changed

+30
-17
lines changed

1 file changed

+30
-17
lines changed

src/net_processing.cpp

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,13 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
979979
{
980980
bool send = false;
981981
BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
982+
std::shared_ptr<const CBlock> a_recent_block;
983+
std::shared_ptr<const CBlockHeaderAndShortTxIDs> a_recent_compact_block;
984+
{
985+
LOCK(cs_most_recent_block);
986+
a_recent_block = most_recent_block;
987+
a_recent_compact_block = most_recent_compact_block;
988+
}
982989
if (mi != mapBlockIndex.end())
983990
{
984991
if (mi->second->nChainTx && !mi->second->IsValid(BLOCK_VALID_SCRIPTS) &&
@@ -988,11 +995,6 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
988995
// before ActivateBestChain but after AcceptBlock).
989996
// In this case, we need to run ActivateBestChain prior to checking the relay
990997
// conditions below.
991-
std::shared_ptr<const CBlock> a_recent_block;
992-
{
993-
LOCK(cs_most_recent_block);
994-
a_recent_block = most_recent_block;
995-
}
996998
CValidationState dummy;
997999
ActivateBestChain(dummy, Params(), a_recent_block);
9981000
}
@@ -1026,14 +1028,20 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
10261028
// it's available before trying to send.
10271029
if (send && (mi->second->nStatus & BLOCK_HAVE_DATA))
10281030
{
1029-
// Send block from disk
1030-
CBlock block;
1031-
if (!ReadBlockFromDisk(block, (*mi).second, consensusParams))
1032-
assert(!"cannot load block from disk");
1031+
std::shared_ptr<const CBlock> pblock;
1032+
if (a_recent_block && a_recent_block->GetHash() == (*mi).second->GetBlockHash()) {
1033+
pblock = a_recent_block;
1034+
} else {
1035+
// Send block from disk
1036+
std::shared_ptr<CBlock> pblockRead = std::make_shared<CBlock>();
1037+
if (!ReadBlockFromDisk(*pblockRead, (*mi).second, consensusParams))
1038+
assert(!"cannot load block from disk");
1039+
pblock = pblockRead;
1040+
}
10331041
if (inv.type == MSG_BLOCK)
1034-
connman.PushMessage(pfrom, msgMaker.Make(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::BLOCK, block));
1042+
connman.PushMessage(pfrom, msgMaker.Make(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::BLOCK, *pblock));
10351043
else if (inv.type == MSG_WITNESS_BLOCK)
1036-
connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::BLOCK, block));
1044+
connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::BLOCK, *pblock));
10371045
else if (inv.type == MSG_FILTERED_BLOCK)
10381046
{
10391047
bool sendMerkleBlock = false;
@@ -1042,7 +1050,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
10421050
LOCK(pfrom->cs_filter);
10431051
if (pfrom->pfilter) {
10441052
sendMerkleBlock = true;
1045-
merkleBlock = CMerkleBlock(block, *pfrom->pfilter);
1053+
merkleBlock = CMerkleBlock(*pblock, *pfrom->pfilter);
10461054
}
10471055
}
10481056
if (sendMerkleBlock) {
@@ -1055,7 +1063,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
10551063
// however we MUST always provide at least what the remote peer needs
10561064
typedef std::pair<unsigned int, uint256> PairType;
10571065
BOOST_FOREACH(PairType& pair, merkleBlock.vMatchedTxn)
1058-
connman.PushMessage(pfrom, msgMaker.Make(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::TX, *block.vtx[pair.first]));
1066+
connman.PushMessage(pfrom, msgMaker.Make(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::TX, *pblock->vtx[pair.first]));
10591067
}
10601068
// else
10611069
// no response
@@ -1069,10 +1077,15 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
10691077
bool fPeerWantsWitness = State(pfrom->GetId())->fWantsCmpctWitness;
10701078
int nSendFlags = fPeerWantsWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS;
10711079
if (CanDirectFetch(consensusParams) && mi->second->nHeight >= chainActive.Height() - MAX_CMPCTBLOCK_DEPTH) {
1072-
CBlockHeaderAndShortTxIDs cmpctblock(block, fPeerWantsWitness);
1073-
connman.PushMessage(pfrom, msgMaker.Make(nSendFlags, NetMsgType::CMPCTBLOCK, cmpctblock));
1074-
} else
1075-
connman.PushMessage(pfrom, msgMaker.Make(nSendFlags, NetMsgType::BLOCK, block));
1080+
if (fPeerWantsWitness && a_recent_compact_block && a_recent_compact_block->header.GetHash() == mi->second->GetBlockHash()) {
1081+
connman.PushMessage(pfrom, msgMaker.Make(nSendFlags, NetMsgType::CMPCTBLOCK, *a_recent_compact_block));
1082+
} else {
1083+
CBlockHeaderAndShortTxIDs cmpctblock(*pblock, fPeerWantsWitness);
1084+
connman.PushMessage(pfrom, msgMaker.Make(nSendFlags, NetMsgType::CMPCTBLOCK, cmpctblock));
1085+
}
1086+
} else {
1087+
connman.PushMessage(pfrom, msgMaker.Make(nSendFlags, NetMsgType::BLOCK, *pblock));
1088+
}
10761089
}
10771090

10781091
// Trigger the peer node to send a getblocks request for the next batch of inventory

0 commit comments

Comments
 (0)