Changeset View
Changeset View
Standalone View
Standalone View
src/net_processing.cpp
// Copyright (c) 2009-2010 Satoshi Nakamoto | // Copyright (c) 2009-2010 Satoshi Nakamoto | ||||
// Copyright (c) 2009-2016 The Bitcoin Core developers | // Copyright (c) 2009-2016 The Bitcoin Core developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include <net_processing.h> | #include <net_processing.h> | ||||
#include <addrman.h> | #include <addrman.h> | ||||
#include <arith_uint256.h> | #include <arith_uint256.h> | ||||
#include <avalanche.h> | |||||
#include <banman.h> | #include <banman.h> | ||||
#include <blockencodings.h> | #include <blockencodings.h> | ||||
#include <blockvalidity.h> | #include <blockvalidity.h> | ||||
#include <chain.h> | #include <chain.h> | ||||
#include <chainparams.h> | #include <chainparams.h> | ||||
#include <config.h> | #include <config.h> | ||||
#include <consensus/validation.h> | #include <consensus/validation.h> | ||||
#include <hash.h> | #include <hash.h> | ||||
▲ Show 20 Lines • Show All 399 Lines • ▼ Show 20 Lines | struct TxDownloadState { | ||||
std::map<TxId, int64_t> m_tx_in_flight; | std::map<TxId, int64_t> m_tx_in_flight; | ||||
//! Periodically check for stuck getdata requests | //! Periodically check for stuck getdata requests | ||||
int64_t m_check_expiry_timer{0}; | int64_t m_check_expiry_timer{0}; | ||||
}; | }; | ||||
TxDownloadState m_tx_download; | TxDownloadState m_tx_download; | ||||
struct AvalancheState { | |||||
std::chrono::time_point<std::chrono::steady_clock> last_poll; | |||||
}; | |||||
AvalancheState m_avalanche_state; | |||||
CNodeState(CAddress addrIn, std::string addrNameIn) | CNodeState(CAddress addrIn, std::string addrNameIn) | ||||
: address(addrIn), name(addrNameIn) { | : address(addrIn), name(addrNameIn) { | ||||
fCurrentlyConnected = false; | fCurrentlyConnected = false; | ||||
nMisbehavior = 0; | nMisbehavior = 0; | ||||
fShouldBan = false; | fShouldBan = false; | ||||
pindexBestKnownBlock = nullptr; | pindexBestKnownBlock = nullptr; | ||||
hashLastUnknownBlock = BlockHash(); | hashLastUnknownBlock = BlockHash(); | ||||
pindexLastCommonBlock = nullptr; | pindexLastCommonBlock = nullptr; | ||||
▲ Show 20 Lines • Show All 2,980 Lines • ▼ Show 20 Lines | if (strCommand == NetMsgType::BLOCK && !fImporting && !fReindex) { | ||||
pfrom->nLastBlockTime = GetTime(); | pfrom->nLastBlockTime = GetTime(); | ||||
} else { | } else { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
mapBlockSource.erase(pblock->GetHash()); | mapBlockSource.erase(pblock->GetHash()); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
// Ignore avalanche requests while importing | |||||
if (strCommand == NetMsgType::AVAPOLL && !fImporting && !fReindex && | |||||
g_avalanche && | |||||
gArgs.GetBoolArg("-avaenabled", AVALANCHE_DEFAULT_ENABLED)) { | |||||
auto now = std::chrono::steady_clock::now(); | |||||
int64_t cooldown = | |||||
gArgs.GetArg("-avacooldown", AVALANCHE_DEFAULT_COOLDOWN); | |||||
{ | |||||
LOCK(cs_main); | |||||
auto &node_state = State(pfrom->GetId())->m_avalanche_state; | |||||
if (now < | |||||
node_state.last_poll + std::chrono::milliseconds(cooldown)) { | |||||
Misbehaving(pfrom, 20, "avapool-cooldown"); | |||||
} | |||||
node_state.last_poll = now; | |||||
} | |||||
uint64_t round; | |||||
Unserialize(vRecv, round); | |||||
unsigned int nCount = ReadCompactSize(vRecv); | |||||
if (nCount > AVALANCHE_MAX_ELEMENT_POLL) { | |||||
LOCK(cs_main); | |||||
Misbehaving(pfrom, 20, "too-many-poll"); | |||||
return error("poll message size = %u", nCount); | |||||
} | |||||
std::vector<AvalancheVote> votes; | |||||
votes.reserve(nCount); | |||||
LogPrint(BCLog::NET, "received avalanche poll from peer=%d\n", | |||||
pfrom->GetId()); | |||||
{ | |||||
LOCK(cs_main); | |||||
for (unsigned int n = 0; n < nCount; n++) { | |||||
CInv inv; | |||||
vRecv >> inv; | |||||
uint64_t error = -1; | |||||
Fabien: `AvalancheVote` expects an `uint32_t` | |||||
if (inv.type == MSG_BLOCK) { | |||||
BlockMap::iterator mi = | |||||
mapBlockIndex.find(BlockHash(inv.hash)); | |||||
if (mi != mapBlockIndex.end()) { | |||||
error = ::ChainActive().Contains(mi->second) ? 0 : 1; | |||||
} | |||||
} | |||||
votes.emplace_back(error, inv.hash); | |||||
} | |||||
} | |||||
// Send the query to the node. | |||||
g_avalanche->sendResponse( | |||||
pfrom, AvalancheResponse(round, cooldown, std::move(votes))); | |||||
return true; | |||||
} | |||||
if (strCommand == NetMsgType::GETADDR) { | if (strCommand == NetMsgType::GETADDR) { | ||||
// This asymmetric behavior for inbound and outbound connections was | // This asymmetric behavior for inbound and outbound connections was | ||||
// introduced to prevent a fingerprinting attack: an attacker can send | // introduced to prevent a fingerprinting attack: an attacker can send | ||||
// specific fake addresses to users' AddrMan and later request them by | // specific fake addresses to users' AddrMan and later request them by | ||||
// sending getaddr messages. Making nodes which are behind NAT and can | // sending getaddr messages. Making nodes which are behind NAT and can | ||||
// only make outgoing connections ignore the getaddr message mitigates | // only make outgoing connections ignore the getaddr message mitigates | ||||
// the attack. | // the attack. | ||||
if (!pfrom->fInbound) { | if (!pfrom->fInbound) { | ||||
▲ Show 20 Lines • Show All 1,343 Lines • Show Last 20 Lines |
AvalancheVote expects an uint32_t