|
|
@ -1038,29 +1038,11 @@ static void RelayAddress(const CAddress& addr, bool fReachable, CConnman* connma |
|
|
|
connman->ForEachNodeThen(std::move(sortfunc), std::move(pushfunc)); |
|
|
|
connman->ForEachNodeThen(std::move(sortfunc), std::move(pushfunc)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParams, CConnman* connman, const std::atomic<bool>& interruptMsgProc) |
|
|
|
void static ProcessGetBlockData(CNode* pfrom, const Consensus::Params& consensusParams, const CInv& inv, CConnman* connman, const std::atomic<bool>& interruptMsgProc) |
|
|
|
{ |
|
|
|
{ |
|
|
|
std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin(); |
|
|
|
|
|
|
|
std::vector<CInv> vNotFound; |
|
|
|
|
|
|
|
const CNetMsgMaker msgMaker(pfrom->GetSendVersion()); |
|
|
|
|
|
|
|
LOCK(cs_main); |
|
|
|
LOCK(cs_main); |
|
|
|
|
|
|
|
|
|
|
|
while (it != pfrom->vRecvGetData.end()) { |
|
|
|
|
|
|
|
// Don't bother if send buffer is too full to respond anyway
|
|
|
|
|
|
|
|
if (pfrom->fPauseSend) |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const CInv &inv = *it; |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (interruptMsgProc) |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it++; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK || inv.type == MSG_CMPCT_BLOCK || inv.type == MSG_WITNESS_BLOCK) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
bool send = false; |
|
|
|
bool send = false; |
|
|
|
BlockMap::iterator mi = mapBlockIndex.find(inv.hash); |
|
|
|
|
|
|
|
std::shared_ptr<const CBlock> a_recent_block; |
|
|
|
std::shared_ptr<const CBlock> a_recent_block; |
|
|
|
std::shared_ptr<const CBlockHeaderAndShortTxIDs> a_recent_compact_block; |
|
|
|
std::shared_ptr<const CBlockHeaderAndShortTxIDs> a_recent_compact_block; |
|
|
|
bool fWitnessesPresentInARecentCompactBlock; |
|
|
|
bool fWitnessesPresentInARecentCompactBlock; |
|
|
@ -1070,6 +1052,9 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam |
|
|
|
a_recent_compact_block = most_recent_compact_block; |
|
|
|
a_recent_compact_block = most_recent_compact_block; |
|
|
|
fWitnessesPresentInARecentCompactBlock = fWitnessesPresentInMostRecentCompactBlock; |
|
|
|
fWitnessesPresentInARecentCompactBlock = fWitnessesPresentInMostRecentCompactBlock; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
BlockMap::iterator mi = mapBlockIndex.find(inv.hash); |
|
|
|
if (mi != mapBlockIndex.end()) |
|
|
|
if (mi != mapBlockIndex.end()) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (mi->second->nChainTx && !mi->second->IsValid(BLOCK_VALID_SCRIPTS) && |
|
|
|
if (mi->second->nChainTx && !mi->second->IsValid(BLOCK_VALID_SCRIPTS) && |
|
|
@ -1082,11 +1067,16 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam |
|
|
|
CValidationState dummy; |
|
|
|
CValidationState dummy; |
|
|
|
ActivateBestChain(dummy, Params(), a_recent_block); |
|
|
|
ActivateBestChain(dummy, Params(), a_recent_block); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
BlockMap::iterator mi = mapBlockIndex.find(inv.hash); |
|
|
|
|
|
|
|
if (mi != mapBlockIndex.end()) { |
|
|
|
send = BlockRequestAllowed(mi->second, consensusParams); |
|
|
|
send = BlockRequestAllowed(mi->second, consensusParams); |
|
|
|
if (!send) { |
|
|
|
if (!send) { |
|
|
|
LogPrint(BCLog::NET, "%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->GetId()); |
|
|
|
LogPrint(BCLog::NET, "%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->GetId()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const CNetMsgMaker msgMaker(pfrom->GetSendVersion()); |
|
|
|
// disconnect node in case we have reached the outbound limit for serving historical blocks
|
|
|
|
// disconnect node in case we have reached the outbound limit for serving historical blocks
|
|
|
|
// never disconnect whitelisted nodes
|
|
|
|
// never disconnect whitelisted nodes
|
|
|
|
if (send && connman->OutboundTargetReached(true) && ( ((pindexBestHeader != nullptr) && (pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() > HISTORICAL_BLOCK_AGE)) || inv.type == MSG_FILTERED_BLOCK) && !pfrom->fWhitelisted) |
|
|
|
if (send && connman->OutboundTargetReached(true) && ( ((pindexBestHeader != nullptr) && (pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() > HISTORICAL_BLOCK_AGE)) || inv.type == MSG_FILTERED_BLOCK) && !pfrom->fWhitelisted) |
|
|
@ -1183,9 +1173,26 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam |
|
|
|
pfrom->hashContinue.SetNull(); |
|
|
|
pfrom->hashContinue.SetNull(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else if (inv.type == MSG_TX || inv.type == MSG_WITNESS_TX) |
|
|
|
|
|
|
|
|
|
|
|
void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParams, CConnman* connman, const std::atomic<bool>& interruptMsgProc) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin(); |
|
|
|
|
|
|
|
std::vector<CInv> vNotFound; |
|
|
|
|
|
|
|
const CNetMsgMaker msgMaker(pfrom->GetSendVersion()); |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
LOCK(cs_main); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (it != pfrom->vRecvGetData.end() && (it->type == MSG_TX || it->type == MSG_WITNESS_TX)) { |
|
|
|
|
|
|
|
if (interruptMsgProc) |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
// Don't bother if send buffer is too full to respond anyway
|
|
|
|
|
|
|
|
if (pfrom->fPauseSend) |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const CInv &inv = *it; |
|
|
|
|
|
|
|
it++; |
|
|
|
|
|
|
|
|
|
|
|
// Send stream from relay memory
|
|
|
|
// Send stream from relay memory
|
|
|
|
bool push = false; |
|
|
|
bool push = false; |
|
|
|
auto mi = mapRelay.find(inv.hash); |
|
|
|
auto mi = mapRelay.find(inv.hash); |
|
|
@ -1205,15 +1212,19 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam |
|
|
|
if (!push) { |
|
|
|
if (!push) { |
|
|
|
vNotFound.push_back(inv); |
|
|
|
vNotFound.push_back(inv); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Track requests for our stuff.
|
|
|
|
// Track requests for our stuff.
|
|
|
|
GetMainSignals().Inventory(inv.hash); |
|
|
|
GetMainSignals().Inventory(inv.hash); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK || inv.type == MSG_CMPCT_BLOCK || inv.type == MSG_WITNESS_BLOCK) |
|
|
|
if (it != pfrom->vRecvGetData.end()) { |
|
|
|
break; |
|
|
|
const CInv &inv = *it; |
|
|
|
|
|
|
|
it++; |
|
|
|
|
|
|
|
if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK || inv.type == MSG_CMPCT_BLOCK || inv.type == MSG_WITNESS_BLOCK) { |
|
|
|
|
|
|
|
ProcessGetBlockData(pfrom, consensusParams, inv, connman, interruptMsgProc); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} // release cs_main
|
|
|
|
|
|
|
|
|
|
|
|
pfrom->vRecvGetData.erase(pfrom->vRecvGetData.begin(), it); |
|
|
|
pfrom->vRecvGetData.erase(pfrom->vRecvGetData.begin(), it); |
|
|
|
|
|
|
|
|
|
|
|