@@ -979,6 +979,13 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
979
979
{
980
980
bool send = false ;
981
981
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
+ }
982
989
if (mi != mapBlockIndex.end ())
983
990
{
984
991
if (mi->second ->nChainTx && !mi->second ->IsValid (BLOCK_VALID_SCRIPTS) &&
@@ -988,11 +995,6 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
988
995
// before ActivateBestChain but after AcceptBlock).
989
996
// In this case, we need to run ActivateBestChain prior to checking the relay
990
997
// 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
- }
996
998
CValidationState dummy;
997
999
ActivateBestChain (dummy, Params (), a_recent_block);
998
1000
}
@@ -1026,14 +1028,20 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
1026
1028
// it's available before trying to send.
1027
1029
if (send && (mi->second ->nStatus & BLOCK_HAVE_DATA))
1028
1030
{
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
+ }
1033
1041
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 ));
1035
1043
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 ));
1037
1045
else if (inv.type == MSG_FILTERED_BLOCK)
1038
1046
{
1039
1047
bool sendMerkleBlock = false ;
@@ -1042,7 +1050,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
1042
1050
LOCK (pfrom->cs_filter );
1043
1051
if (pfrom->pfilter ) {
1044
1052
sendMerkleBlock = true ;
1045
- merkleBlock = CMerkleBlock (block , *pfrom->pfilter );
1053
+ merkleBlock = CMerkleBlock (*pblock , *pfrom->pfilter );
1046
1054
}
1047
1055
}
1048
1056
if (sendMerkleBlock) {
@@ -1055,7 +1063,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
1055
1063
// however we MUST always provide at least what the remote peer needs
1056
1064
typedef std::pair<unsigned int , uint256> PairType;
1057
1065
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 ]));
1059
1067
}
1060
1068
// else
1061
1069
// no response
@@ -1069,10 +1077,15 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
1069
1077
bool fPeerWantsWitness = State (pfrom->GetId ())->fWantsCmpctWitness ;
1070
1078
int nSendFlags = fPeerWantsWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS;
1071
1079
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
+ }
1076
1089
}
1077
1090
1078
1091
// Trigger the peer node to send a getblocks request for the next batch of inventory
0 commit comments