Changeset View
Changeset View
Standalone View
Standalone View
src/net_processing.cpp
Show All 33 Lines | |||||
#include <utilstrencodings.h> | #include <utilstrencodings.h> | ||||
#include <validation.h> | #include <validation.h> | ||||
#include <validationinterface.h> | #include <validationinterface.h> | ||||
#if defined(NDEBUG) | #if defined(NDEBUG) | ||||
#error "Bitcoin cannot be compiled without assertions." | #error "Bitcoin cannot be compiled without assertions." | ||||
#endif | #endif | ||||
// Used only to inform the wallet of when we last received a block. | /** Expiration time for orphan transactions in seconds */ | ||||
std::atomic<int64_t> nTimeBestReceived(0); | static constexpr int64_t ORPHAN_TX_EXPIRE_TIME = 20 * 60; | ||||
bool g_enable_bip61 = DEFAULT_ENABLE_BIP61; | /** Minimum time between orphan transactions expire time checks in seconds */ | ||||
static constexpr int64_t ORPHAN_TX_EXPIRE_INTERVAL = 5 * 60; | |||||
/** | |||||
* Headers download timeout expressed in microseconds. | |||||
* Timeout = base + per_header * (expected number of headers) | |||||
*/ | |||||
// 15 minutes | |||||
static constexpr int64_t HEADERS_DOWNLOAD_TIMEOUT_BASE = 15 * 60 * 1000000; | |||||
// 1ms/header | |||||
static constexpr int64_t HEADERS_DOWNLOAD_TIMEOUT_PER_HEADER = 1000; | |||||
/** | |||||
* Protect at least this many outbound peers from disconnection due to | |||||
* slow/behind headers chain. | |||||
*/ | |||||
static constexpr int32_t MAX_OUTBOUND_PEERS_TO_PROTECT_FROM_DISCONNECT = 4; | |||||
/** | |||||
* Timeout for (unprotected) outbound peers to sync to our chainwork, in | |||||
* seconds. | |||||
*/ | |||||
// 20 minutes | |||||
static constexpr int64_t CHAIN_SYNC_TIMEOUT = 20 * 60; | |||||
/** How frequently to check for stale tips, in seconds */ | |||||
// 10 minutes | |||||
static constexpr int64_t STALE_CHECK_INTERVAL = 10 * 60; | |||||
/** | |||||
* How frequently to check for extra outbound peers and disconnect, in seconds. | |||||
*/ | |||||
static constexpr int64_t EXTRA_PEER_CHECK_INTERVAL = 45; | |||||
/** | |||||
* Minimum time an outbound-peer-eviction candidate must be connected for, in | |||||
* order to evict, in seconds. | |||||
*/ | |||||
static constexpr int64_t MINIMUM_CONNECT_TIME = 30; | |||||
/** SHA256("main address relay")[0:8] */ | |||||
static constexpr 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 constexpr 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 constexpr int HISTORICAL_BLOCK_AGE = 7 * 24 * 60 * 60; | |||||
struct IteratorComparator { | /// How many non standard orphan do we consider from a node before ignoring it. | ||||
template <typename I> bool operator()(const I &a, const I &b) { | static constexpr uint32_t MAX_NON_STANDARD_ORPHAN_PER_NODE = 5; | ||||
return &(*a) < &(*b); | |||||
} | |||||
}; | |||||
struct COrphanTx { | struct COrphanTx { | ||||
// When modifying, adapt the copy of this definition in tests/DoS_tests. | // When modifying, adapt the copy of this definition in tests/DoS_tests. | ||||
CTransactionRef tx; | CTransactionRef tx; | ||||
NodeId fromPeer; | NodeId fromPeer; | ||||
int64_t nTimeExpire; | int64_t nTimeExpire; | ||||
}; | }; | ||||
static CCriticalSection g_cs_orphans; | static CCriticalSection g_cs_orphans; | ||||
std::map<uint256, COrphanTx> mapOrphanTransactions GUARDED_BY(g_cs_orphans); | std::map<uint256, COrphanTx> mapOrphanTransactions GUARDED_BY(g_cs_orphans); | ||||
std::map<COutPoint, | |||||
std::set<std::map<uint256, COrphanTx>::iterator, IteratorComparator>> | |||||
mapOrphanTransactionsByPrev GUARDED_BY(g_cs_orphans); | |||||
void EraseOrphansFor(NodeId peer); | |||||
static size_t vExtraTxnForCompactIt GUARDED_BY(g_cs_orphans) = 0; | |||||
static std::vector<std::pair<uint256, CTransactionRef>> | |||||
vExtraTxnForCompact GUARDED_BY(g_cs_orphans); | |||||
// SHA256("main address relay")[0:8] | void EraseOrphansFor(NodeId peer); | ||||
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; | |||||
// How many non standard orphan do we consider from a node before ignoring it. | |||||
static const uint32_t MAX_NON_STANDARD_ORPHAN_PER_NODE = 5; | |||||
// 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 | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | |||||
typedef std::map<uint256, CTransactionRef> MapRelay; | typedef std::map<uint256, CTransactionRef> MapRelay; | ||||
MapRelay mapRelay GUARDED_BY(cs_main); | MapRelay mapRelay GUARDED_BY(cs_main); | ||||
/** | /** | ||||
* Expiration-time ordered list of (expire time, relay map entry) pairs, | * Expiration-time ordered list of (expire time, relay map entry) pairs, | ||||
* protected by cs_main). | * protected by cs_main). | ||||
*/ | */ | ||||
std::deque<std::pair<int64_t, MapRelay::iterator>> | std::deque<std::pair<int64_t, MapRelay::iterator>> | ||||
vRelayExpiration GUARDED_BY(cs_main); | vRelayExpiration GUARDED_BY(cs_main); | ||||
// Used only to inform the wallet of when we last received a block | |||||
std::atomic<int64_t> nTimeBestReceived(0); | |||||
struct IteratorComparator { | |||||
template <typename I> bool operator()(const I &a, const I &b) const { | |||||
return &(*a) < &(*b); | |||||
} | |||||
}; | |||||
std::map<COutPoint, | |||||
std::set<std::map<uint256, COrphanTx>::iterator, IteratorComparator>> | |||||
mapOrphanTransactionsByPrev GUARDED_BY(g_cs_orphans); | |||||
static size_t vExtraTxnForCompactIt GUARDED_BY(g_cs_orphans) = 0; | |||||
static std::vector<std::pair<uint256, CTransactionRef>> | |||||
vExtraTxnForCompact GUARDED_BY(g_cs_orphans); | |||||
} // namespace | } // namespace | ||||
namespace { | namespace { | ||||
struct CBlockReject { | struct CBlockReject { | ||||
uint8_t chRejectCode; | uint8_t chRejectCode; | ||||
std::string strRejectReason; | std::string strRejectReason; | ||||
uint256 hashBlock; | uint256 hashBlock; | ||||
}; | }; | ||||
/** | /** | ||||
* Maintain validation-specific state about nodes, protected by cs_main, instead | * Maintain validation-specific state about nodes, protected by cs_main, instead | ||||
▲ Show 20 Lines • Show All 785 Lines • ▼ Show 20 Lines | return pindex->IsValid(BlockValidity::SCRIPTS) && | ||||
(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 *connmanIn, | PeerLogicValidation::PeerLogicValidation(CConnman *connmanIn, | ||||
CScheduler &scheduler) | CScheduler &scheduler, | ||||
: connman(connmanIn), m_stale_tip_check_time(0) { | bool enable_bip61) | ||||
: connman(connmanIn), m_stale_tip_check_time(0), | |||||
m_enable_bip61(enable_bip61) { | |||||
// 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 | ||||
// 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. | ||||
▲ Show 20 Lines • Show All 824 Lines • ▼ Show 20 Lines | static bool ProcessHeadersMessage(const Config &config, CNode *pfrom, | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
static bool ProcessMessage(const Config &config, CNode *pfrom, | static bool ProcessMessage(const Config &config, CNode *pfrom, | ||||
const std::string &strCommand, CDataStream &vRecv, | const std::string &strCommand, CDataStream &vRecv, | ||||
int64_t nTimeReceived, CConnman *connman, | int64_t nTimeReceived, CConnman *connman, | ||||
const std::atomic<bool> &interruptMsgProc) { | const std::atomic<bool> &interruptMsgProc, | ||||
bool enable_bip61) { | |||||
const CChainParams &chainparams = config.GetChainParams(); | 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(strCommand), vRecv.size(), pfrom->GetId()); | SanitizeString(strCommand), 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 true; | return true; | ||||
} | } | ||||
Show All 37 Lines | if (strCommand == NetMsgType::REJECT) { | ||||
} | } | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
else if (strCommand == NetMsgType::VERSION) { | else if (strCommand == NetMsgType::VERSION) { | ||||
// Each connection can only send one version message | // Each connection can only send one version message | ||||
if (pfrom->nVersion != 0) { | if (pfrom->nVersion != 0) { | ||||
if (g_enable_bip61) { | if (enable_bip61) { | ||||
connman->PushMessage( | connman->PushMessage( | ||||
pfrom, | pfrom, | ||||
CNetMsgMaker(INIT_PROTO_VERSION) | CNetMsgMaker(INIT_PROTO_VERSION) | ||||
.Make(NetMsgType::REJECT, strCommand, REJECT_DUPLICATE, | .Make(NetMsgType::REJECT, strCommand, REJECT_DUPLICATE, | ||||
std::string("Duplicate version message"))); | std::string("Duplicate version message"))); | ||||
} | } | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
Misbehaving(pfrom, 1, "multiple-version"); | Misbehaving(pfrom, 1, "multiple-version"); | ||||
Show All 22 Lines | else if (strCommand == NetMsgType::VERSION) { | ||||
if (!pfrom->fInbound && !pfrom->fFeeler && | if (!pfrom->fInbound && !pfrom->fFeeler && | ||||
!pfrom->m_manual_connection && | !pfrom->m_manual_connection && | ||||
!HasAllDesirableServiceFlags(nServices)) { | !HasAllDesirableServiceFlags(nServices)) { | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"peer=%d does not offer the expected services " | "peer=%d does not offer the expected services " | ||||
"(%08x offered, %08x expected); disconnecting\n", | "(%08x offered, %08x expected); disconnecting\n", | ||||
pfrom->GetId(), nServices, | pfrom->GetId(), nServices, | ||||
GetDesirableServiceFlags(nServices)); | GetDesirableServiceFlags(nServices)); | ||||
if (g_enable_bip61) { | if (enable_bip61) { | ||||
connman->PushMessage( | connman->PushMessage( | ||||
pfrom, | pfrom, | ||||
CNetMsgMaker(INIT_PROTO_VERSION) | CNetMsgMaker(INIT_PROTO_VERSION) | ||||
.Make(NetMsgType::REJECT, strCommand, | .Make(NetMsgType::REJECT, strCommand, | ||||
REJECT_NONSTANDARD, | REJECT_NONSTANDARD, | ||||
strprintf("Expected to offer services %08x", | strprintf("Expected to offer services %08x", | ||||
GetDesirableServiceFlags(nServices)))); | GetDesirableServiceFlags(nServices)))); | ||||
} | } | ||||
pfrom->fDisconnect = true; | pfrom->fDisconnect = true; | ||||
return false; | return false; | ||||
} | } | ||||
if (nVersion < MIN_PEER_PROTO_VERSION) { | if (nVersion < MIN_PEER_PROTO_VERSION) { | ||||
// disconnect from peers older than this proto version | // disconnect from peers older than this proto version | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"peer=%d using obsolete version %i; disconnecting\n", | "peer=%d using obsolete version %i; disconnecting\n", | ||||
pfrom->GetId(), nVersion); | pfrom->GetId(), nVersion); | ||||
if (g_enable_bip61) { | if (enable_bip61) { | ||||
connman->PushMessage( | connman->PushMessage( | ||||
pfrom, | pfrom, | ||||
CNetMsgMaker(INIT_PROTO_VERSION) | CNetMsgMaker(INIT_PROTO_VERSION) | ||||
.Make(NetMsgType::REJECT, strCommand, REJECT_OBSOLETE, | .Make(NetMsgType::REJECT, strCommand, REJECT_OBSOLETE, | ||||
strprintf("Version must be %d or greater", | strprintf("Version must be %d or greater", | ||||
MIN_PEER_PROTO_VERSION))); | MIN_PEER_PROTO_VERSION))); | ||||
} | } | ||||
pfrom->fDisconnect = true; | pfrom->fDisconnect = true; | ||||
▲ Show 20 Lines • Show All 759 Lines • ▼ Show 20 Lines | else if (strCommand == NetMsgType::TX) { | ||||
int nDoS = 0; | int nDoS = 0; | ||||
if (state.IsInvalid(nDoS)) { | if (state.IsInvalid(nDoS)) { | ||||
LogPrint(BCLog::MEMPOOLREJ, | LogPrint(BCLog::MEMPOOLREJ, | ||||
"%s from peer=%d was not accepted: %s\n", | "%s from peer=%d was not accepted: %s\n", | ||||
tx.GetHash().ToString(), pfrom->GetId(), | tx.GetHash().ToString(), pfrom->GetId(), | ||||
FormatStateMessage(state)); | FormatStateMessage(state)); | ||||
// Never send AcceptToMemoryPool's internal codes over P2P. | // Never send AcceptToMemoryPool's internal codes over P2P. | ||||
if (g_enable_bip61 && state.GetRejectCode() > 0 && | if (enable_bip61 && state.GetRejectCode() > 0 && | ||||
state.GetRejectCode() < REJECT_INTERNAL) { | state.GetRejectCode() < REJECT_INTERNAL) { | ||||
connman->PushMessage( | connman->PushMessage( | ||||
pfrom, msgMaker.Make(NetMsgType::REJECT, strCommand, | pfrom, msgMaker.Make(NetMsgType::REJECT, strCommand, | ||||
uint8_t(state.GetRejectCode()), | uint8_t(state.GetRejectCode()), | ||||
state.GetRejectReason().substr( | state.GetRejectReason().substr( | ||||
0, MAX_REJECT_MESSAGE_LENGTH), | 0, MAX_REJECT_MESSAGE_LENGTH), | ||||
inv.hash)); | inv.hash)); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 216 Lines • ▼ Show 20 Lines | else if (strCommand == NetMsgType::CMPCTBLOCK && !fImporting && !fReindex) { | ||||
fRevertToHeaderProcessing = true; | fRevertToHeaderProcessing = true; | ||||
} | } | ||||
} | } | ||||
} // cs_main | } // cs_main | ||||
if (fProcessBLOCKTXN) { | if (fProcessBLOCKTXN) { | ||||
return ProcessMessage(config, pfrom, NetMsgType::BLOCKTXN, | return ProcessMessage(config, pfrom, NetMsgType::BLOCKTXN, | ||||
blockTxnMsg, nTimeReceived, connman, | blockTxnMsg, nTimeReceived, connman, | ||||
interruptMsgProc); | interruptMsgProc, enable_bip61); | ||||
} | } | ||||
if (fRevertToHeaderProcessing) { | if (fRevertToHeaderProcessing) { | ||||
// Headers received from HB compact block peers are permitted to be | // Headers received from HB compact block peers are permitted to be | ||||
// relayed before full validation (see BIP 152), so we don't want to | // relayed before full validation (see BIP 152), so we don't want to | ||||
// disconnect the peer if the header turns out to be for an invalid | // disconnect the peer if the header turns out to be for an invalid | ||||
// block. | // block. | ||||
// Note that if a peer tries to build on an invalid chain, that will | // Note that if a peer tries to build on an invalid chain, that will | ||||
▲ Show 20 Lines • Show All 403 Lines • ▼ Show 20 Lines | else { | ||||
// Ignore unknown commands for extensibility | // Ignore unknown commands for extensibility | ||||
LogPrint(BCLog::NET, "Unknown command \"%s\" from peer=%d\n", | LogPrint(BCLog::NET, "Unknown command \"%s\" from peer=%d\n", | ||||
SanitizeString(strCommand), pfrom->GetId()); | SanitizeString(strCommand), pfrom->GetId()); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
static bool SendRejectsAndCheckIfBanned(CNode *pnode, CConnman *connman) { | static bool SendRejectsAndCheckIfBanned(CNode *pnode, CConnman *connman, | ||||
bool enable_bip61) { | |||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
CNodeState &state = *State(pnode->GetId()); | CNodeState &state = *State(pnode->GetId()); | ||||
if (g_enable_bip61) { | if (enable_bip61) { | ||||
for (const CBlockReject &reject : state.rejects) { | for (const CBlockReject &reject : state.rejects) { | ||||
connman->PushMessage( | connman->PushMessage( | ||||
pnode, | pnode, | ||||
CNetMsgMaker(INIT_PROTO_VERSION) | CNetMsgMaker(INIT_PROTO_VERSION) | ||||
.Make(NetMsgType::REJECT, std::string(NetMsgType::BLOCK), | .Make(NetMsgType::REJECT, std::string(NetMsgType::BLOCK), | ||||
reject.chRejectCode, reject.strRejectReason, | reject.chRejectCode, reject.strRejectReason, | ||||
reject.hashBlock)); | reject.hashBlock)); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 116 Lines • ▼ Show 20 Lines | if (memcmp(hash.begin(), hdr.pchChecksum, CMessageHeader::CHECKSUM_SIZE) != | ||||
connman->Ban(pfrom->addr, BanReasonNodeMisbehaving); | connman->Ban(pfrom->addr, BanReasonNodeMisbehaving); | ||||
return fMoreWork; | return fMoreWork; | ||||
} | } | ||||
// Process message | // Process message | ||||
bool fRet = false; | bool fRet = false; | ||||
try { | try { | ||||
fRet = ProcessMessage(config, pfrom, strCommand, vRecv, msg.nTime, | fRet = ProcessMessage(config, pfrom, strCommand, vRecv, msg.nTime, | ||||
connman, interruptMsgProc); | connman, interruptMsgProc, m_enable_bip61); | ||||
if (interruptMsgProc) { | if (interruptMsgProc) { | ||||
return false; | return false; | ||||
} | } | ||||
if (!pfrom->vRecvGetData.empty()) { | if (!pfrom->vRecvGetData.empty()) { | ||||
fMoreWork = true; | fMoreWork = true; | ||||
} | } | ||||
} catch (const std::ios_base::failure &e) { | } catch (const std::ios_base::failure &e) { | ||||
if (g_enable_bip61) { | if (m_enable_bip61) { | ||||
connman->PushMessage( | connman->PushMessage( | ||||
pfrom, | pfrom, | ||||
CNetMsgMaker(INIT_PROTO_VERSION) | CNetMsgMaker(INIT_PROTO_VERSION) | ||||
.Make(NetMsgType::REJECT, strCommand, REJECT_MALFORMED, | .Make(NetMsgType::REJECT, strCommand, REJECT_MALFORMED, | ||||
std::string("error parsing message"))); | std::string("error parsing message"))); | ||||
} | } | ||||
if (strstr(e.what(), "end of data")) { | if (strstr(e.what(), "end of data")) { | ||||
// Allow exceptions from under-length message on vRecv | // Allow exceptions from under-length message on vRecv | ||||
Show All 22 Lines | bool PeerLogicValidation::ProcessMessages(const Config &config, CNode *pfrom, | ||||
} | } | ||||
if (!fRet) { | if (!fRet) { | ||||
LogPrint(BCLog::NET, "%s(%s, %u bytes) FAILED peer=%d\n", __func__, | LogPrint(BCLog::NET, "%s(%s, %u bytes) FAILED peer=%d\n", __func__, | ||||
SanitizeString(strCommand), nMessageSize, pfrom->GetId()); | SanitizeString(strCommand), nMessageSize, pfrom->GetId()); | ||||
} | } | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
SendRejectsAndCheckIfBanned(pfrom, connman); | SendRejectsAndCheckIfBanned(pfrom, connman, m_enable_bip61); | ||||
return fMoreWork; | return fMoreWork; | ||||
} | } | ||||
void PeerLogicValidation::ConsiderEviction(CNode *pto, | void PeerLogicValidation::ConsiderEviction(CNode *pto, | ||||
int64_t time_in_seconds) { | int64_t time_in_seconds) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
▲ Show 20 Lines • Show All 248 Lines • ▼ Show 20 Lines | bool PeerLogicValidation::SendMessages(const Config &config, CNode *pto, | ||||
} | } | ||||
// Acquire cs_main for IsInitialBlockDownload() and CNodeState() | // Acquire cs_main for IsInitialBlockDownload() and CNodeState() | ||||
TRY_LOCK(cs_main, lockMain); | TRY_LOCK(cs_main, lockMain); | ||||
if (!lockMain) { | if (!lockMain) { | ||||
return true; | return true; | ||||
} | } | ||||
if (SendRejectsAndCheckIfBanned(pto, connman)) { | if (SendRejectsAndCheckIfBanned(pto, connman, 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 (!IsInitialBlockDownload() && pto->nNextLocalAddrSend < nNow) { | ||||
AdvertiseLocal(pto); | AdvertiseLocal(pto); | ||||
▲ Show 20 Lines • Show All 595 Lines • Show Last 20 Lines |