76#include <initializer_list>
89#include <unordered_set>
217 std::unique_ptr<PartiallyDownloadedBlock> partialBlock;
251 std::atomic<ServiceFlags> m_their_services{
NODE_NONE};
254 const bool m_is_inbound;
257 Mutex m_misbehavior_mutex;
262 Mutex m_block_inv_mutex;
281 std::atomic<uint64_t> m_ping_nonce_sent{0};
285 std::atomic<bool> m_ping_queued{
false};
288 std::atomic<bool> m_wtxid_relay{
false};
300 bool m_relay_txs
GUARDED_BY(m_bloom_filter_mutex){
false};
326 std::atomic<CAmount> m_fee_filter_received{0};
332 LOCK(m_tx_relay_mutex);
334 m_tx_relay = std::make_unique<Peer::TxRelay>();
369 std::atomic_bool m_addr_relay_enabled{
false};
371 mutable Mutex m_addr_send_times_mutex;
378 std::atomic_bool m_wants_addrv2{
false};
387 std::atomic<uint64_t> m_addr_rate_limited{0};
389 std::atomic<uint64_t> m_addr_processed{0};
395 Mutex m_getdata_requests_mutex;
403 Mutex m_headers_sync_mutex;
409 std::atomic<bool> m_sent_sendheaders{
false};
419 std::atomic<std::chrono::seconds> m_time_offset{0
s};
428 mutable Mutex m_tx_relay_mutex;
434using PeerRef = std::shared_ptr<Peer>;
446 uint256 hashLastUnknownBlock{};
452 bool fSyncStarted{
false};
454 std::chrono::microseconds m_stalling_since{0
us};
455 std::list<QueuedBlock> vBlocksInFlight;
457 std::chrono::microseconds m_downloading_since{0
us};
459 std::chrono::microseconds m_block_download_paused_until{0
us};
461 bool fPreferredDownload{
false};
463 bool m_requested_hb_cmpctblocks{
false};
465 bool m_provides_cmpctblocks{
false};
491 struct ChainSyncTimeoutState {
493 std::chrono::seconds m_timeout{0
s};
497 bool m_sent_getheaders{
false};
499 bool m_protect{
false};
502 ChainSyncTimeoutState m_chain_sync;
508struct InvToSendBucket {
509 const double count_floor{0};
510 std::vector<Wtxid> backlog;
527 static constexpr double SIZE_INIT{12'000'000};
528 static constexpr double SIZE_CAP{50'000'000};
529 static constexpr double SIZE_REFILL{20'000};
531 static constexpr double INBOUND_COUNT_SECONDS{30};
533 InvToSendBucket(
unsigned int rate,
double mult)
535 size_bucket(SIZE_REFILL *
mult, SIZE_INIT, SIZE_CAP),
536 count_bucket(
rate *
mult,
rate * INBOUND_COUNT_SECONDS,
rate * INBOUND_COUNT_SECONDS)
542 return !backlog.empty() && size_bucket.
value() > 0 && count_bucket.
value() > 0;
553 bool decrement(
double size)
564 .count_bucket = count_bucket.
value(),
565 .size_bucket = size_bucket.
value(),
613 void SetBestBlock(
int height,
std::chrono::
seconds time)
override
615 m_best_height = height;
616 m_best_block_time = time;
805 template <
typename... Args>
810 template <
typename... Args>
869 std::unique_ptr<TxReconciliationTracker> m_txreconciliation;
872 std::atomic<int> m_best_height{-1};
874 std::atomic<std::chrono::seconds> m_best_block_time{0
s};
882 const Options m_opts;
892 mutable Mutex m_peer_mutex;
949 Mutex m_most_recent_block_mutex;
957 Mutex m_headers_presync_mutex;
965 using HeadersPresyncStats = std::pair<arith_uint256, std::optional<std::pair<int64_t, uint32_t>>>;
971 std::atomic_bool m_headers_presync_should_signal{
false};
1190 std::
atomic<
NodeClock::time_point> m_next_inv_bucket_check{NodeClock::time_point::min()};
1206 return const_cast<CNodeState*
>(std::as_const(*this).State(
pnode));
1219void PeerManagerImpl::AddAddressKnown(Peer& peer,
const CAddress& addr)
1221 assert(peer.m_addr_known);
1222 peer.m_addr_known->insert(addr.
GetKey());
1225void PeerManagerImpl::PushAddress(Peer& peer,
const CAddress& addr)
1230 assert(peer.m_addr_known);
1233 peer.m_addrs_to_send[m_rng.randrange(peer.m_addrs_to_send.size())] = addr;
1235 peer.m_addrs_to_send.push_back(addr);
1246 tx_relay->m_tx_inventory_known_filter.insert(hash);
1269std::chrono::microseconds PeerManagerImpl::NextInvToInbounds(std::chrono::microseconds now,
1274 auto& timer{it->second};
1281bool PeerManagerImpl::IsBlockRequested(
const uint256& hash)
1286bool PeerManagerImpl::IsBlockRequestedFromOutbound(
const uint256& hash)
1288 for (
auto range =
mapBlocksInFlight.equal_range(hash); range.first != range.second; range.first++) {
1289 auto [nodeid,
block_it] = range.first->second;
1291 if (peer && !peer->m_is_inbound)
return true;
1297void PeerManagerImpl::RemoveBlockRequest(
const uint256& hash, std::optional<NodeId>
from_peer)
1300 if (range.first == range.second) {
1308 while (range.first != range.second) {
1318 if (state.vBlocksInFlight.begin() ==
list_it) {
1322 state.vBlocksInFlight.erase(
list_it);
1324 if (state.vBlocksInFlight.empty()) {
1328 state.m_stalling_since = 0
us;
1334bool PeerManagerImpl::BlockRequested(
NodeId nodeid,
const CBlockIndex& block, std::list<QueuedBlock>::iterator**
pit)
1338 CNodeState *state =
State(nodeid);
1339 assert(state !=
nullptr);
1344 for (
auto range =
mapBlocksInFlight.equal_range(hash); range.first != range.second; range.first++) {
1345 if (range.first->second.first == nodeid) {
1347 *
pit = &range.first->second.second;
1356 std::list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(),
1357 {&block, std::unique_ptr<PartiallyDownloadedBlock>(pit ? new PartiallyDownloadedBlock(&m_mempool) : nullptr)});
1358 if (state->vBlocksInFlight.size() == 1) {
1370void PeerManagerImpl::MaybeSetPeerAsAnnouncingHeaderAndIDs(
NodeId nodeid)
1377 if (m_opts.ignore_incoming_txs)
return;
1388 if (*it == nodeid) {
1396 if (peer && peer->m_is_inbound) {
1412 pfrom->m_bip152_highbandwidth_to =
true;
1422 pnodeStop->m_bip152_highbandwidth_to =
false;
1429bool PeerManagerImpl::TipMayBeStale()
1433 if (m_last_tip_update.load() == 0s) {
1439int64_t PeerManagerImpl::ApproximateBestBlockDepth()
const
1444bool PeerManagerImpl::CanDirectFetch()
1451 if (state->pindexBestKnownBlock && pindex == state->pindexBestKnownBlock->GetAncestor(pindex->nHeight))
1453 if (state->pindexBestHeaderSent && pindex == state->pindexBestHeaderSent->GetAncestor(pindex->nHeight))
1458void PeerManagerImpl::ProcessBlockAvailability(
NodeId nodeid) {
1459 CNodeState *state =
State(nodeid);
1460 assert(state !=
nullptr);
1462 if (!state->hashLastUnknownBlock.IsNull()) {
1465 if (state->pindexBestKnownBlock ==
nullptr || pindex->
nChainWork >= state->pindexBestKnownBlock->nChainWork) {
1466 state->pindexBestKnownBlock = pindex;
1468 state->hashLastUnknownBlock.SetNull();
1473void PeerManagerImpl::UpdateBlockAvailability(
NodeId nodeid,
const uint256 &hash) {
1474 CNodeState *state =
State(nodeid);
1475 assert(state !=
nullptr);
1482 if (state->pindexBestKnownBlock ==
nullptr || pindex->
nChainWork >= state->pindexBestKnownBlock->nChainWork) {
1483 state->pindexBestKnownBlock = pindex;
1487 state->hashLastUnknownBlock = hash;
1492void PeerManagerImpl::FindNextBlocksToDownload(
const Peer& peer,
unsigned int count, std::vector<const CBlockIndex*>&
vBlocks,
NodeId&
nodeStaller)
1498 CNodeState *state =
State(peer.m_id);
1499 assert(state !=
nullptr);
1504 if (state->pindexBestKnownBlock ==
nullptr || state->pindexBestKnownBlock->nChainWork < m_chainman.
ActiveChain().
Tip()->
nChainWork || state->pindexBestKnownBlock->nChainWork < m_chainman.
MinimumChainWork()) {
1516 LogDebug(
BCLog::NET,
"Not downloading blocks from peer=%d, which doesn't have the snapshot block in its best chain.\n", peer.m_id);
1525 if (state->pindexLastCommonBlock ==
nullptr ||
1526 fork_point->nChainWork > state->pindexLastCommonBlock->nChainWork ||
1527 state->pindexBestKnownBlock->GetAncestor(state->pindexLastCommonBlock->nHeight) != state->pindexLastCommonBlock) {
1530 if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
1554 if (state->pindexBestKnownBlock ==
nullptr || state->pindexBestKnownBlock->GetAncestor(
target_block->nHeight) !=
target_block) {
1573 std::vector<const CBlockIndex*>
vToFetch;
1585 for (
unsigned int i =
nToFetch - 1; i > 0; i--) {
1606 state->pindexLastCommonBlock = pindex;
1645void PeerManagerImpl::PushNodeVersion(
CNode&
pnode,
const Peer& peer)
1654 if (
pnode.IsPrivateBroadcastConn()) {
1676 pnode.AdvertisedVersion(),
1683 pnode.GetLocalNonce(),
1689 BCLog::NET,
"send version message: version=%d, blocks=%d%s, txrelay=%d, peer=%d\n",
1699 if (state) state->m_last_block_announcement = time;
1722void PeerManagerImpl::ReattemptInitialBroadcast(
CScheduler& scheduler)
1729 if (tx !=
nullptr) {
1730 InitiateTxBroadcastToAll(tx->GetWitnessHash());
1742void PeerManagerImpl::ReattemptPrivateBroadcast(
CScheduler& scheduler)
1747 const auto stale_txs = m_tx_for_private_broadcast.GetStale();
1754 if (!m_tx_for_private_broadcast.TryGrantRetry(
stale_tx))
continue;
1756 "Reattempting broadcast of stale txid=%s wtxid=%s",
1763 m_tx_for_private_broadcast.MarkResolved(
stale_tx);
1775void PeerManagerImpl::FinalizeNode(
const CNode&
node)
1789 CNodeState *state =
State(nodeid);
1790 assert(state !=
nullptr);
1792 if (state->fSyncStarted)
1795 for (
const QueuedBlock& entry : state->vBlocksInFlight) {
1797 while (range.first != range.second) {
1807 LOCK(m_tx_download_mutex);
1810 if (m_txreconciliation) m_txreconciliation->ForgetPeer(nodeid);
1828 if (
node.fSuccessfullyConnected &&
1829 !
node.IsBlockOnlyConn() && !
node.IsPrivateBroadcastConn() && !
node.IsInboundConn()) {
1837 LOCK(m_headers_presync_mutex);
1840 if (
node.IsPrivateBroadcastConn()) {
1841 m_tx_for_private_broadcast.NodeDisconnected(nodeid);
1849 if (!
node.fSuccessfullyConnected && m_tx_for_private_broadcast.HavePendingTransactions()) {
1856bool PeerManagerImpl::HasAllDesirableServiceFlags(
ServiceFlags services)
const
1859 return !(GetDesirableServiceFlags(services) & (
~services));
1877 return it !=
m_peer_map.end() ? it->second :
nullptr;
1886 ret = std::move(it->second);
1892std::vector<PeerRef> PeerManagerImpl::GetAllPeers()
const
1894 std::vector<PeerRef> peers;
1898 peers.push_back(peer);
1907 const CNodeState* state =
State(nodeid);
1908 if (state ==
nullptr)
1910 stats.
nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1;
1911 stats.
nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->nHeight : -1;
1912 for (
const QueuedBlock&
queue : state->vBlocksInFlight) {
1920 if (peer ==
nullptr)
return false;
1929 if ((0 != peer->m_ping_nonce_sent) && (peer->m_ping_start.load() >
NodeClock::epoch)) {
1950 LOCK(peer->m_headers_sync_mutex);
1951 if (peer->m_headers_sync) {
1960std::vector<node::TxOrphanage::OrphanInfo> PeerManagerImpl::GetOrphanTransactions()
1962 LOCK(m_tx_download_mutex);
1971 .ignores_incoming_txs = m_opts.ignore_incoming_txs,
1972 .private_broadcast = m_opts.private_broadcast,
1973 .tx_send_rate = m_opts.tx_send_rate,
1979std::vector<PrivateBroadcast::TxBroadcastInfo> PeerManagerImpl::GetPrivateBroadcastInfo()
const
1981 return m_tx_for_private_broadcast.GetBroadcastInfo();
1984std::vector<CTransactionRef> PeerManagerImpl::AbortPrivateBroadcast(
const uint256&
id)
1986 const auto snapshot{m_tx_for_private_broadcast.GetBroadcastInfo()};
1992 if (tx->GetHash().ToUint256() !=
id && tx->GetWitnessHash().ToUint256() !=
id)
continue;
1993 if (
const auto remaining_sends{m_tx_for_private_broadcast.Remove(tx)}) {
2003void PeerManagerImpl::AddToCompactExtraTransactions(
const CTransactionRef& tx)
2005 if (m_opts.max_extra_txs == 0)
return;
2015void PeerManagerImpl::Misbehaving(Peer& peer,
const std::string& message)
2017 LOCK(peer.m_misbehavior_mutex);
2019 const std::string
message_prefixed = message.empty() ?
"" : (
": " + message);
2020 peer.m_should_discourage =
true;
2068 if (message !=
"") {
2126 return std::make_unique<PeerManagerImpl>(connman, addrman, banman, chainman, pool, warnings, opts);
2132 : m_rng{opts.deterministic_rng},
2134 m_chainparams(chainman.GetParams()),
2138 m_chainman(chainman),
2141 m_warnings{warnings},
2148 if (opts.reconcile_txs) {
2153void PeerManagerImpl::StartScheduledTasks(
CScheduler& scheduler)
2166 if (m_opts.private_broadcast) {
2179 LOCK(m_tx_download_mutex);
2193void PeerManagerImpl::BlockConnected(
2195 const std::shared_ptr<const CBlock>& pblock,
2216 LOCK(m_tx_download_mutex);
2221void PeerManagerImpl::BlockDisconnected(
const std::shared_ptr<const CBlock> &block,
const CBlockIndex* pindex)
2223 LOCK(m_tx_download_mutex);
2231void PeerManagerImpl::NewPoWValidBlock(
const CBlockIndex *pindex,
const std::shared_ptr<const CBlock>& pblock)
2243 uint256 hashBlock(pblock->GetHash());
2244 const std::shared_future<CSerializedNetMsg>
lazy_ser{
2249 for (
const auto& tx : pblock->vtx) {
2254 LOCK(m_most_recent_block_mutex);
2272 LogDebug(
BCLog::NET,
"%s sending header-and-ids %s to peer=%d\n",
"PeerManager::NewPoWValidBlock",
2273 hashBlock.ToString(),
pnode->GetId());
2277 state.pindexBestHeaderSent = pindex;
2288 SetBestBlock(
pindexNew->nHeight, std::chrono::seconds{pindexNew->GetBlockTime()});
2309 Peer& peer = *it.second;
2310 LOCK(peer.m_block_inv_mutex);
2312 peer.m_blocks_for_headers_relay.push_back(hash);
2324void PeerManagerImpl::BlockChecked(
const std::shared_ptr<const CBlock>& block,
const BlockValidationState& state)
2328 const uint256 hash(block->GetHash());
2329 std::map<uint256, std::pair<NodeId, bool>>::iterator it =
mapBlockSource.find(hash);
2335 State(it->second.first)) {
2360bool PeerManagerImpl::AlreadyHaveBlock(
const uint256& block_hash)
2365void PeerManagerImpl::SendPings()
2371std::vector<Wtxid> InvToSendBucket::TakeForProcessing(
CTxMemPool& mempool)
2375 size_t n_to_take =
static_cast<size_t>(std::max<double>(count_bucket.
value() - count_floor, 0));
2377 std::vector<Wtxid>
best;
2382 auto&
wtxid = txiter->GetTx().GetWitnessHash();
2385 if (!decrement(txiter->GetTx().ComputeTotalSize())) {
2389 backlog.push_back(
wtxid);
2395 std::vector<Wtxid> dummy;
2397 dummy.swap(backlog);
2407 if (!
backlog_bumped && now <= m_next_inv_bucket_check.load())
return;
2421 LogDebug(
BCLog::NET,
"Transaction rate-limiting backlog inbound=%d itok=%.1f isz=%.1f outbound=%d otok=%.1f osz=%.1f",
2464 if (
tx_relay->m_next_inv_send_time == 0s)
continue;
2465 if (peer.m_is_inbound) {
2471 tx_relay->m_tx_inventory_to_send.push_back(i);
2483void PeerManagerImpl::InitiateTxBroadcastToAll(
const Wtxid&
wtxid)
2495 const auto txstr{
strprintf(
"txid=%s, wtxid=%s", tx->GetHash().ToString(), tx->GetWitnessHash().ToString())};
2496 switch (m_tx_for_private_broadcast.Add(tx)) {
2537 std::array<std::pair<uint64_t, Peer*>, 2>
best{{{0,
nullptr}, {0,
nullptr}}};
2555 for (
unsigned int i = 0; i <
nRelayNodes &&
best[i].first != 0; i++) {
2560void PeerManagerImpl::ProcessGetBlockData(
CNode&
pfrom, Peer& peer,
const CInv& inv)
2565 LogDebug(
BCLog::NET,
"filtered block request received when NODE_BLOOM service disabled, %s",
pfrom.DisconnectMsg());
2566 pfrom.fDisconnect =
true;
2573 LOCK(m_most_recent_block_mutex);
2621 pfrom.fDisconnect =
true;
2631 pfrom.fDisconnect =
true;
2643 std::shared_ptr<const CBlock> pblock;
2655 LogError(
"Cannot load block from disk, %s",
pfrom.DisconnectMsg());
2657 pfrom.fDisconnect =
true;
2663 std::shared_ptr<CBlock>
pblockRead = std::make_shared<CBlock>();
2668 LogError(
"Cannot load block from disk, %s",
pfrom.DisconnectMsg());
2670 pfrom.fDisconnect =
true;
2722 LOCK(peer.m_block_inv_mutex);
2724 if (inv.
hash == peer.m_continuation_block) {
2728 std::vector<CInv>
vInv;
2731 peer.m_continuation_block.SetNull();
2740 [&](
const auto&
id) {
2745 return std::move(
txinfo.tx);
2750 LOCK(m_most_recent_block_mutex);
2766 std::deque<CInv>::iterator it = peer.m_getdata_requests.begin();
2772 while (it != peer.m_getdata_requests.end() && it->IsGenTxMsg()) {
2776 if (
pfrom.fPauseSend)
break;
2778 const CInv &inv = *it++;
2798 if (it != peer.m_getdata_requests.end() && !
pfrom.fPauseSend) {
2799 const CInv &inv = *it++;
2810 peer.m_getdata_requests.erase(peer.m_getdata_requests.begin(), it);
2831uint32_t PeerManagerImpl::GetFetchFlags(
const Peer& peer)
const
2843 for (
size_t i = 0; i < req.
indexes.size(); i++) {
2845 Misbehaving(peer,
"getblocktxn with out-of-bounds tx indices");
2863bool PeerManagerImpl::CheckHeadersPoW(
const std::vector<CBlockHeader>&
headers, Peer& peer)
2867 Misbehaving(peer,
"header with invalid proof of work");
2873 Misbehaving(peer,
"non-continuous headers sequence");
2898void PeerManagerImpl::HandleUnconnectingHeaders(
CNode&
pfrom, Peer& peer,
2899 const std::vector<CBlockHeader>&
headers)
2904 LogDebug(
BCLog::NET,
"received header %s: missing prev block %s, sending getheaders (%d) to end (peer=%d)\n",
2906 headers[0].hashPrevBlock.ToString(),
2917bool PeerManagerImpl::CheckHeadersAreContinuous(
const std::vector<CBlockHeader>&
headers)
const
2929bool PeerManagerImpl::IsContinuationOfLowWorkHeadersSync(Peer& peer,
CNode&
pfrom, std::vector<CBlockHeader>&
headers)
2931 if (peer.m_headers_sync) {
2932 auto result = peer.m_headers_sync->ProcessNextHeaders(
headers,
headers.size() == m_opts.max_headers_result);
2934 if (result.success) peer.m_last_getheaders_timestamp = {};
2935 if (result.request_more) {
2936 auto locator = peer.m_headers_sync->NextHeadersRequestLocator();
2938 Assume(!locator.vHave.empty());
2941 if (!locator.vHave.empty()) {
2947 locator.vHave.front().ToString(),
pfrom.GetId());
2951 if (peer.m_headers_sync->GetState() == HeadersSyncState::State::FINAL) {
2952 peer.m_headers_sync.reset(
nullptr);
2957 LOCK(m_headers_presync_mutex);
2961 HeadersPresyncStats stats;
2962 stats.first = peer.m_headers_sync->GetPresyncWork();
2963 if (peer.m_headers_sync->GetState() == HeadersSyncState::State::PRESYNC) {
2964 stats.second = {peer.m_headers_sync->GetPresyncHeight(),
2965 peer.m_headers_sync->GetPresyncTime()};
2969 LOCK(m_headers_presync_mutex);
2977 const HeadersPresyncStats*
stat_best{
nullptr};
2993 m_headers_presync_should_signal =
true;
2997 if (result.success) {
3000 headers.swap(result.pow_validated_headers);
3003 return result.success;
3026 if (
headers.size() == m_opts.max_headers_result) {
3036 LOCK(peer.m_headers_sync_mutex);
3045 const auto msg{
strprintf(
"Failure when attempting to initiate headers sync: %s",
e.what())};
3046 std::cerr <<
msg << std::endl;
3068bool PeerManagerImpl::IsAncestorOfBestHeaderOrTip(
const CBlockIndex* header)
3070 if (header ==
nullptr) {
3072 }
else if (m_chainman.m_best_header !=
nullptr && header == m_chainman.m_best_header->GetAncestor(header->
nHeight)) {
3105 std::vector<const CBlockIndex*>
vToFetch;
3146 if (!m_opts.ignore_incoming_txs &&
3165void PeerManagerImpl::UpdatePeerStateForReceivedHeaders(
CNode&
pfrom,
3195 if (
pfrom.IsOutboundOrBlockRelayConn()) {
3196 LogInfo(
"outbound peer headers chain has insufficient work, %s",
pfrom.DisconnectMsg());
3197 pfrom.fDisconnect =
true;
3207 if (!
pfrom.fDisconnect &&
pfrom.IsFullOutboundConn() &&
nodestate->pindexBestKnownBlock !=
nullptr) {
3210 nodestate->m_chain_sync.m_protect =
true;
3216void PeerManagerImpl::ProcessHeadersMessage(
CNode&
pfrom, Peer& peer,
3217 std::vector<CBlockHeader>&&
headers,
3227 LOCK(peer.m_headers_sync_mutex);
3228 if (peer.m_headers_sync) {
3229 peer.m_headers_sync.reset(
nullptr);
3230 LOCK(m_headers_presync_mutex);
3235 peer.m_last_getheaders_timestamp = {};
3263 LOCK(peer.m_headers_sync_mutex);
3299 peer.m_last_getheaders_timestamp = {};
3347 "If this happens with all peers, consider database corruption (that -reindex may fix) "
3348 "or a potential consensus incompatibility.",
3387 ptx->GetHash().ToString(),
3388 ptx->GetWitnessHash().ToString(),
3414 tx->GetHash().ToString(),
3415 tx->GetWitnessHash().ToString(),
3418 InitiateTxBroadcastToAll(tx->GetWitnessHash());
3431 const auto&
package = package_to_validate.m_txns;
3483bool PeerManagerImpl::ProcessOrphanTx(Peer& peer)
3517bool PeerManagerImpl::PrepareBlockFilterRequest(
CNode&
node, Peer& peer,
3529 node.fDisconnect =
true;
3541 node.fDisconnect =
true;
3549 "start height %d and stop height %d, %s",
3551 node.fDisconnect =
true;
3557 node.fDisconnect =
true;
3562 if (!filter_index) {
3587 std::vector<BlockFilter>
filters;
3589 LogDebug(
BCLog::NET,
"Failed to find block filter in index: filter_type=%s, start_height=%d, stop_hash=%s\n",
3594 for (
const auto& filter :
filters) {
3621 LogDebug(
BCLog::NET,
"Failed to find block filter header in index: filter_type=%s, block_hash=%s\n",
3629 LogDebug(
BCLog::NET,
"Failed to find block filter hashes in index: filter_type=%s, start_height=%d, stop_hash=%s\n",
3653 std::numeric_limits<uint32_t>::max(),
3662 for (
int i =
int(
headers.size()) - 1; i >= 0; i--) {
3667 LogDebug(
BCLog::NET,
"Failed to find block filter header in index: filter_type=%s, block_hash=%s\n",
3698 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
3731 Misbehaving(peer,
"previous compact block reconstruction attempt failed");
3742 Misbehaving(peer,
"invalid compact block/non-matching block transactions");
3750 std::vector<CInv>
invs;
3755 LogDebug(
BCLog::NET,
"Peer %d sent us a compact block but it failed to reconstruct, waiting on first download to complete\n",
pfrom.GetId());
3795 "Saw new %sheader hash=%s height=%d %s",
3808void PeerManagerImpl::PushPrivateBroadcastTx(
CNode&
node)
3812 const auto opt_tx{m_tx_for_private_broadcast.PickTxForSend(
node.GetId(),
CService{node.addr})};
3815 node.fDisconnect =
true;
3821 tx->GetHash().ToString(), tx->HasWitness() ?
strprintf(
", wtxid=%s", tx->GetWitnessHash().ToString()) :
"",
3837 if (
pfrom.nVersion != 0) {
3847 std::string cleanSubVer;
3857 if (!
pfrom.IsInboundConn() && !
pfrom.IsPrivateBroadcastConn())
3864 if (
pfrom.ExpectServicesFromConn() && !HasAllDesirableServiceFlags(nServices))
3866 LogDebug(
BCLog::NET,
"peer does not offer the expected services (%08x offered, %08x expected), %s",
3868 GetDesirableServiceFlags(nServices),
3869 pfrom.DisconnectMsg());
3870 pfrom.fDisconnect =
true;
3877 pfrom.fDisconnect =
true;
3881 if (!
vRecv.empty()) {
3889 if (!
vRecv.empty()) {
3894 if (!
vRecv.empty()) {
3902 LogInfo(
"connected to self at %s, disconnecting\n",
pfrom.addr.ToStringAddrPort());
3903 pfrom.fDisconnect =
true;
3914 if (
pfrom.IsInboundConn()) {
3921 pfrom.nVersion = nVersion;
3923 pfrom.m_has_all_wanted_services = HasAllDesirableServiceFlags(nServices);
3924 peer.m_their_services = nServices;
3928 pfrom.cleanSubVer = cleanSubVer;
3937 if (!
pfrom.IsBlockOnlyConn() &&
3938 !
pfrom.IsFeelerConn() &&
3940 auto*
const tx_relay = peer.SetTxRelay();
3949 LogDebug(
BCLog::NET,
"receive version message: %s: version %d, blocks=%d, us=%s, txrelay=%d, %s%s",
3950 cleanSubVer.empty() ?
"<no user agent>" : cleanSubVer,
pfrom.nVersion,
3952 (mapped_as ?
strprintf(
", mapped_as=%d", mapped_as) :
""));
3954 if (
pfrom.IsPrivateBroadcastConn()) {
3960 pfrom.fDisconnect =
true;
3985 const auto*
tx_relay = peer.GetTxRelay();
3987 !
pfrom.IsAddrFetchConn() && !m_opts.ignore_incoming_txs) {
4016 if (!
pfrom.IsInboundConn()) {
4032 if (!
pfrom.IsInboundConn()) {
4051 if (!
pfrom.IsInboundConn()) {
4054 m_outbound_time_offsets.Add(peer.m_time_offset);
4055 m_outbound_time_offsets.WarnIfOutOfSync();
4060 constexpr auto finalAlert{
"60010000000000000000000000ffffff7f00000000ffffff7ffeffff7f01ffffff7f00000000ffffff7f00ffffff7f002f555247454e543a20416c657274206b657920636f6d70726f6d697365642c2075706772616465207265717569726564004630440220653febd6410f470f6bae11cad19c48413becb1ac2c17f908fd0fd53bdc3abd5202206d0e9c96fe88d4a0f01ed9dedae2b6f9e00da94cad0fecaae66ecf689bf71b50"_hex};
4065 if (
pfrom.IsFeelerConn()) {
4067 pfrom.fDisconnect =
true;
4072 if (
pfrom.nVersion == 0) {
4079 if (
pfrom.fSuccessfullyConnected) {
4086 return strprintf(
"New %s peer connected: transport: %s, version: %d, %s%s",
4087 pfrom.ConnectionTypeAsString(),
4090 (mapped_as ?
strprintf(
", mapped_as=%d", mapped_as) :
""));
4095 if (
pfrom.IsInboundConn()) {
4101 if (
auto tx_relay = peer.GetTxRelay()) {
4111 return tx_relay->m_tx_inventory_to_send.empty() &&
4112 tx_relay->m_next_inv_send_time == 0s));
4115 if (
pfrom.IsPrivateBroadcastConn()) {
4116 pfrom.fSuccessfullyConnected =
true;
4135 if (m_txreconciliation) {
4136 if (!peer.m_wtxid_relay || !m_txreconciliation->IsPeerRegistered(
pfrom.GetId())) {
4140 m_txreconciliation->ForgetPeer(
pfrom.GetId());
4146 const CNodeState* state =
State(
pfrom.GetId());
4148 .m_preferred = state->fPreferredDownload,
4149 .m_relay_permissions = pfrom.HasPermission(NetPermissionFlags::Relay),
4150 .m_wtxid_relay = peer.m_wtxid_relay,
4154 pfrom.fSuccessfullyConnected =
true;
4159 peer.m_prefers_headers =
true;
4171 Misbehaving(peer,
"invalid sendcmpct announce field");
4180 nodestate->m_provides_cmpctblocks =
true;
4191 if (
pfrom.fSuccessfullyConnected) {
4194 pfrom.fDisconnect =
true;
4198 if (!peer.m_wtxid_relay) {
4199 peer.m_wtxid_relay =
true;
4212 if (
pfrom.fSuccessfullyConnected) {
4215 pfrom.fDisconnect =
true;
4218 peer.m_wants_addrv2 =
true;
4223 if (
pfrom.fSuccessfullyConnected) {
4226 pfrom.fDisconnect =
true;
4231 pfrom.fDisconnect =
true;
4242 }
catch (
const std::exception&) {
4247 pfrom.fDisconnect =
true;
4265 if (!m_txreconciliation) {
4266 LogDebug(
BCLog::NET,
"sendtxrcncl from peer=%d ignored, as our node does not have txreconciliation enabled\n",
pfrom.GetId());
4270 if (
pfrom.fSuccessfullyConnected) {
4272 pfrom.fDisconnect =
true;
4279 pfrom.fDisconnect =
true;
4286 const auto*
tx_relay = peer.GetTxRelay();
4289 pfrom.fDisconnect =
true;
4306 LogDebug(
BCLog::NET,
"txreconciliation protocol violation (sendtxrcncl received from already registered peer), %s",
pfrom.DisconnectMsg());
4307 pfrom.fDisconnect =
true;
4311 pfrom.fDisconnect =
true;
4317 if (!
pfrom.fSuccessfullyConnected) {
4322 if (
pfrom.IsPrivateBroadcastConn()) {
4338 std::vector<CAddress>
vAddr;
4345 std::vector<CInv>
vInv;
4354 std::unordered_set<uint256, SaltedUint256Hasher>
seen_txids{0, m_txhash_hasher};
4355 std::unordered_set<uint256, SaltedUint256Hasher>
seen_wtxids{0, m_txhash_hasher};
4368 if (peer.m_wtxid_relay) {
4391 pfrom.fDisconnect =
true;
4424 m_chainman.m_best_header->nHeight,
best_block->ToString(),
4427 if (!state.fSyncStarted) {
4428 peer.m_inv_triggered_getheaders_before_sync =
true;
4441 std::vector<CInv>
vInv;
4451 if (
vInv.size() > 0) {
4455 if (
pfrom.IsPrivateBroadcastConn()) {
4460 pfrom.fDisconnect =
true;
4472 peer.m_ping_queued =
true;
4477 pfrom.fDisconnect =
true;
4483 LOCK(peer.m_getdata_requests_mutex);
4484 peer.m_getdata_requests.insert(peer.m_getdata_requests.end(),
vInv.begin(),
vInv.end());
4498 pfrom.fDisconnect =
true;
4512 LOCK(m_most_recent_block_mutex);
4531 for (; pindex; pindex = m_chainman.
ActiveChain().Next(*pindex))
4550 WITH_LOCK(peer.m_block_inv_mutex, {peer.m_continuation_block = pindex->GetBlockHash();});
4564 pfrom.fDisconnect =
true;
4570 for (
size_t i = 1; i < req.
indexes.size(); ++i) {
4576 LOCK(m_most_recent_block_mutex);
4621 WITH_LOCK(peer.m_getdata_requests_mutex, peer.m_getdata_requests.push_back(inv));
4633 pfrom.fDisconnect =
true;
4647 if (m_chainman.
ActiveTip() ==
nullptr ||
4649 LogDebug(
BCLog::NET,
"Ignoring getheaders from peer=%d because active chain has too little work; sending empty response\n",
pfrom.GetId());
4680 int nLimit = m_opts.max_headers_result;
4682 for (; pindex; pindex = m_chainman.
ActiveChain().Next(*pindex))
4708 pfrom.fDisconnect =
true;
4720 const Txid& txid =
ptx->GetHash();
4726 if (m_tx_for_private_broadcast.MarkResolved(
ptx)) {
4740 if (!m_mempool.
exists(txid)) {
4741 LogInfo(
"Not relaying non-mempool transaction %s (wtxid=%s) from forcerelay peer=%d\n",
4744 LogInfo(
"Force relaying tx %s (wtxid=%s) from peer=%d\n",
4746 InitiateTxBroadcastToAll(
wtxid);
4753 package_result.m_state.IsValid() ?
"package accepted" :
"package rejected");
4773 package_result.m_state.IsValid() ?
"package accepted" :
"package rejected");
4787 }
else if (m_opts.ignore_incoming_txs) {
4795 if (!
nodestate->m_provides_cmpctblocks) {
4851 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
4894 std::vector<CInv>
vInv(1);
4913 if (!(*queuedBlockIt)->partialBlock)
4931 std::vector<CInv>
vInv(1);
4942 for (
size_t i = 0; i <
cmpctblock.BlockTxCount(); i++) {
4953 }
else if (
pfrom.m_bip152_highbandwidth_to &&
4954 (!
pfrom.IsInboundConn() ||
4980 std::vector<CTransactionRef> dummy;
4982 status =
tempBlock.FillBlock(*pblock, dummy,
4992 std::vector<CInv>
vInv(1);
5069 std::vector<CBlockHeader>
headers;
5073 if (
nCount > m_opts.max_headers_result) {
5078 for (
unsigned int n = 0; n <
nCount; n++) {
5087 if (m_headers_presync_should_signal.exchange(
false)) {
5088 HeadersPresyncStats stats;
5090 LOCK(m_headers_presync_mutex);
5110 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
5127 const uint256 hash(pblock->GetHash());
5155 if (!
pfrom.IsInboundConn()) {
5166 if (peer.m_getaddr_recvd) {
5170 peer.m_getaddr_recvd =
true;
5172 peer.m_addrs_to_send.clear();
5173 std::vector<CAddress>
vAddr;
5193 pfrom.fDisconnect =
true;
5203 pfrom.fDisconnect =
true;
5243 pfrom.fDisconnect =
true;
5259 pfrom.m_bloom_filter_loaded =
true;
5260 pfrom.m_relays_txs =
true;
5269 pfrom.fDisconnect =
true;
5272 std::vector<unsigned char> vData;
5283 tx_relay->m_bloom_filter->insert(vData);
5297 pfrom.fDisconnect =
true;
5305 tx_relay->m_bloom_filter =
nullptr;
5308 pfrom.m_bloom_filter_loaded =
false;
5309 pfrom.m_relays_txs =
true;
5342 std::vector<CInv>
vInv;
5352 LOCK(m_tx_download_mutex);
5362bool PeerManagerImpl::MaybeDiscourageAndDisconnect(
CNode&
pnode, Peer& peer)
5365 LOCK(peer.m_misbehavior_mutex);
5368 if (!peer.m_should_discourage)
return false;
5370 peer.m_should_discourage =
false;
5375 LogWarning(
"Not punishing noban peer %d!", peer.m_id);
5379 if (
pnode.IsManualConn()) {
5381 LogWarning(
"Not punishing manually connected peer %d!", peer.m_id);
5385 if (
pnode.IsPrivateBroadcastConn()) {
5387 pnode.fDisconnect =
true;
5391 if (
pnode.addr.IsLocal()) {
5395 pnode.m_inbound_onion ?
"inbound onion" :
"local", peer.m_id);
5396 pnode.fDisconnect =
true;
5409 if (!
node.IsInboundConn() || !
node.m_relays_txs)
return false;
5412 LogDebug(
BCLog::NET,
"failed to find a tx-relaying eviction candidate - connection dropped after %s message, peer=%d\n",
msg_type,
node.GetId());
5413 node.fDisconnect =
true;
5428 if (!
node.IsInboundConn() && !peer.m_outbound_version_message_sent)
return false;
5431 LOCK(peer.m_getdata_requests_mutex);
5432 if (!peer.m_getdata_requests.empty()) {
5439 if (
node.fDisconnect)
5447 LOCK(peer.m_getdata_requests_mutex);
5448 if (!peer.m_getdata_requests.empty())
return true;
5452 if (
node.fPauseSend)
return false;
5465 node.m_addr_name.c_str(),
5466 node.ConnectionTypeAsString().c_str(),
5472 if (m_opts.capture_messages) {
5480 LOCK(peer.m_getdata_requests_mutex);
5481 if (!peer.m_getdata_requests.empty())
fMoreWork =
true;
5488 LOCK(m_tx_download_mutex);
5490 }
catch (
const std::exception&
e) {
5503 CNodeState &state = *
State(
pto.GetId());
5505 if (!state.m_chain_sync.m_protect &&
pto.IsOutboundOrBlockRelayConn() && state.fSyncStarted) {
5512 if (state.pindexBestKnownBlock !=
nullptr && state.pindexBestKnownBlock->nChainWork >= m_chainman.
ActiveChain().
Tip()->
nChainWork) {
5514 if (state.m_chain_sync.m_timeout != 0s) {
5515 state.m_chain_sync.m_timeout = 0
s;
5516 state.m_chain_sync.m_work_header =
nullptr;
5517 state.m_chain_sync.m_sent_getheaders =
false;
5519 }
else if (state.m_chain_sync.m_timeout == 0s || (state.m_chain_sync.m_work_header !=
nullptr && state.pindexBestKnownBlock !=
nullptr && state.pindexBestKnownBlock->nChainWork >= state.m_chain_sync.m_work_header->nChainWork)) {
5527 state.m_chain_sync.m_work_header = m_chainman.
ActiveChain().
Tip();
5528 state.m_chain_sync.m_sent_getheaders =
false;
5529 }
else if (state.m_chain_sync.m_timeout > 0s &&
time_in_seconds > state.m_chain_sync.m_timeout) {
5533 if (state.m_chain_sync.m_sent_getheaders) {
5535 LogInfo(
"Outbound peer has old chain, best known block = %s, %s", state.pindexBestKnownBlock !=
nullptr ? state.pindexBestKnownBlock->GetBlockHash().ToString() :
"<none>",
pto.DisconnectMsg());
5536 pto.fDisconnect =
true;
5538 assert(state.m_chain_sync.m_work_header);
5544 GetLocator(state.m_chain_sync.m_work_header->pprev),
5546 LogDebug(
BCLog::NET,
"sending getheaders to outbound peer=%d to verify chain work (current best known block:%s, benchmark blockhash: %s)\n",
pto.GetId(), state.pindexBestKnownBlock !=
nullptr ? state.pindexBestKnownBlock->GetBlockHash().ToString() :
"<none>", state.m_chain_sync.m_work_header->GetBlockHash().
ToString());
5547 state.m_chain_sync.m_sent_getheaders =
true;
5571 if (!
pnode->IsBlockOnlyConn() ||
pnode->fDisconnect)
return;
5594 pnode->fDisconnect =
true;
5595 LogDebug(
BCLog::NET,
"disconnecting extra block-relay-only peer=%d (last block received at time %d)\n",
5599 LogDebug(
BCLog::NET,
"keeping block-relay-only peer=%d chosen for eviction (connect time: %d, blocks_in_flight: %d)\n",
5625 if (!
pnode->IsFullOutboundConn() ||
pnode->fDisconnect)
return;
5627 if (state ==
nullptr)
return;
5629 if (state->m_chain_sync.m_protect)
return;
5634 (state->m_last_block_announcement < (*worst_peer).oldest_block_announcement) ||
5635 ((state->m_last_block_announcement == (*worst_peer).oldest_block_announcement) &&
pnode->GetId() > (*worst_peer).node)) {
5650 LogDebug(
BCLog::NET,
"disconnecting extra outbound peer=%d (last block announcement received at time %d)\n",
5652 pnode->fDisconnect =
true;
5655 LogDebug(
BCLog::NET,
"keeping outbound peer=%d chosen for eviction (connect time: %d, blocks_in_flight: %d)\n",
5672void PeerManagerImpl::CheckForStaleTipAndEvictPeers()
5685 LogInfo(
"Potential stale tip detected, will try using extra outbound peer (last tip update: %d seconds ago)\n",
5704 if (peer.m_ping_queued) {
5709 if (peer.m_ping_nonce_sent == 0 && now > peer.m_ping_start.load() +
PING_INTERVAL) {
5718 }
while (
nonce == 0);
5719 peer.m_ping_queued =
false;
5720 peer.m_ping_start = now;
5722 peer.m_ping_nonce_sent =
nonce;
5726 peer.m_ping_nonce_sent = 0;
5735 if (!peer.m_addr_relay_enabled)
return;
5737 LOCK(peer.m_addr_send_times_mutex);
5747 if (peer.m_next_local_addr_send != 0
us) {
5748 peer.m_addr_known->reset();
5752 if (peer.m_next_local_addr_send == 0
us) {
5758 if (peer.m_wants_addrv2) {
5786 bool ret = peer.m_addr_known->contains(addr.
GetKey());
5787 if (!
ret) peer.m_addr_known->insert(addr.
GetKey());
5793 if (peer.m_addrs_to_send.empty())
return;
5795 if (peer.m_wants_addrv2) {
5800 peer.m_addrs_to_send.clear();
5803 if (peer.m_addrs_to_send.capacity() > 40) {
5804 peer.m_addrs_to_send.shrink_to_fit();
5808void PeerManagerImpl::MaybeSendSendHeaders(
CNode&
node, Peer& peer)
5816 CNodeState &state = *
State(
node.GetId());
5817 if (state.pindexBestKnownBlock !=
nullptr &&
5824 peer.m_sent_sendheaders =
true;
5829void PeerManagerImpl::MaybeSendFeefilter(
CNode&
pto, Peer& peer, std::chrono::microseconds
current_time)
5831 if (m_opts.ignore_incoming_txs)
return;
5837 if (
pto.IsBlockOnlyConn())
return;
5850 peer.m_next_send_feefilter = 0
us;
5871bool PeerManagerImpl::RejectIncomingTxs(
const CNode& peer)
const
5892 if (peer.m_ping_nonce_sent != 0) {
5893 if (
nonce == peer.m_ping_nonce_sent) {
5900 if (
pfrom.IsPrivateBroadcastConn()) {
5901 m_tx_for_private_broadcast.NodeConfirmedReception(
pfrom.GetId());
5904 pfrom.fDisconnect =
true;
5920 sProblem =
"Unsolicited pong without ping";
5932 peer.m_ping_nonce_sent,
5937 peer.m_ping_nonce_sent = 0;
5941bool PeerManagerImpl::SetupAddressRelay(
const CNode&
node, Peer& peer)
5946 if (
node.IsBlockOnlyConn())
return false;
5951 if (
node.IsFeelerConn())
return false;
5953 if (!peer.m_addr_relay_enabled.exchange(
true)) {
5957 peer.m_addr_known = std::make_unique<CRollingBloomFilter>(5000, 0.001);
5980 std::vector<CAddress>
vAddrOk;
5995 std::shuffle(
vAddr.begin(),
vAddr.end(), m_rng);
6002 if (peer.m_addr_token_bucket < 1.0) {
6008 peer.m_addr_token_bucket -= 1.0;
6017 addr.
nTime = std::chrono::time_point_cast<std::chrono::seconds>(
current_time - 5 * 24h);
6037 LogDebug(
BCLog::NET,
"Received addr: %u addresses (%u processed, %u rate-limited) from peer=%d\n",
6043 if (
pfrom.IsAddrFetchConn() &&
vAddr.size() > 1) {
6045 pfrom.fDisconnect =
true;
6049bool PeerManagerImpl::SendMessages(
CNode&
node)
6064 if (!
node.IsInboundConn() && !peer.m_outbound_version_message_sent) {
6066 peer.m_outbound_version_message_sent =
true;
6070 if (!
node.fSuccessfullyConnected ||
node.fDisconnect)
6079 if (
node.IsPrivateBroadcastConn()) {
6083 node.fDisconnect =
true;
6090 node.fDisconnect =
true;
6105 CNodeState &state = *
State(
node.GetId());
6108 if (m_chainman.m_best_header ==
nullptr) {
6116 if (state.fPreferredDownload) {
6149 state.fSyncStarted =
true;
6173 LOCK(peer.m_block_inv_mutex);
6176 (!state.m_requested_hb_cmpctblocks || peer.m_blocks_for_headers_relay.size() > 1)) ||
6229 if (
vHeaders.size() == 1 && state.m_requested_hb_cmpctblocks) {
6237 LOCK(m_most_recent_block_mutex);
6252 }
else if (peer.m_prefers_headers) {
6256 vHeaders.front().GetHash().ToString(),
6271 if (!peer.m_blocks_for_headers_relay.empty()) {
6292 peer.m_blocks_for_headers_relay.clear();
6298 std::vector<CInv>
vInv;
6300 LOCK(peer.m_block_inv_mutex);
6301 vInv.reserve(peer.m_blocks_for_inv_relay.size());
6311 peer.m_blocks_for_inv_relay.clear();
6320 if (
node.IsInboundConn()) {
6344 tx_relay->m_tx_inventory_to_send.clear();
6351 const auto inv = peer.m_wtxid_relay ?
6360 if (!
tx_relay->m_bloom_filter->IsRelevantAndUpdate(*
txinfo.tx))
continue;
6362 tx_relay->m_tx_inventory_known_filter.insert(inv.
hash);
6363 vInv.push_back(inv);
6379 std::vector<CTransactionRef>
res;
6381 if (
invs.size() == 0)
return res;
6384 if (
invs.capacity() > 2 *
invs.size())
invs.shrink_to_fit();
6390 if (txiter->GetFee() <
filterrate.GetFee(txiter->GetTxSize())) {
6393 res.push_back(txiter->GetSharedTx());
6402 for (
auto& tx :
inv_tx) {
6406 const auto inv = peer.m_wtxid_relay ?
6410 if (
tx_relay->m_tx_inventory_known_filter.contains(inv.
hash)) {
6413 if (
tx_relay->m_bloom_filter && !
tx_relay->m_bloom_filter->IsRelevantAndUpdate(*tx))
continue;
6415 vInv.push_back(inv);
6420 tx_relay->m_tx_inventory_known_filter.insert(inv.
hash);
6433 if (
node.IsManualConn()) {
6436 while (!state.vBlocksInFlight.empty()) {
6440 LogInfo(
"Peer is stalling block download, %s",
node.DisconnectMsg());
6441 node.fDisconnect =
true;
6456 if (state.vBlocksInFlight.size() > 0) {
6457 QueuedBlock &
queuedBlock = state.vBlocksInFlight.front();
6460 LogInfo(
"Timeout downloading block %s, %s",
queuedBlock.pindex->GetBlockHash().ToString(),
node.DisconnectMsg());
6461 node.fDisconnect =
true;
6468 if (state.vBlocksInFlight.empty() &&
6471 peer.m_ping_nonce_sent &&
6477 node.fDisconnect =
true;
6481 if (state.fSyncStarted && peer.m_headers_sync_timeout < std::chrono::microseconds::max()) {
6483 if (m_chainman.m_best_header->Time() <=
NodeClock::now() - 24h) {
6491 LogInfo(
"Timeout downloading headers, %s",
node.DisconnectMsg());
6492 node.fDisconnect =
true;
6495 LogInfo(
"Timeout downloading headers from noban peer, not %s",
node.DisconnectMsg());
6501 state.fSyncStarted =
false;
6503 peer.m_headers_sync_timeout = 0
us;
6509 peer.m_headers_sync_timeout = std::chrono::microseconds::max();
6550 if (state.vBlocksInFlight.empty() &&
staller != -1) {
6562 LOCK(m_tx_download_mutex);
constexpr CAmount MAX_MONEY
No amount larger than this (in satoshi) is valid.
bool MoneyRange(const CAmount &nValue)
int64_t CAmount
Amount in satoshis (Can be negative)
enum ReadStatus_t ReadStatus
const std::string & BlockFilterTypeName(BlockFilterType filter_type)
Get the human-readable name for a filter type.
BlockFilterIndex * GetBlockFilterIndex(BlockFilterType filter_type)
Get a block filter index by type.
constexpr int CFCHECKPT_INTERVAL
Interval between compact filter checkpoints.
CBlockLocator GetLocator(const CBlockIndex *index)
Get a locator for a block index entry.
int64_t GetBlockProofEquivalentTime(const CBlockIndex &to, const CBlockIndex &from, const CBlockIndex &tip, const Consensus::Params ¶ms)
Return the time it would take to redo the work difference between from and to, assuming the current h...
const CBlockIndex * LastCommonAncestor(const CBlockIndex *pa, const CBlockIndex *pb)
Find the last common ancestor two blocks have.
@ BLOCK_VALID_CHAIN
Outputs do not overspend inputs, no double spends, coinbase output ok, no immature coinbase spends,...
@ BLOCK_VALID_TRANSACTIONS
Only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid,...
@ BLOCK_VALID_SCRIPTS
Scripts & signatures ok.
@ BLOCK_VALID_TREE
All parent headers found, difficulty matches, timestamp >= median previous.
@ BLOCK_HAVE_DATA
full block available in blk*.dat
arith_uint256 GetBlockProof(const CBlockIndex &block)
Compute how much work a block index entry corresponds to.
#define Assert(val)
Identity function.
#define Assume(val)
Assume is the identity function.
Stochastic address manager.
void Connected(const CService &addr, NodeSeconds time=Now< NodeSeconds >())
We have successfully connected to this peer.
bool Good(const CService &addr, NodeSeconds time=Now< NodeSeconds >())
Mark an address record as accessible and attempt to move it to addrman's tried table.
bool Add(const std::vector< CAddress > &vAddr, const CNetAddr &source, std::chrono::seconds time_penalty=0s)
Attempt to add one or more addresses to addrman's new table.
void SetServices(const CService &addr, ServiceFlags nServices)
Update an entry's service bits.
bool IsBanned(const CNetAddr &net_addr) EXCLUSIVE_LOCKS_REQUIRED(!m_banned_mutex)
Return whether net_addr is banned.
bool IsDiscouraged(const CNetAddr &net_addr) EXCLUSIVE_LOCKS_REQUIRED(!m_banned_mutex)
Return whether net_addr is discouraged.
void Discourage(const CNetAddr &net_addr) EXCLUSIVE_LOCKS_REQUIRED(!m_banned_mutex)
BlockFilterIndex is used to store and retrieve block filters, hashes, and headers for a range of bloc...
bool LookupFilterRange(int start_height, const CBlockIndex *stop_index, std::vector< BlockFilter > &filters_out) const
Get a range of filters between two heights on a chain.
bool LookupFilterHashRange(int start_height, const CBlockIndex *stop_index, std::vector< uint256 > &hashes_out) const
Get a range of filter hashes between two heights on a chain.
bool LookupFilterHeader(const CBlockIndex *block_index, uint256 &header_out) EXCLUSIVE_LOCKS_REQUIRED(!m_cs_headers_cache)
Get a single filter header by block.
std::vector< uint16_t > indexes
A CService with information about it as peer.
ServiceFlags nServices
Serialized as uint64_t in V1, and as CompactSize in V2.
static constexpr SerParams V1_NETWORK
NodeSeconds nTime
Always included in serialization. The behavior is unspecified if the value is not representable as ui...
static constexpr SerParams V2_NETWORK
std::vector< CTransactionRef > vtx
The block chain is a tree shaped structure starting with the genesis block at the root,...
bool IsValid(enum BlockStatus nUpTo) const EXCLUSIVE_LOCKS_REQUIRED(
Check whether this block index entry is valid up to the passed validity level.
CBlockIndex * pprev
pointer to the index of the predecessor of this block
CBlockHeader GetBlockHeader() const
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
bool HaveNumChainTxs() const
Check whether this block and all previous blocks back to the genesis block or an assumeutxo snapshot ...
uint256 GetBlockHash() const
int64_t GetBlockTime() const
unsigned int nTx
Number of transactions in this block.
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
int nHeight
height of the entry in the chain. The genesis block has height 0
FlatFilePos GetBlockPos() const EXCLUSIVE_LOCKS_REQUIRED(
BloomFilter is a probabilistic filter which SPV clients provide so that we can filter the transaction...
bool IsWithinSizeConstraints() const
True if the size is <= MAX_BLOOM_FILTER_SIZE and the number of hash functions is <= MAX_HASH_FUNCS (c...
An in-memory indexed chain of blocks.
bool Contains(const CBlockIndex &index) const
Efficiently check whether a block is present in this chain.
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
CBlockIndex * Next(const CBlockIndex &index) const
Find the successor of a block in this chain, or nullptr if the given index is not found or is the tip...
int Height() const
Return the maximal height in the chain.
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system.
const HeadersSyncParams & HeadersSync() const
const Consensus::Params & GetConsensus() const
void NumToOpenAdd(size_t n)
Increment the number of new connections of type ConnectionType::PRIVATE_BROADCAST to be opened by CCo...
size_t NumToOpenSub(size_t n)
Decrement the number of new connections of type ConnectionType::PRIVATE_BROADCAST to be opened by CCo...
bool GetNetworkActive() const
bool GetTryNewOutboundPeer() const
class CConnman::PrivateBroadcast m_private_broadcast
bool ShouldRunInactivityChecks(const CNode &node, NodeClock::time_point now) const
Return true if we should disconnect the peer for failing an inactivity check.
std::vector< CAddress > GetAddresses(CNode &requestor, size_t max_addresses, size_t max_pct)
Return addresses from the per-requestor cache.
void SetTryNewOutboundPeer(bool flag)
void WakeMessageHandler() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc)
bool OutboundTargetReached(bool historicalBlockServingLimit) const EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex)
check if the outbound target is reached if param historicalBlockServingLimit is set true,...
void StartExtraBlockRelayPeers()
void ForEachNode(const NodeFn &func) EXCLUSIVE_LOCKS_REQUIRED(!m_nodes_mutex)
CSipHasher GetDeterministicRandomizer(uint64_t id) const
Get a unique deterministic randomizer.
bool EvictTxPeerIfFull(std::optional< NodeId > protect_peer=std::nullopt) EXCLUSIVE_LOCKS_REQUIRED(!m_nodes_mutex)
If we are at capacity for inbound tx-relay peers, attempt to evict one.
uint32_t GetMappedAS(const CNetAddr &addr) const
bool MultipleManualOrFullOutboundConns(Network net) const EXCLUSIVE_LOCKS_REQUIRED(m_nodes_mutex)
bool ForNode(NodeId id, std::function< bool(CNode *pnode)> func) EXCLUSIVE_LOCKS_REQUIRED(!m_nodes_mutex)
std::vector< CAddress > GetAddressesUnsafe(size_t max_addresses, size_t max_pct, std::optional< Network > network, bool filtered=true) const
Return randomly selected addresses.
int GetExtraBlockRelayCount() const EXCLUSIVE_LOCKS_REQUIRED(!m_nodes_mutex)
bool DisconnectNode(std::string_view node) EXCLUSIVE_LOCKS_REQUIRED(!m_nodes_mutex)
Mutex & GetNodesMutex() const LOCK_RETURNED(m_nodes_mutex)
int GetExtraFullOutboundCount() const EXCLUSIVE_LOCKS_REQUIRED(!m_nodes_mutex)
bool GetUseAddrmanOutgoing() const
bool CheckIncomingNonce(uint64_t nonce) EXCLUSIVE_LOCKS_REQUIRED(!m_nodes_mutex)
Fee rate in satoshis per virtualbyte: CAmount / vB the feerate is represented internally as FeeFrac.
CAmount GetFeePerK() const
Return the fee in satoshis for a vsize of 1000 vbytes.
bool IsMsgCmpctBlk() const
std::string ToString() const
bool IsMsgFilteredBlk() const
bool IsMsgWitnessBlk() const
Used to relay blocks as header + vector<merkle branch> to filtered nodes.
bool IsRelayable() const
Whether this address should be relayed to other peers even if we can't reach it ourselves.
static constexpr SerParams V1
bool IsAddrV1Compatible() const
Check if the current object can be serialized in pre-ADDRv2/BIP155 format.
Transport protocol agnostic message container.
Information about a peer.
bool IsFeelerConn() const
bool HasPermission(NetPermissionFlags permission) const
bool IsBlockOnlyConn() const
RollingBloomFilter is a probabilistic "keep track of most recently inserted" set.
Simple class for background tasks that should be run periodically or once "after a while".
void scheduleEvery(Function f, std::chrono::milliseconds delta) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Repeat f until the scheduler is stopped.
void scheduleFromNow(Function f, std::chrono::milliseconds delta) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Call f once after the delta has passed.
A combination of a network address (CNetAddr) and a (TCP) port.
std::vector< unsigned char > GetKey() const
General SipHash-2-4 implementation.
uint64_t Finalize() const
Compute the 64-bit SipHash-2-4 of the data written so far.
CSipHasher & Write(uint64_t data)
Hash a 64-bit integer worth of data.
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
TxMempoolInfo info_for_relay(const T &id, uint64_t last_sequence) const
Returns info for a transaction if its entry_sequence < last_sequence.
CFeeRate GetMinFee(size_t sizelimit) const
CTransactionRef get(const Txid &hash) const
Return a mempool transaction with a given hash.
size_t DynamicMemoryUsage() const
std::vector< TxMempoolInfo > infoAll() const
bool exists(const Txid &txid) const
uint64_t GetSequence() const EXCLUSIVE_LOCKS_REQUIRED(cs)
std::set< Txid > GetUnbroadcastTxs() const
Returns a copy of the unbroadcast txid set.
unsigned long size() const
void RemoveUnbroadcastTx(const Txid &txid, bool unchecked=false)
Removes a transaction from the unbroadcast set.
std::vector< txiter > ExtractBestByMiningScoreWithTopology(std::vector< Wtxid > &wtxids, size_t n_to_sort) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Look up wtxids in the mempool and (partially) sort by mining score.
virtual void NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr< const CBlock > &block)
Notifies listeners that a block which builds directly on our current tip has been received and connec...
virtual void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload)
Notifies listeners when the block chain tip advances.
virtual void BlockChecked(const std::shared_ptr< const CBlock > &, const BlockValidationState &)
Notifies listeners of a block validation result.
virtual void ActiveTipChange(const CBlockIndex &new_tip, bool is_ibd)
Notifies listeners any time the block chain tip changes, synchronously.
virtual void BlockDisconnected(const std::shared_ptr< const CBlock > &block, const CBlockIndex *pindex)
Notifies listeners of a block being disconnected Provides the block that was disconnected.
virtual void BlockConnected(const kernel::ChainstateRole &role, const std::shared_ptr< const CBlock > &block, const CBlockIndex *pindex)
Notifies listeners of a block being connected.
void ClearBlockIndexCandidates() EXCLUSIVE_LOCKS_REQUIRED(void PopulateBlockIndexCandidates() EXCLUSIVE_LOCKS_REQUIRED(const CBlockIndex * FindForkInGlobalIndex(const CBlockLocator &locator) const EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Populate the candidate set by calling TryAddBlockIndexCandidate on all valid block indices.
Interface for managing multiple Chainstate objects, where each chainstate is associated with chainsta...
bool IsInitialBlockDownload() const noexcept
Check whether we are doing an initial block download (synchronizing from disk or network)
MempoolAcceptResult ProcessTransaction(const CTransactionRef &tx, bool test_accept=false) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Try to add a transaction to the memory pool.
RecursiveMutex & GetMutex() const LOCK_RETURNED(
Alias for cs_main.
CBlockIndex * ActiveTip() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
Chainstate & ActiveChainstate() const
Alternatives to CurrentChainstate() used by older code to query latest chainstate information without...
SnapshotCompletionResult MaybeValidateSnapshot(Chainstate &validated_cs, Chainstate &unvalidated_cs) EXCLUSIVE_LOCKS_REQUIRED(Chainstate & CurrentChainstate() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
Try to validate an assumeutxo snapshot by using a validated historical chainstate targeted at the sna...
bool ProcessNewBlock(const std::shared_ptr< const CBlock > &block, bool force_processing, bool min_pow_checked, bool *new_block) LOCKS_EXCLUDED(cs_main)
Process an incoming block.
bool ProcessNewBlockHeaders(std::span< const CBlockHeader > headers, bool min_pow_checked, BlockValidationState &state, const CBlockIndex **ppindex=nullptr) LOCKS_EXCLUDED(cs_main)
Process incoming block headers.
const arith_uint256 & MinimumChainWork() const
CChain & ActiveChain() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
void ReportHeadersPresync(int64_t height, int64_t timestamp)
This is used by net_processing to report pre-synchronization progress of headers, as headers are not ...
node::BlockManager m_blockman
A single BlockManager instance is shared across each constructed chainstate to avoid duplicating bloc...
Double ended buffer combining vector and stream-like interfaces.
uint64_t rand64() noexcept
Generate a random 64-bit integer.
static Mutex g_msgproc_mutex
Mutex for anything that is only accessed via the msg processing thread.
virtual void FinalizeNode(const CNode &node)=0
Handle removal of a peer (clear state)
virtual bool ProcessMessages(CNode &node, std::atomic< bool > &interrupt) EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex)=0
Process protocol messages received from a given node.
virtual bool HasAllDesirableServiceFlags(ServiceFlags services) const =0
Callback to determine whether the given set of service flags are sufficient for a peer to be "relevan...
virtual bool SendMessages(CNode &node) EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex)=0
Send queued protocol messages to a given node.
virtual void InitializeNode(const CNode &node, ServiceFlags our_services)=0
Initialize a peer (setup state)
static bool HasFlag(NetPermissionFlags flags, NetPermissionFlags f)
ReadStatus FillBlock(CBlock &block, const std::vector< CTransactionRef > &vtx_missing, bool segwit_active)
bool IsTxAvailable(size_t index) const
ReadStatus InitData(const CBlockHeaderAndShortTxIDs &cmpctblock, const std::vector< std::pair< Wtxid, CTransactionRef > > &extra_txn)
virtual void UpdateLastBlockAnnounceTime(NodeId node, NodeClock::time_point time)=0
This function is used for testing the stale tip eviction logic, see denialofservice_tests....
virtual util::Expected< void, std::string > FetchBlock(NodeId peer_id, const CBlockIndex &block_index)=0
Attempt to manually fetch block from a given peer.
virtual ServiceFlags GetDesirableServiceFlags(ServiceFlags services) const =0
Gets the set of service flags which are "desirable" for a given peer.
virtual void StartScheduledTasks(CScheduler &scheduler)=0
Begin running background tasks, should only be called once.
virtual std::vector< node::TxOrphanage::OrphanInfo > GetOrphanTransactions()=0
static std::unique_ptr< PeerManager > make(CConnman &connman, AddrMan &addrman, BanMan *banman, ChainstateManager &chainman, CTxMemPool &pool, node::Warnings &warnings, Options opts)
virtual void UnitTestMisbehaving(NodeId peer_id)=0
virtual bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) const =0
Get statistics from node state.
virtual void CheckForStaleTipAndEvictPeers()=0
Evict extra outbound peers.
Store a list of transactions to be broadcast privately.
@ QueueFull
Rejected: the queue is already at MAX_TRANSACTIONS.
@ AlreadyPresent
The transaction was already present with send attempts remaining; no change.
@ Added
The transaction was newly added or reset after exhausting its send attempts.
static constexpr size_t MAX_TRANSACTIONS
Maximum number of transactions tracked simultaneously.
static constexpr size_t INITIAL_CONNECTION_COUNT
Number of connections to make for initial broadcast.
I randrange(I range) noexcept
Generate a random integer in the range [0..range), with range > 0.
bool Contains(Network net) const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
std::string GetDebugMessage() const
std::string ToString() const
256-bit unsigned big integer.
std::string ToString() const
CBlockIndex * LookupBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
CBlockFileInfo *GetBlockFileInfo(size_t n) EXCLUSIVE_LOCKS_REQUIRED(bool WriteBlockUndo(const CBlockUndo &blockundo, BlockValidationState &state, CBlockIndex &block) EXCLUSIVE_LOCKS_REQUIRED(FlatFilePos WriteBlock(const CBlock &block, int nHeight) EXCLUSIVE_LOCKS_REQUIRED(void UpdateBlockInfo(const CBlock &block, unsigned int nHeight, const FlatFilePos &pos) EXCLUSIVE_LOCKS_REQUIRED(bool IsPruneMode() const
Get block file info entry for one block file.
bool LoadingBlocks() const
ReadRawBlockResult ReadRawBlock(const FlatFilePos &pos, std::optional< std::pair< size_t, size_t > > block_part=std::nullopt) const
bool ReadBlock(CBlock &block, const FlatFilePos &pos, const std::optional< uint256 > &expected_hash) const
Functions for disk access for blocks.
Class responsible for deciding what transactions to request and, once downloaded, whether and how to ...
Manages warning messages within a node.
std::string ToString() const
const uint256 & ToUint256() const LIFETIMEBOUND
The util::Expected class provides a standard way for low-level functions to return either error value...
A token bucket rate limiter.
bool decrement(double n=1.0, double floor=0.0)
Consume n tokens.
void increment(const time_point &now)
Refill tokens based on elapsed time since last call.
double value() const
Current token balance.
The util::Unexpected class represents an unexpected value stored in util::Expected.
std::string TransportTypeAsString(TransportProtocolType transport_type)
Convert TransportProtocolType enum to a string value.
@ BLOCK_HEADER_LOW_WORK
the block header may be on a too-little-work chain
@ BLOCK_INVALID_HEADER
invalid proof of work or time too old
@ BLOCK_CACHED_INVALID
this block was cached as being invalid and we didn't store the reason why
@ BLOCK_CONSENSUS
invalid by consensus rules (excluding any below reasons)
@ BLOCK_MISSING_PREV
We don't have the previous block the checked one is built on.
@ BLOCK_INVALID_PREV
A block this one builds on is invalid.
@ BLOCK_MUTATED
the block's data didn't match the data committed to by the PoW
@ BLOCK_TIME_FUTURE
block timestamp was > 2 hours in the future (or our clock is bad)
@ BLOCK_RESULT_UNSET
initial value. Block has not yet been rejected
@ TX_MISSING_INPUTS
transaction was missing some of its inputs
@ TX_UNKNOWN
transaction was not validated because package failed
@ TX_NO_MEMPOOL
this node does not have a mempool so can't validate the transaction
@ TX_RESULT_UNSET
initial value. Tx has not yet been rejected
static size_t RecursiveDynamicUsage(const CScript &script)
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
bool DeploymentActiveAfter(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms, Consensus::BuriedDeployment dep, VersionBitsCache &versionbitscache)
Determine if a deployment is active for the next block.
bool DeploymentActiveAt(const CBlockIndex &index, const Consensus::Params ¶ms, Consensus::BuriedDeployment dep, VersionBitsCache &versionbitscache)
Determine if a deployment is active for this block.
is a home for simple enum and struct type definitions that can be used internally by functions in the...
#define LogTrace(category,...)
#define LogDebug(category,...)
CSerializedNetMsg Make(std::string msg_type, Args &&... args)
Bitcoin protocol message types.
constexpr const char * FILTERCLEAR
The filterclear message tells the receiving peer to remove a previously-set bloom filter.
constexpr const char * FEEFILTER
The feefilter message tells the receiving peer not to inv us any txs which do not meet the specified ...
constexpr const char * SENDHEADERS
Indicates that a node prefers to receive new block announcements via a "headers" message rather than ...
constexpr const char * GETBLOCKS
The getblocks message requests an inv message that provides block header hashes starting from a parti...
constexpr const char * HEADERS
The headers message sends one or more block headers to a node which previously requested certain head...
constexpr const char * ADDR
The addr (IP address) message relays connection information for peers on the network.
constexpr const char * GETBLOCKTXN
Contains a BlockTransactionsRequest Peer should respond with "blocktxn" message.
constexpr const char * CMPCTBLOCK
Contains a CBlockHeaderAndShortTxIDs object - providing a header and list of "short txids".
constexpr const char * CFCHECKPT
cfcheckpt is a response to a getcfcheckpt request containing a vector of evenly spaced filter headers...
constexpr const char * SENDADDRV2
The sendaddrv2 message signals support for receiving ADDRV2 messages (BIP155).
constexpr const char * GETADDR
The getaddr message requests an addr message from the receiving node, preferably one with lots of IP ...
constexpr const char * GETCFILTERS
getcfilters requests compact filters for a range of blocks.
constexpr const char * PONG
The pong message replies to a ping message, proving to the pinging node that the ponging node is stil...
constexpr const char * BLOCKTXN
Contains a BlockTransactions.
constexpr const char * CFHEADERS
cfheaders is a response to a getcfheaders request containing a filter header and a vector of filter h...
constexpr const char * PING
The ping message is sent periodically to help confirm that the receiving peer is still connected.
constexpr const char * FILTERLOAD
The filterload message tells the receiving peer to filter all relayed transactions and requested merk...
constexpr const char * SENDTXRCNCL
Contains a 4-byte version number and an 8-byte salt.
constexpr const char * ADDRV2
The addrv2 message relays connection information for peers on the network just like the addr message,...
constexpr const char * VERACK
The verack message acknowledges a previously-received version message, informing the connecting node ...
constexpr const char * GETHEADERS
The getheaders message requests a headers message that provides block headers starting from a particu...
constexpr const char * FILTERADD
The filteradd message tells the receiving peer to add a single element to a previously-set bloom filt...
constexpr const char * CFILTER
cfilter is a response to a getcfilters request containing a single compact filter.
constexpr const char * FEATURE
BIP 434 Peer feature negotiation.
constexpr const char * GETDATA
The getdata message requests one or more data objects from another node.
constexpr const char * SENDCMPCT
Contains a 1-byte bool and 8-byte LE version number.
constexpr const char * GETCFCHECKPT
getcfcheckpt requests evenly spaced compact filter headers, enabling parallelized download and valida...
constexpr const char * INV
The inv message (inventory message) transmits one or more inventories of objects known to the transmi...
constexpr const char * TX
The tx message transmits a single transaction.
constexpr const char * MEMPOOL
The mempool message requests the TXIDs of transactions that the receiving node has verified as valid ...
constexpr const char * NOTFOUND
The notfound message is a reply to a getdata message which requested an object the receiving node doe...
constexpr const char * MERKLEBLOCK
The merkleblock message is a reply to a getdata message which requested a block using the inventory t...
constexpr const char * WTXIDRELAY
Indicates that a node prefers to relay transactions via wtxid, rather than txid.
constexpr const char * BLOCK
The block message transmits a single serialized block.
constexpr const char * GETCFHEADERS
getcfheaders requests a compact filter header and the filter hashes for a range of blocks,...
constexpr const char * VERSION
The version message provides information about the transmitting node to the receiving node at the beg...
constexpr int32_t MAX_PEER_TX_ANNOUNCEMENTS
Maximum number of transactions to consider for requesting, per peer.
""_hex is a compile-time user-defined literal returning a std::array<std::byte>, equivalent to ParseH...
bool ShouldDebugLog(Category)
Return whether messages with specified category should be debug logged.
bool ShouldTraceLog(Category)
Return whether messages with specified category should be trace logged.
std::string ToString(const T &t)
Locale-independent version of std::to_string.
auto Join(const C &container, const S &separator, UnaryOp unary_op)
Join all container items.
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
std::optional< CService > GetLocalAddrForPeer(CNode &node)
Returns a local address that we should advertise to this peer.
std::function< void(const CAddress &addr, const std::string &msg_type, std::span< const unsigned char > data, bool is_incoming)> CaptureMessage
Defaults to CaptureMessageToFile(), but can be overridden by unit tests.
bool SeenLocal(const CService &addr)
vote for a local address
constexpr unsigned int MAX_SUBVERSION_LENGTH
Maximum length of the user agent string in version message.
constexpr std::chrono::minutes TIMEOUT_INTERVAL
Time after which to disconnect, after waiting for a ping response (or inactivity).
static constexpr auto HEADERS_RESPONSE_TIME
How long to wait for a peer to respond to a getheaders request.
static constexpr size_t MAX_ADDR_TO_SEND
The maximum number of address records permitted in an ADDR message.
static constexpr auto INVENTORY_BUCKET_CHECK_DELAY
Delay between checking inventory bucket and backlog.
static constexpr size_t MAX_ADDR_PROCESSING_TOKEN_BUCKET
The soft limit of the address processing token bucket (the regular MAX_ADDR_RATE_PER_SECOND based inc...
static constexpr auto INVENTORY_BUCKET_BACKLOG_HEARTBEAT
Delay between inventory bucket backlog heartbeat log entries.
static const int MAX_BLOCKS_IN_TRANSIT_PER_PEER
Number of blocks that can be requested at any given time from a single peer.
static constexpr auto BLOCK_STALLING_TIMEOUT_DEFAULT
Default time during which a peer must stall block download progress before being disconnected.
static constexpr auto AVG_FEEFILTER_BROADCAST_INTERVAL
Average delay between feefilter broadcasts in seconds.
static constexpr auto EXTRA_PEER_CHECK_INTERVAL
How frequently to check for extra outbound peers and disconnect.
static const unsigned int BLOCK_DOWNLOAD_WINDOW
Size of the "block download window": how far ahead of our current height do we fetch?...
static constexpr int STALE_RELAY_AGE_LIMIT
Age after which a stale block will no longer be served if requested as protection against fingerprint...
static constexpr int HISTORICAL_BLOCK_AGE
Age after which a block is considered historical for purposes of rate limiting block relay.
static constexpr auto ROTATE_ADDR_RELAY_DEST_INTERVAL
Delay between rotating the peers we relay a particular address to.
static constexpr auto MANUAL_PEER_BLOCK_DOWNLOAD_COOLDOWN
Time to avoid requesting blocks from a manual peer after it stalls block download.
static constexpr auto MINIMUM_CONNECT_TIME
Minimum time an outbound-peer-eviction candidate must be connected for, in order to evict.
static constexpr auto CHAIN_SYNC_TIMEOUT
Timeout for (unprotected) outbound peers to sync to our chainwork.
static constexpr auto OUTBOUND_INVENTORY_BROADCAST_INTERVAL
Average delay between trickled inventory transmissions for outbound peers.
static const unsigned int NODE_NETWORK_LIMITED_MIN_BLOCKS
Minimum blocks required to signal NODE_NETWORK_LIMITED.
static constexpr auto AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL
Average delay between local address broadcasts.
static const int MAX_BLOCKTXN_DEPTH
Maximum depth of blocks we're willing to respond to GETBLOCKTXN requests for.
static constexpr size_t INVENTORY_BUCKET_BACKLOG_CAPACITY
Empty backlog target capacity.
static constexpr int32_t MAX_OUTBOUND_PEERS_TO_PROTECT_FROM_DISCONNECT
Protect at least this many outbound peers from disconnection due to slow/ behind headers chain.
static constexpr auto INBOUND_INVENTORY_BROADCAST_INTERVAL
Average delay between trickled inventory transmissions for inbound peers.
static constexpr auto MAX_FEEFILTER_CHANGE_DELAY
Maximum feefilter broadcast delay after significant change.
static constexpr uint32_t MAX_GETCFILTERS_SIZE
Maximum number of compact filters that may be requested with one getcfilters.
static constexpr double OUTBOUND_INVENTORY_BUCKET_MULTIPLIER
Multiplier for the inventory bucket rate for outbounds.
static constexpr auto HEADERS_DOWNLOAD_TIMEOUT_BASE
Headers download timeout.
static const unsigned int MAX_GETDATA_SZ
Limit to avoid sending big packets.
static constexpr double BLOCK_DOWNLOAD_TIMEOUT_BASE
Block download timeout base, expressed in multiples of the block interval (i.e.
static constexpr auto PRIVATE_BROADCAST_MAX_CONNECTION_LIFETIME
Private broadcast connections must complete within this time.
static constexpr auto STALE_CHECK_INTERVAL
How frequently to check for stale tips.
static constexpr auto AVG_ADDRESS_BROADCAST_INTERVAL
Average delay between peer address broadcasts.
static const unsigned int MAX_LOCATOR_SZ
The maximum number of entries in a locator.
static constexpr double BLOCK_DOWNLOAD_TIMEOUT_PER_PEER
Additional block download timeout per parallel downloading peer (i.e.
static constexpr double MAX_ADDR_RATE_PER_SECOND
The maximum rate of address records we're willing to process on average.
static constexpr auto PING_INTERVAL
Time between pings automatically sent out for latency probing and keepalive.
static constexpr size_t INVENTORY_BUCKET_BACKLOG_HEARTBEAT_MIN
Minimum backlog to trigger heartbeat log entries.
static const int MAX_CMPCTBLOCK_DEPTH
Maximum depth of blocks we're willing to serve as compact blocks to peers when requested.
static const unsigned int MAX_BLOCKS_TO_ANNOUNCE
Maximum number of headers to announce when relaying blocks with headers message.
static const unsigned int NODE_NETWORK_LIMITED_ALLOW_CONN_BLOCKS
Window, in blocks, for connecting to NODE_NETWORK_LIMITED peers.
static constexpr uint32_t MAX_GETCFHEADERS_SIZE
Maximum number of cf hashes that may be requested with one getcfheaders.
static constexpr auto BLOCK_STALLING_TIMEOUT_MAX
Maximum timeout for stalling block download.
static constexpr auto HEADERS_DOWNLOAD_TIMEOUT_PER_HEADER
static constexpr uint64_t RANDOMIZER_ID_ADDRESS_RELAY
SHA256("main address relay")[0:8].
static constexpr size_t MAX_PCT_ADDR_TO_SEND
the maximum percentage of addresses from our addrman to return in response to a getaddr message.
static constexpr auto POST_BLOCK_PONG_GRACE
Time to wait for a pong after the last block a peer delivered, before applying the ping timeout.
static const unsigned int MAX_INV_SZ
The maximum number of entries in an 'inv' protocol message.
constexpr unsigned int MAX_CMPCTBLOCKS_INFLIGHT_PER_BLOCK
Maximum number of outstanding CMPCTBLOCK requests for the same block.
constexpr uint64_t CMPCTBLOCKS_VERSION
The compactblocks version we support.
ReachableNets g_reachable_nets
bool IsProxy(const CNetAddr &addr)
constexpr unsigned int DEFAULT_MIN_RELAY_TX_FEE
Default for -minrelaytxfee, minimum relay fee for transactions.
constexpr TransactionSerParams TX_NO_WITNESS
constexpr TransactionSerParams TX_WITH_WITNESS
std::shared_ptr< const CTransaction > CTransactionRef
GenTxid ToGenTxid(const CInv &inv)
Convert a TX/WITNESS_TX/WTX CInv to a GenTxid.
constexpr size_t MAX_FEATUREDATA_LENGTH
constexpr uint32_t MSG_WITNESS_FLAG
getdata message type flags
@ MSG_WTX
Defined in BIP 339.
@ MSG_CMPCT_BLOCK
Defined in BIP152.
@ MSG_WITNESS_BLOCK
Defined in BIP144.
ServiceFlags
nServices flags
constexpr size_t MAX_FEATUREID_LENGTH
static bool MayHaveUsefulAddressDB(ServiceFlags services)
Checks if a peer with the given service flags may be capable of having a robust address-storage DB.
constexpr int MIN_PEER_PROTO_VERSION
disconnect from peers older than this proto version
constexpr int SHORT_IDS_BLOCKS_VERSION
short-id-based block download starts with this version
constexpr int BIP0031_VERSION
BIP 0031, pong message, is enabled for all versions AFTER this one.
constexpr int FEEFILTER_VERSION
"feefilter" tells peers to filter invs to you by fee starts with this version
constexpr int WTXID_RELAY_VERSION
"wtxidrelay" message type for wtxid-based relay starts with this version
constexpr int INVALID_CB_NO_BAN_VERSION
not banning for invalid compact blocks starts with this version
constexpr int FEATURE_VERSION
"feature" message type for feature negotiation starts with this version
constexpr int SENDHEADERS_VERSION
"sendheaders" message type and announcing blocks with headers starts with this version
constexpr unsigned int MAX_SCRIPT_ELEMENT_SIZE
#define LIMITED_VECTOR(obj, n)
#define LIMITED_STRING(obj, n)
uint64_t ReadCompactSize(Stream &is, bool range_check=true)
Decode a CompactSize-encoded variable-length integer.
constexpr auto MakeUCharSpan(const V &v) -> decltype(UCharSpanCast(std::span{v}))
Like the std::span constructor, but for (const) unsigned char member types only.
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
std::vector< uint256 > vHave
NodeClock::time_point m_last_block_announcement
NodeClock::duration m_ping_wait
std::vector< int > vHeightInFlight
CAmount m_fee_filter_received
std::chrono::seconds time_offset
bool m_addr_relay_enabled
uint64_t m_addr_rate_limited
uint64_t m_addr_processed
ServiceFlags their_services
Parameters that influence chain consensus.
int64_t nPowTargetSpacing
std::chrono::seconds PowTargetSpacing() const
Validation result for a transaction evaluated by MemPoolAccept (single or package).
const ResultType m_result_type
Result type.
const TxValidationState m_state
Contains information about why the transaction failed.
@ DIFFERENT_WITNESS
Valid, transaction was already in the mempool.
@ INVALID
Fully validated, valid.
const std::list< CTransactionRef > m_replaced_transactions
Mempool transactions replaced by the tx.
Version of the system clock that is mockable in the context of tests (via FakeNodeClock or SetMockTim...
static time_point now() noexcept
Return current system time or mocked time, if set.
std::chrono::time_point< NodeClock > time_point
static constexpr time_point epoch
Validation result for package mempool acceptance.
std::chrono::seconds median_outbound_time_offset
Information about chainstate that notifications are sent from.
bool historical
Whether this is a historical chainstate downloading old blocks to validate an assumeutxo snapshot,...
CFeeRate min_relay_feerate
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation)
#define AssertLockNotHeld(cs)
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
#define AssertLockHeld(cs)
COutPoint ProcessBlock(const NodeContext &node, const std::shared_ptr< CBlock > &block)
Returns the generated coin (or Null if the block was invalid).
#define EXCLUSIVE_LOCKS_REQUIRED(...)
#define LOCKS_EXCLUDED(...)
#define ACQUIRED_BEFORE(...)
#define TRACEPOINT(context,...)
#define TRACEPOINT_SEMAPHORE(context, event)
consteval auto _(util::TranslatedLiteral str)
ReconciliationRegisterResult
constexpr uint32_t TXRECONCILIATION_VERSION
Supported transaction reconciliation protocol version.
std::string SanitizeString(std::string_view str, int rule)
Remove unsafe chars.
constexpr int64_t count_seconds(std::chrono::seconds t)
std::chrono::time_point< NodeClock, std::chrono::seconds > NodeSeconds
constexpr auto Ticks(Dur2 d)
Helper to count the seconds of a duration/time_point.
PackageMempoolAcceptResult ProcessNewPackage(Chainstate &active_chainstate, CTxMemPool &pool, const Package &package, bool test_accept, const std::optional< CFeeRate > &client_maxfeerate)
Validate (and maybe submit) a package to the mempool.
bool IsBlockMutated(const CBlock &block, bool check_witness_root)
Check if a block has been mutated (with respect to its merkle root and witness commitments).
bool HasValidProofOfWork(std::span< const CBlockHeader > headers, const Consensus::Params &consensusParams)
Check that the proof of work on each blockheader matches the value in nBits.
arith_uint256 CalculateClaimedHeadersWork(std::span< const CBlockHeader > headers)
Return the sum of the claimed work on a given set of headers.
@ UNVALIDATED
Blocks after an assumeutxo snapshot have been validated but the snapshot itself has not been validate...
constexpr unsigned int MIN_BLOCKS_TO_KEEP
Block files containing a block-height within MIN_BLOCKS_TO_KEEP of ActiveChain().Tip() will not be pr...