Changeset View
Changeset View
Standalone View
Standalone View
src/net_processing.cpp
Show First 20 Lines • Show All 1,393 Lines • ▼ Show 20 Lines | if (state.IsInvalid(nDoS)) { | ||||
} | } | ||||
} | } | ||||
// Check that: | // Check that: | ||||
// 1. The block is valid | // 1. The block is valid | ||||
// 2. We're not in initial block download | // 2. We're not in initial block download | ||||
// 3. This is currently the best block we're aware of. We haven't updated | // 3. This is currently the best block we're aware of. We haven't updated | ||||
// the tip yet so we have no way to check this directly here. Instead we | // the tip yet so we have no way to check this directly here. Instead we | ||||
// just check that there are currently no other blocks in flight. | // just check that there are currently no other blocks in flight. | ||||
else if (state.IsValid() && !IsInitialBlockDownload() && | else if (state.IsValid() && | ||||
!::ChainstateActive().IsInitialBlockDownload() && | |||||
mapBlocksInFlight.count(hash) == mapBlocksInFlight.size()) { | mapBlocksInFlight.count(hash) == mapBlocksInFlight.size()) { | ||||
if (it != mapBlockSource.end()) { | if (it != mapBlockSource.end()) { | ||||
MaybeSetPeerAsAnnouncingHeaderAndIDs(it->second.first, connman); | MaybeSetPeerAsAnnouncingHeaderAndIDs(it->second.first, connman); | ||||
} | } | ||||
} | } | ||||
if (it != mapBlockSource.end()) { | if (it != mapBlockSource.end()) { | ||||
mapBlockSource.erase(it); | mapBlockSource.erase(it); | ||||
▲ Show 20 Lines • Show All 587 Lines • ▼ Show 20 Lines | if (!ProcessNewBlockHeaders(config, headers, state, &pindexLast, | ||||
} | } | ||||
connman->PushMessage( | connman->PushMessage( | ||||
pfrom, msgMaker.Make(NetMsgType::GETDATA, vGetData)); | pfrom, msgMaker.Make(NetMsgType::GETDATA, vGetData)); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
// If we're in IBD, we want outbound peers that will serve us a useful | // If we're in IBD, we want outbound peers that will serve us a useful | ||||
// chain. Disconnect peers that are on chains with insufficient work. | // chain. Disconnect peers that are on chains with insufficient work. | ||||
if (IsInitialBlockDownload() && nCount != MAX_HEADERS_RESULTS) { | if (::ChainstateActive().IsInitialBlockDownload() && | ||||
nCount != MAX_HEADERS_RESULTS) { | |||||
// When nCount < MAX_HEADERS_RESULTS, we know we have no more | // When nCount < MAX_HEADERS_RESULTS, we know we have no more | ||||
// headers to fetch from this peer. | // headers to fetch from this peer. | ||||
if (nodestate->pindexBestKnownBlock && | if (nodestate->pindexBestKnownBlock && | ||||
nodestate->pindexBestKnownBlock->nChainWork < | nodestate->pindexBestKnownBlock->nChainWork < | ||||
nMinimumChainWork) { | nMinimumChainWork) { | ||||
// This peer has too little work on their headers chain to help | // This peer has too little work on their headers chain to help | ||||
// us sync -- disconnect if using an outbound slot (unless | // us sync -- disconnect if using an outbound slot (unless | ||||
// whitelisted or addnode). | // whitelisted or addnode). | ||||
▲ Show 20 Lines • Show All 224 Lines • ▼ Show 20 Lines | if (strCommand == NetMsgType::VERSION) { | ||||
// Potentially mark this peer as a preferred download peer. | // Potentially mark this peer as a preferred download peer. | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
UpdatePreferredDownload(pfrom, State(pfrom->GetId())); | UpdatePreferredDownload(pfrom, State(pfrom->GetId())); | ||||
} | } | ||||
if (!pfrom->fInbound) { | if (!pfrom->fInbound) { | ||||
// Advertise our address | // Advertise our address | ||||
if (fListen && !IsInitialBlockDownload()) { | if (fListen && !::ChainstateActive().IsInitialBlockDownload()) { | ||||
CAddress addr = | CAddress addr = | ||||
GetLocalAddress(&pfrom->addr, pfrom->GetLocalServices()); | GetLocalAddress(&pfrom->addr, pfrom->GetLocalServices()); | ||||
FastRandomContext insecure_rand; | FastRandomContext insecure_rand; | ||||
if (addr.IsRoutable()) { | if (addr.IsRoutable()) { | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"ProcessMessages: advertising address %s\n", | "ProcessMessages: advertising address %s\n", | ||||
addr.ToString()); | addr.ToString()); | ||||
pfrom->PushAddress(addr, insecure_rand); | pfrom->PushAddress(addr, insecure_rand); | ||||
▲ Show 20 Lines • Show All 236 Lines • ▼ Show 20 Lines | if (strCommand == NetMsgType::INV) { | ||||
} else { | } else { | ||||
pfrom->AddInventoryKnown(inv); | pfrom->AddInventoryKnown(inv); | ||||
if (fBlocksOnly) { | if (fBlocksOnly) { | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"transaction (%s) inv sent in violation of " | "transaction (%s) inv sent in violation of " | ||||
"protocol peer=%d\n", | "protocol peer=%d\n", | ||||
inv.hash.ToString(), pfrom->GetId()); | inv.hash.ToString(), pfrom->GetId()); | ||||
} else if (!fAlreadyHave && !fImporting && !fReindex && | } else if (!fAlreadyHave && !fImporting && !fReindex && | ||||
!IsInitialBlockDownload()) { | !::ChainstateActive().IsInitialBlockDownload()) { | ||||
RequestTx(State(pfrom->GetId()), TxId(inv.hash), nNow); | RequestTx(State(pfrom->GetId()), TxId(inv.hash), nNow); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
if (strCommand == NetMsgType::GETDATA) { | if (strCommand == NetMsgType::GETDATA) { | ||||
▲ Show 20 Lines • Show All 167 Lines • ▼ Show 20 Lines | if (strCommand == NetMsgType::GETHEADERS) { | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"getheaders locator size %lld > %d, disconnect peer=%d\n", | "getheaders locator size %lld > %d, disconnect peer=%d\n", | ||||
locator.vHave.size(), MAX_LOCATOR_SZ, pfrom->GetId()); | locator.vHave.size(), MAX_LOCATOR_SZ, pfrom->GetId()); | ||||
pfrom->fDisconnect = true; | pfrom->fDisconnect = true; | ||||
return true; | return true; | ||||
} | } | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
if (IsInitialBlockDownload() && !pfrom->HasPermission(PF_NOBAN)) { | if (::ChainstateActive().IsInitialBlockDownload() && | ||||
!pfrom->HasPermission(PF_NOBAN)) { | |||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"Ignoring getheaders from peer=%d because node is in " | "Ignoring getheaders from peer=%d because node is in " | ||||
"initial block download\n", | "initial block download\n", | ||||
pfrom->GetId()); | pfrom->GetId()); | ||||
return true; | return true; | ||||
} | } | ||||
CNodeState *nodestate = State(pfrom->GetId()); | CNodeState *nodestate = State(pfrom->GetId()); | ||||
▲ Show 20 Lines • Show All 286 Lines • ▼ Show 20 Lines | if (strCommand == NetMsgType::CMPCTBLOCK && !fImporting && !fReindex) { | ||||
bool received_new_header = false; | bool received_new_header = false; | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
if (!LookupBlockIndex(cmpctblock.header.hashPrevBlock)) { | if (!LookupBlockIndex(cmpctblock.header.hashPrevBlock)) { | ||||
// Doesn't connect (or is genesis), instead of DoSing in | // Doesn't connect (or is genesis), instead of DoSing in | ||||
// AcceptBlockHeader, request deeper headers | // AcceptBlockHeader, request deeper headers | ||||
if (!IsInitialBlockDownload()) { | if (!::ChainstateActive().IsInitialBlockDownload()) { | ||||
connman->PushMessage( | connman->PushMessage( | ||||
pfrom, msgMaker.Make( | pfrom, msgMaker.Make( | ||||
NetMsgType::GETHEADERS, | NetMsgType::GETHEADERS, | ||||
::ChainActive().GetLocator(pindexBestHeader), | ::ChainActive().GetLocator(pindexBestHeader), | ||||
uint256())); | uint256())); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 377 Lines • ▼ Show 20 Lines | if (strCommand == NetMsgType::BLOCK && !fImporting && !fReindex) { | ||||
LogPrint(BCLog::NET, "received block %s peer=%d\n", | LogPrint(BCLog::NET, "received block %s peer=%d\n", | ||||
pblock->GetHash().ToString(), pfrom->GetId()); | pblock->GetHash().ToString(), pfrom->GetId()); | ||||
// Process all blocks from whitelisted peers, even if not requested, | // Process all blocks from whitelisted peers, even if not requested, | ||||
// unless we're still syncing with the network. Such an unrequested | // unless we're still syncing with the network. Such an unrequested | ||||
// block may still be processed, subject to the conditions in | // block may still be processed, subject to the conditions in | ||||
// AcceptBlock(). | // AcceptBlock(). | ||||
bool forceProcessing = | bool forceProcessing = pfrom->HasPermission(PF_NOBAN) && | ||||
pfrom->HasPermission(PF_NOBAN) && !IsInitialBlockDownload(); | !::ChainstateActive().IsInitialBlockDownload(); | ||||
const uint256 hash(pblock->GetHash()); | const uint256 hash(pblock->GetHash()); | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
// Also always process if we requested the block explicitly, as we | // Also always process if we requested the block explicitly, as we | ||||
// may need it even though it is not a candidate for a new best tip. | // may need it even though it is not a candidate for a new best tip. | ||||
forceProcessing |= MarkBlockAsReceived(hash); | forceProcessing |= MarkBlockAsReceived(hash); | ||||
// mapBlockSource is only used for sending reject messages and DoS | // mapBlockSource is only used for sending reject messages and DoS | ||||
// scores, so the race between here and cs_main in ProcessNewBlock | // scores, so the race between here and cs_main in ProcessNewBlock | ||||
▲ Show 20 Lines • Show All 820 Lines • ▼ Show 20 Lines | bool PeerLogicValidation::SendMessages(const Config &config, CNode *pto, | ||||
if (SendRejectsAndCheckIfBanned(pto, m_enable_bip61)) { | if (SendRejectsAndCheckIfBanned(pto, m_enable_bip61)) { | ||||
return true; | return true; | ||||
} | } | ||||
CNodeState &state = *State(pto->GetId()); | CNodeState &state = *State(pto->GetId()); | ||||
// Address refresh broadcast | // Address refresh broadcast | ||||
int64_t nNow = GetTimeMicros(); | int64_t nNow = GetTimeMicros(); | ||||
if (!IsInitialBlockDownload() && pto->nNextLocalAddrSend < nNow) { | if (!::ChainstateActive().IsInitialBlockDownload() && | ||||
pto->nNextLocalAddrSend < nNow) { | |||||
AdvertiseLocal(pto); | AdvertiseLocal(pto); | ||||
pto->nNextLocalAddrSend = | pto->nNextLocalAddrSend = | ||||
PoissonNextSend(nNow, AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL); | PoissonNextSend(nNow, AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL); | ||||
} | } | ||||
// | // | ||||
// Message: addr | // Message: addr | ||||
// | // | ||||
▲ Show 20 Lines • Show All 471 Lines • ▼ Show 20 Lines | bool PeerLogicValidation::SendMessages(const Config &config, CNode *pto, | ||||
// this anti-DoS logic so we can test this using mocktime. | // this anti-DoS logic so we can test this using mocktime. | ||||
ConsiderEviction(pto, GetTime()); | ConsiderEviction(pto, GetTime()); | ||||
// | // | ||||
// Message: getdata (blocks) | // Message: getdata (blocks) | ||||
// | // | ||||
std::vector<CInv> vGetData; | std::vector<CInv> vGetData; | ||||
if (!pto->fClient && | if (!pto->fClient && | ||||
((fFetch && !pto->m_limited_node) || !IsInitialBlockDownload()) && | ((fFetch && !pto->m_limited_node) || | ||||
!::ChainstateActive().IsInitialBlockDownload()) && | |||||
state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) { | state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) { | ||||
std::vector<const CBlockIndex *> vToDownload; | std::vector<const CBlockIndex *> vToDownload; | ||||
NodeId staller = -1; | NodeId staller = -1; | ||||
FindNextBlocksToDownload(pto->GetId(), | FindNextBlocksToDownload(pto->GetId(), | ||||
MAX_BLOCKS_IN_TRANSIT_PER_PEER - | MAX_BLOCKS_IN_TRANSIT_PER_PEER - | ||||
state.nBlocksInFlight, | state.nBlocksInFlight, | ||||
vToDownload, staller, consensusParams); | vToDownload, staller, consensusParams); | ||||
for (const CBlockIndex *pindex : vToDownload) { | for (const CBlockIndex *pindex : vToDownload) { | ||||
▲ Show 20 Lines • Show All 137 Lines • Show Last 20 Lines |