Changeset View
Changeset View
Standalone View
Standalone View
src/net_processing.cpp
Show First 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | |||||
static size_t vExtraTxnForCompactIt = 0; | static size_t vExtraTxnForCompactIt = 0; | ||||
static std::vector<std::pair<uint256, CTransactionRef>> | static std::vector<std::pair<uint256, CTransactionRef>> | ||||
vExtraTxnForCompact GUARDED_BY(cs_main); | vExtraTxnForCompact GUARDED_BY(cs_main); | ||||
// SHA256("main address relay")[0:8] | // SHA256("main address relay")[0:8] | ||||
static const uint64_t RANDOMIZER_ID_ADDRESS_RELAY = 0x3cac0035b5866b90ULL; | static const uint64_t RANDOMIZER_ID_ADDRESS_RELAY = 0x3cac0035b5866b90ULL; | ||||
/// Age after which a stale block will no longer be served if requested as | |||||
/// protection against fingerprinting. Set to one month, denominated in seconds. | |||||
static const int STALE_RELAY_AGE_LIMIT = 30 * 24 * 60 * 60; | |||||
/// Age after which a block is considered historical for purposes of rate | |||||
/// limiting block relay. Set to one week, denominated in seconds. | |||||
static const int HISTORICAL_BLOCK_AGE = 7 * 24 * 60 * 60; | |||||
// Internal stuff | // Internal stuff | ||||
namespace { | namespace { | ||||
/** Number of nodes with fSyncStarted. */ | /** Number of nodes with fSyncStarted. */ | ||||
int nSyncStarted GUARDED_BY(cs_main) = 0; | int nSyncStarted GUARDED_BY(cs_main) = 0; | ||||
/** | /** | ||||
* Sources of received blocks, saved to be able to send them reject messages or | * Sources of received blocks, saved to be able to send them reject messages or | ||||
* ban them when processing happens afterwards. | * ban them when processing happens afterwards. | ||||
▲ Show 20 Lines • Show All 841 Lines • ▼ Show 20 Lines | static void Misbehaving(CNode *node, int howmuch, const std::string &reason) | ||||
Misbehaving(node->GetId(), howmuch, reason); | Misbehaving(node->GetId(), howmuch, reason); | ||||
} | } | ||||
////////////////////////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////////////////////////// | ||||
// | // | ||||
// blockchain -> download logic notification | // blockchain -> download logic notification | ||||
// | // | ||||
// To prevent fingerprinting attacks, only send blocks/headers outside of the | |||||
// active chain if they are no more than a month older (both in time, and in | |||||
// best equivalent proof of work) than the best header chain we know about. | |||||
static bool StaleBlockRequestAllowed(const CBlockIndex *pindex, | |||||
const Consensus::Params &consensusParams) { | |||||
AssertLockHeld(cs_main); | |||||
return (pindexBestHeader != nullptr) && | |||||
(pindexBestHeader->GetBlockTime() - pindex->GetBlockTime() < | |||||
STALE_RELAY_AGE_LIMIT) && | |||||
(GetBlockProofEquivalentTime(*pindexBestHeader, *pindex, | |||||
*pindexBestHeader, consensusParams) < | |||||
STALE_RELAY_AGE_LIMIT); | |||||
} | |||||
PeerLogicValidation::PeerLogicValidation(CConnman *connmanIn, | PeerLogicValidation::PeerLogicValidation(CConnman *connmanIn, | ||||
CScheduler &scheduler) | CScheduler &scheduler) | ||||
: connman(connmanIn), m_stale_tip_check_time(0) { | : connman(connmanIn), 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)); | ||||
const Consensus::Params &consensusParams = Params().GetConsensus(); | const Consensus::Params &consensusParams = Params().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 | ||||
▲ Show 20 Lines • Show All 314 Lines • ▼ Show 20 Lines | while (it != pfrom->vRecvGetData.end()) { | ||||
a_recent_block = most_recent_block; | a_recent_block = most_recent_block; | ||||
} | } | ||||
CValidationState dummy; | CValidationState dummy; | ||||
ActivateBestChain(config, dummy, a_recent_block); | ActivateBestChain(config, dummy, a_recent_block); | ||||
} | } | ||||
if (chainActive.Contains(mi->second)) { | if (chainActive.Contains(mi->second)) { | ||||
send = true; | send = true; | ||||
} else { | } else { | ||||
static const int nOneMonth = 30 * 24 * 60 * 60; | |||||
// To prevent fingerprinting attacks, only send blocks | |||||
// outside of the active chain if they are valid, and no | |||||
// more than a month older (both in time, and in best | |||||
// equivalent proof of work) than the best header chain | |||||
// we know about. | |||||
send = mi->second->IsValid(BlockValidity::SCRIPTS) && | send = mi->second->IsValid(BlockValidity::SCRIPTS) && | ||||
(pindexBestHeader != nullptr) && | StaleBlockRequestAllowed(mi->second, | ||||
(pindexBestHeader->GetBlockTime() - | consensusParams); | ||||
mi->second->GetBlockTime() < | |||||
nOneMonth) && | |||||
(GetBlockProofEquivalentTime( | |||||
*pindexBestHeader, *mi->second, | |||||
*pindexBestHeader, | |||||
consensusParams) < nOneMonth); | |||||
if (!send) { | if (!send) { | ||||
LogPrintf("%s: ignoring request from peer=%i for " | LogPrintf("%s: ignoring request from peer=%i for " | ||||
"old block that isn't in the main " | "old block that isn't in the main " | ||||
"chain\n", | "chain\n", | ||||
__func__, pfrom->GetId()); | __func__, pfrom->GetId()); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
// Disconnect node in case we have reached the outbound limit | // Disconnect node in case we have reached the outbound limit | ||||
// for serving historical blocks never disconnect whitelisted | // for serving historical blocks. | ||||
// nodes. | // Never disconnect whitelisted nodes. | ||||
// assume > 1 week = historical | |||||
static const int nOneWeek = 7 * 24 * 60 * 60; | |||||
if (send && connman->OutboundTargetReached(true) && | if (send && connman->OutboundTargetReached(true) && | ||||
(((pindexBestHeader != nullptr) && | (((pindexBestHeader != nullptr) && | ||||
(pindexBestHeader->GetBlockTime() - | (pindexBestHeader->GetBlockTime() - | ||||
mi->second->GetBlockTime() > | mi->second->GetBlockTime() > | ||||
nOneWeek)) || | HISTORICAL_BLOCK_AGE)) || | ||||
inv.type == MSG_FILTERED_BLOCK) && | inv.type == MSG_FILTERED_BLOCK) && | ||||
!pfrom->fWhitelisted) { | !pfrom->fWhitelisted) { | ||||
LogPrint(BCLog::NET, "historical block serving limit " | LogPrint(BCLog::NET, "historical block serving limit " | ||||
"reached, disconnect peer=%d\n", | "reached, disconnect peer=%d\n", | ||||
pfrom->GetId()); | pfrom->GetId()); | ||||
// disconnect node | // disconnect node | ||||
pfrom->fDisconnect = true; | pfrom->fDisconnect = true; | ||||
▲ Show 20 Lines • Show All 1,039 Lines • ▼ Show 20 Lines | else if (strCommand == 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 | ||||
BlockMap::iterator mi = mapBlockIndex.find(hashStop); | BlockMap::iterator mi = mapBlockIndex.find(hashStop); | ||||
if (mi == mapBlockIndex.end()) { | if (mi == mapBlockIndex.end()) { | ||||
return true; | return true; | ||||
} | } | ||||
pindex = (*mi).second; | pindex = (*mi).second; | ||||
if (!chainActive.Contains(pindex) && | |||||
!StaleBlockRequestAllowed(pindex, chainparams.GetConsensus())) { | |||||
LogPrintf("%s: ignoring request from peer=%i for old block " | |||||
"header that isn't in the main chain\n", | |||||
__func__, pfrom->GetId()); | |||||
return true; | |||||
} | |||||
} else { | } else { | ||||
// Find the last block the caller has in the main chain | // Find the last block the caller has in the main chain | ||||
pindex = FindForkInGlobalIndex(chainActive, locator); | pindex = FindForkInGlobalIndex(chainActive, locator); | ||||
if (pindex) { | if (pindex) { | ||||
pindex = chainActive.Next(pindex); | pindex = chainActive.Next(pindex); | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,910 Lines • Show Last 20 Lines |