Changeset View
Changeset View
Standalone View
Standalone View
src/net_processing.cpp
Show First 20 Lines • Show All 1,481 Lines • ▼ Show 20 Lines | return pindex->IsValid(BlockValidity::SCRIPTS) && | ||||
(pindexBestHeader != nullptr) && | (pindexBestHeader != nullptr) && | ||||
(pindexBestHeader->GetBlockTime() - pindex->GetBlockTime() < | (pindexBestHeader->GetBlockTime() - pindex->GetBlockTime() < | ||||
STALE_RELAY_AGE_LIMIT) && | STALE_RELAY_AGE_LIMIT) && | ||||
(GetBlockProofEquivalentTime(*pindexBestHeader, *pindex, | (GetBlockProofEquivalentTime(*pindexBestHeader, *pindex, | ||||
*pindexBestHeader, consensusParams) < | *pindexBestHeader, consensusParams) < | ||||
STALE_RELAY_AGE_LIMIT); | STALE_RELAY_AGE_LIMIT); | ||||
} | } | ||||
PeerLogicValidation::PeerLogicValidation(CConnman &connman, BanMan *banman, | PeerLogicValidation::PeerLogicValidation(const CChainParams &chainparams, | ||||
CConnman &connman, BanMan *banman, | |||||
CScheduler &scheduler, | CScheduler &scheduler, | ||||
ChainstateManager &chainman, | ChainstateManager &chainman, | ||||
CTxMemPool &pool) | CTxMemPool &pool) | ||||
: m_connman(connman), m_banman(banman), m_chainman(chainman), | : m_chainparams(chainparams), m_connman(connman), m_banman(banman), | ||||
m_mempool(pool), m_stale_tip_check_time(0) { | m_chainman(chainman), m_mempool(pool), m_stale_tip_check_time(0) { | ||||
// Initialize global variables that cannot be constructed at startup. | // Initialize global variables that cannot be constructed at startup. | ||||
recentRejects.reset(new CRollingBloomFilter(120000, 0.000001)); | recentRejects.reset(new CRollingBloomFilter(120000, 0.000001)); | ||||
// Blocks don't typically have more than 4000 transactions, so this should | // Blocks don't typically have more than 4000 transactions, so this should | ||||
// be at least six blocks (~1 hr) worth of transactions that we can store. | // be at least six blocks (~1 hr) worth of transactions that we can store. | ||||
// If the number of transactions appearing in a block goes up, or if we are | // If the number of transactions appearing in a block goes up, or if we are | ||||
// seeing getdata requests more than an hour after initial announcement, we | // seeing getdata requests more than an hour after initial announcement, we | ||||
// can increase this number. | // can increase this number. | ||||
// The false positive rate of 1/1M should come out to less than 1 | // The false positive rate of 1/1M should come out to less than 1 | ||||
// transaction per day that would be inadvertently ignored (which is the | // transaction per day that would be inadvertently ignored (which is the | ||||
// same probability that we have in the reject filter). | // same probability that we have in the reject filter). | ||||
g_recent_confirmed_transactions.reset( | g_recent_confirmed_transactions.reset( | ||||
new CRollingBloomFilter(24000, 0.000001)); | new CRollingBloomFilter(24000, 0.000001)); | ||||
const Consensus::Params &consensusParams = Params().GetConsensus(); | const Consensus::Params &consensusParams = chainparams.GetConsensus(); | ||||
// Stale tip checking and peer eviction are on two different timers, but we | // Stale tip checking and peer eviction are on two different timers, but we | ||||
// don't want them to get out of sync due to drift in the scheduler, so we | // don't want them to get out of sync due to drift in the scheduler, so we | ||||
// combine them in one function and schedule at the quicker (peer-eviction) | // combine them in one function and schedule at the quicker (peer-eviction) | ||||
// timer. | // timer. | ||||
static_assert( | static_assert( | ||||
EXTRA_PEER_CHECK_INTERVAL < STALE_CHECK_INTERVAL, | EXTRA_PEER_CHECK_INTERVAL < STALE_CHECK_INTERVAL, | ||||
"peer eviction timer should be less than stale tip check timer"); | "peer eviction timer should be less than stale tip check timer"); | ||||
scheduler.scheduleEvery( | scheduler.scheduleEvery( | ||||
▲ Show 20 Lines • Show All 1,150 Lines • ▼ Show 20 Lines | CSerializedNetMsg msg = CNetMsgMaker(peer.GetSendVersion()) | ||||
stop_index->GetBlockHash(), headers); | stop_index->GetBlockHash(), headers); | ||||
connman.PushMessage(&peer, std::move(msg)); | connman.PushMessage(&peer, std::move(msg)); | ||||
} | } | ||||
void PeerLogicValidation::ProcessMessage( | void PeerLogicValidation::ProcessMessage( | ||||
const Config &config, CNode &pfrom, const std::string &msg_type, | const Config &config, CNode &pfrom, const std::string &msg_type, | ||||
CDataStream &vRecv, int64_t nTimeReceived, | CDataStream &vRecv, int64_t nTimeReceived, | ||||
const std::atomic<bool> &interruptMsgProc) { | const std::atomic<bool> &interruptMsgProc) { | ||||
const CChainParams &chainparams = config.GetChainParams(); | |||||
LogPrint(BCLog::NET, "received: %s (%u bytes) peer=%d\n", | LogPrint(BCLog::NET, "received: %s (%u bytes) peer=%d\n", | ||||
SanitizeString(msg_type), vRecv.size(), pfrom.GetId()); | SanitizeString(msg_type), vRecv.size(), pfrom.GetId()); | ||||
if (gArgs.IsArgSet("-dropmessagestest") && | if (gArgs.IsArgSet("-dropmessagestest") && | ||||
GetRand(gArgs.GetArg("-dropmessagestest", 0)) == 0) { | GetRand(gArgs.GetArg("-dropmessagestest", 0)) == 0) { | ||||
LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n"); | LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n"); | ||||
return; | return; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 164 Lines • ▼ Show 20 Lines | if (msg_type == NetMsgType::VERSION) { | ||||
"us=%s, peer=%d%s\n", | "us=%s, peer=%d%s\n", | ||||
pfrom.addr.ToString(), cleanSubVer, pfrom.nVersion, | pfrom.addr.ToString(), cleanSubVer, pfrom.nVersion, | ||||
pfrom.nStartingHeight, addrMe.ToString(), pfrom.GetId(), | pfrom.nStartingHeight, addrMe.ToString(), pfrom.GetId(), | ||||
remoteAddr); | remoteAddr); | ||||
// Ignore time offsets that are improbable (before the Genesis block) | // Ignore time offsets that are improbable (before the Genesis block) | ||||
// and may underflow the nTimeOffset calculation. | // and may underflow the nTimeOffset calculation. | ||||
int64_t currentTime = GetTime(); | int64_t currentTime = GetTime(); | ||||
if (nTime >= int64_t(chainparams.GenesisBlock().nTime)) { | if (nTime >= int64_t(m_chainparams.GenesisBlock().nTime)) { | ||||
int64_t nTimeOffset = nTime - currentTime; | int64_t nTimeOffset = nTime - currentTime; | ||||
pfrom.nTimeOffset = nTimeOffset; | pfrom.nTimeOffset = nTimeOffset; | ||||
AddTimeData(pfrom.addr, nTimeOffset); | AddTimeData(pfrom.addr, nTimeOffset); | ||||
} else { | } else { | ||||
Misbehaving(pfrom, 20, | Misbehaving(pfrom, 20, | ||||
"Ignoring invalid timestamp in version message"); | "Ignoring invalid timestamp in version message"); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 311 Lines • ▼ Show 20 Lines | if (msg_type == NetMsgType::GETBLOCKS) { | ||||
pindex->nHeight, pindex->GetBlockHash().ToString()); | pindex->nHeight, pindex->GetBlockHash().ToString()); | ||||
break; | break; | ||||
} | } | ||||
// If pruning, don't inv blocks unless we have on disk and are | // If pruning, don't inv blocks unless we have on disk and are | ||||
// likely to still have for some reasonable time window (1 hour) | // likely to still have for some reasonable time window (1 hour) | ||||
// that block relay might require. | // that block relay might require. | ||||
const int nPrunedBlocksLikelyToHave = | const int nPrunedBlocksLikelyToHave = | ||||
MIN_BLOCKS_TO_KEEP - | MIN_BLOCKS_TO_KEEP - | ||||
3600 / chainparams.GetConsensus().nPowTargetSpacing; | 3600 / m_chainparams.GetConsensus().nPowTargetSpacing; | ||||
if (fPruneMode && | if (fPruneMode && | ||||
(!pindex->nStatus.hasData() || | (!pindex->nStatus.hasData() || | ||||
pindex->nHeight <= ::ChainActive().Tip()->nHeight - | pindex->nHeight <= ::ChainActive().Tip()->nHeight - | ||||
nPrunedBlocksLikelyToHave)) { | nPrunedBlocksLikelyToHave)) { | ||||
LogPrint( | LogPrint( | ||||
BCLog::NET, | BCLog::NET, | ||||
" getblocks stopping, pruned or too old block at %d %s\n", | " getblocks stopping, pruned or too old block at %d %s\n", | ||||
pindex->nHeight, pindex->GetBlockHash().ToString()); | pindex->nHeight, pindex->GetBlockHash().ToString()); | ||||
▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | if (msg_type == NetMsgType::GETBLOCKTXN) { | ||||
inv.hash = req.blockhash; | inv.hash = req.blockhash; | ||||
pfrom.vRecvGetData.push_back(inv); | pfrom.vRecvGetData.push_back(inv); | ||||
// The message processing loop will go around again (without | // The message processing loop will go around again (without | ||||
// pausing) and we'll respond then (without cs_main) | // pausing) and we'll respond then (without cs_main) | ||||
return; | return; | ||||
} | } | ||||
CBlock block; | CBlock block; | ||||
bool ret = ReadBlockFromDisk(block, pindex, chainparams.GetConsensus()); | bool ret = | ||||
ReadBlockFromDisk(block, pindex, m_chainparams.GetConsensus()); | |||||
assert(ret); | assert(ret); | ||||
SendBlockTransactions(block, req, pfrom, m_connman); | SendBlockTransactions(block, req, pfrom, m_connman); | ||||
return; | return; | ||||
} | } | ||||
if (msg_type == NetMsgType::GETHEADERS) { | if (msg_type == NetMsgType::GETHEADERS) { | ||||
CBlockLocator locator; | CBlockLocator locator; | ||||
Show All 22 Lines | if (msg_type == NetMsgType::GETHEADERS) { | ||||
const CBlockIndex *pindex = nullptr; | const CBlockIndex *pindex = nullptr; | ||||
if (locator.IsNull()) { | if (locator.IsNull()) { | ||||
// If locator is null, return the hashStop block | // If locator is null, return the hashStop block | ||||
pindex = LookupBlockIndex(hashStop); | pindex = LookupBlockIndex(hashStop); | ||||
if (!pindex) { | if (!pindex) { | ||||
return; | return; | ||||
} | } | ||||
if (!BlockRequestAllowed(pindex, chainparams.GetConsensus())) { | if (!BlockRequestAllowed(pindex, m_chainparams.GetConsensus())) { | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"%s: ignoring request from peer=%i for old block " | "%s: ignoring request from peer=%i for old block " | ||||
"header that isn't in the main chain\n", | "header that isn't in the main chain\n", | ||||
__func__, pfrom.GetId()); | __func__, pfrom.GetId()); | ||||
return; | return; | ||||
} | } | ||||
} else { | } else { | ||||
// Find the last block the caller has in the main chain | // Find the last block the caller has in the main chain | ||||
▲ Show 20 Lines • Show All 295 Lines • ▼ Show 20 Lines | if (msg_type == NetMsgType::CMPCTBLOCK) { | ||||
&pfrom, msgMaker.Make(NetMsgType::GETDATA, vInv)); | &pfrom, msgMaker.Make(NetMsgType::GETDATA, vInv)); | ||||
} | } | ||||
return; | return; | ||||
} | } | ||||
// If we're not close to tip yet, give up and let parallel block | // If we're not close to tip yet, give up and let parallel block | ||||
// fetch work its magic. | // fetch work its magic. | ||||
if (!fAlreadyInFlight && | if (!fAlreadyInFlight && | ||||
!CanDirectFetch(chainparams.GetConsensus())) { | !CanDirectFetch(m_chainparams.GetConsensus())) { | ||||
return; | return; | ||||
} | } | ||||
// We want to be a bit conservative just to be extra careful about | // We want to be a bit conservative just to be extra careful about | ||||
// DoS possibilities in compact block processing... | // DoS possibilities in compact block processing... | ||||
if (pindex->nHeight <= ::ChainActive().Height() + 2) { | if (pindex->nHeight <= ::ChainActive().Height() + 2) { | ||||
if ((!fAlreadyInFlight && nodestate->nBlocksInFlight < | if ((!fAlreadyInFlight && nodestate->nBlocksInFlight < | ||||
MAX_BLOCKS_IN_TRANSIT_PER_PEER) || | MAX_BLOCKS_IN_TRANSIT_PER_PEER) || | ||||
(fAlreadyInFlight && | (fAlreadyInFlight && | ||||
blockInFlightIt->second.first == pfrom.GetId())) { | blockInFlightIt->second.first == pfrom.GetId())) { | ||||
std::list<QueuedBlock>::iterator *queuedBlockIt = nullptr; | std::list<QueuedBlock>::iterator *queuedBlockIt = nullptr; | ||||
if (!MarkBlockAsInFlight(config, m_mempool, pfrom.GetId(), | if (!MarkBlockAsInFlight(config, m_mempool, pfrom.GetId(), | ||||
pindex->GetBlockHash(), | pindex->GetBlockHash(), | ||||
chainparams.GetConsensus(), pindex, | m_chainparams.GetConsensus(), | ||||
&queuedBlockIt)) { | pindex, &queuedBlockIt)) { | ||||
if (!(*queuedBlockIt)->partialBlock) { | if (!(*queuedBlockIt)->partialBlock) { | ||||
(*queuedBlockIt) | (*queuedBlockIt) | ||||
->partialBlock.reset( | ->partialBlock.reset( | ||||
new PartiallyDownloadedBlock(config, | new PartiallyDownloadedBlock(config, | ||||
&m_mempool)); | &m_mempool)); | ||||
} else { | } else { | ||||
// The block was already in flight using compact | // The block was already in flight using compact | ||||
// blocks from the same peer. | // blocks from the same peer. | ||||
▲ Show 20 Lines • Show All 724 Lines • ▼ Show 20 Lines | if (msg_type == NetMsgType::FEEFILTER) { | ||||
} | } | ||||
LogPrint(BCLog::NET, "received: feefilter of %s from peer=%d\n", | LogPrint(BCLog::NET, "received: feefilter of %s from peer=%d\n", | ||||
CFeeRate(newFeeFilter).ToString(), pfrom.GetId()); | CFeeRate(newFeeFilter).ToString(), pfrom.GetId()); | ||||
} | } | ||||
return; | return; | ||||
} | } | ||||
if (msg_type == NetMsgType::GETCFILTERS) { | if (msg_type == NetMsgType::GETCFILTERS) { | ||||
ProcessGetCFilters(pfrom, vRecv, chainparams, m_connman); | ProcessGetCFilters(pfrom, vRecv, m_chainparams, m_connman); | ||||
return; | return; | ||||
} | } | ||||
if (msg_type == NetMsgType::GETCFHEADERS) { | if (msg_type == NetMsgType::GETCFHEADERS) { | ||||
ProcessGetCFHeaders(pfrom, vRecv, chainparams, m_connman); | ProcessGetCFHeaders(pfrom, vRecv, m_chainparams, m_connman); | ||||
return; | return; | ||||
} | } | ||||
if (msg_type == NetMsgType::GETCFCHECKPT) { | if (msg_type == NetMsgType::GETCFCHECKPT) { | ||||
ProcessGetCFCheckPt(pfrom, vRecv, chainparams, m_connman); | ProcessGetCFCheckPt(pfrom, vRecv, m_chainparams, m_connman); | ||||
return; | return; | ||||
} | } | ||||
if (msg_type == NetMsgType::NOTFOUND) { | if (msg_type == NetMsgType::NOTFOUND) { | ||||
// Remove the NOTFOUND transactions from the peer | // Remove the NOTFOUND transactions from the peer | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
CNodeState *state = State(pfrom.GetId()); | CNodeState *state = State(pfrom.GetId()); | ||||
std::vector<CInv> vInv; | std::vector<CInv> vInv; | ||||
▲ Show 20 Lines • Show All 1,157 Lines • Show Last 20 Lines |