74#include <initializer_list>
212 std::unique_ptr<PartiallyDownloadedBlock> partialBlock;
246 std::atomic<ServiceFlags> m_their_services{
NODE_NONE};
249 const bool m_is_inbound;
252 Mutex m_misbehavior_mutex;
257 Mutex m_block_inv_mutex;
277 std::atomic<int> m_starting_height{-1};
280 std::atomic<uint64_t> m_ping_nonce_sent{0};
282 std::atomic<std::chrono::microseconds> m_ping_start{0
us};
284 std::atomic<bool> m_ping_queued{
false};
287 std::atomic<bool> m_wtxid_relay{
false};
299 bool m_relay_txs
GUARDED_BY(m_bloom_filter_mutex){
false};
325 std::atomic<CAmount> m_fee_filter_received{0};
331 LOCK(m_tx_relay_mutex);
333 m_tx_relay = std::make_unique<Peer::TxRelay>();
368 std::atomic_bool m_addr_relay_enabled{
false};
372 mutable Mutex m_addr_send_times_mutex;
379 std::atomic_bool m_wants_addrv2{
false};
388 std::atomic<uint64_t> m_addr_rate_limited{0};
390 std::atomic<uint64_t> m_addr_processed{0};
396 Mutex m_getdata_requests_mutex;
404 Mutex m_headers_sync_mutex;
410 std::atomic<bool> m_sent_sendheaders{
false};
420 std::atomic<std::chrono::seconds> m_time_offset{0
s};
429 mutable Mutex m_tx_relay_mutex;
435using PeerRef = std::shared_ptr<Peer>;
447 uint256 hashLastUnknownBlock{};
453 bool fSyncStarted{
false};
455 std::chrono::microseconds m_stalling_since{0
us};
456 std::list<QueuedBlock> vBlocksInFlight;
458 std::chrono::microseconds m_downloading_since{0
us};
460 bool fPreferredDownload{
false};
462 bool m_requested_hb_cmpctblocks{
false};
464 bool m_provides_cmpctblocks{
false};
490 struct ChainSyncTimeoutState {
492 std::chrono::seconds m_timeout{0
s};
496 bool m_sent_getheaders{
false};
498 bool m_protect{
false};
501 ChainSyncTimeoutState m_chain_sync;
504 int64_t m_last_block_announcement{0};
519 void BlockDisconnected(
const std::shared_ptr<const CBlock> &block,
const CBlockIndex* pindex)
override
523 void BlockChecked(
const std::shared_ptr<const CBlock>& block,
const BlockValidationState& state)
override
525 void NewPoWValidBlock(
const CBlockIndex *pindex,
const std::shared_ptr<const CBlock>& pblock)
override
531 bool HasAllDesirableServiceFlags(
ServiceFlags services)
const override;
532 bool ProcessMessages(
CNode&
node, std::atomic<bool>& interrupt)
override
533 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !m_most_recent_block_mutex, !m_headers_presync_mutex, g_msgproc_mutex, !m_tx_download_mutex);
538 void StartScheduledTasks(
CScheduler& scheduler)
override;
539 void CheckForStaleTipAndEvictPeers()
override;
550 void SetBestBlock(
int height,
std::chrono::
seconds time)
override
552 m_best_height = height;
553 m_best_block_time = time;
562 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !m_most_recent_block_mutex, !m_headers_presync_mutex, g_msgproc_mutex, !m_tx_download_mutex);
586 void Misbehaving(Peer& peer,
const std::string& message);
726 template <
typename... Args>
782 std::unique_ptr<TxReconciliationTracker> m_txreconciliation;
785 std::atomic<int> m_best_height{-1};
787 std::atomic<std::chrono::seconds> m_best_block_time{0
s};
795 const Options m_opts;
805 mutable Mutex m_peer_mutex;
841 std::atomic<int> m_wtxid_relay_peers{0};
865 Mutex m_most_recent_block_mutex;
873 Mutex m_headers_presync_mutex;
881 using HeadersPresyncStats = std::pair<arith_uint256, std::optional<std::pair<int64_t, uint32_t>>>;
887 std::atomic_bool m_headers_presync_should_signal{
false};
1109 return const_cast<CNodeState*
>(std::as_const(*this).State(
pnode));
1122void PeerManagerImpl::AddAddressKnown(Peer& peer,
const CAddress& addr)
1124 assert(peer.m_addr_known);
1125 peer.m_addr_known->insert(addr.
GetKey());
1128void PeerManagerImpl::PushAddress(Peer& peer,
const CAddress& addr)
1133 assert(peer.m_addr_known);
1136 peer.m_addrs_to_send[m_rng.randrange(peer.m_addrs_to_send.size())] = addr;
1138 peer.m_addrs_to_send.push_back(addr);
1149 tx_relay->m_tx_inventory_known_filter.insert(hash);
1172std::chrono::microseconds PeerManagerImpl::NextInvToInbounds(std::chrono::microseconds now,
1177 auto& timer{it->second};
1184bool PeerManagerImpl::IsBlockRequested(
const uint256& hash)
1189bool PeerManagerImpl::IsBlockRequestedFromOutbound(
const uint256& hash)
1194 if (peer && !peer->m_is_inbound)
return true;
1200void PeerManagerImpl::RemoveBlockRequest(
const uint256& hash, std::optional<NodeId>
from_peer)
1221 if (state.vBlocksInFlight.begin() ==
list_it) {
1225 state.vBlocksInFlight.erase(
list_it);
1227 if (state.vBlocksInFlight.empty()) {
1231 state.m_stalling_since = 0
us;
1237bool PeerManagerImpl::BlockRequested(
NodeId nodeid,
const CBlockIndex& block, std::list<QueuedBlock>::iterator**
pit)
1241 CNodeState *state =
State(nodeid);
1242 assert(state !=
nullptr);
1248 if (
range.first->second.first == nodeid) {
1250 *
pit = &
range.first->second.second;
1259 std::list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(),
1260 {&block, std::unique_ptr<PartiallyDownloadedBlock>(pit ? new PartiallyDownloadedBlock(&m_mempool) : nullptr)});
1261 if (state->vBlocksInFlight.size() == 1) {
1273void PeerManagerImpl::MaybeSetPeerAsAnnouncingHeaderAndIDs(
NodeId nodeid)
1280 if (m_opts.ignore_incoming_txs)
return;
1291 if (*it == nodeid) {
1299 if (peer && peer->m_is_inbound) {
1317 MakeAndPushMessage(*pnodeStop, NetMsgType::SENDCMPCT, false, CMPCTBLOCKS_VERSION);
1319 pnodeStop->m_bip152_highbandwidth_to = false;
1326 pfrom->m_bip152_highbandwidth_to =
true;
1332bool PeerManagerImpl::TipMayBeStale()
1336 if (m_last_tip_update.load() == 0s) {
1342int64_t PeerManagerImpl::ApproximateBestBlockDepth()
const
1347bool PeerManagerImpl::CanDirectFetch()
1354 if (state->pindexBestKnownBlock && pindex == state->pindexBestKnownBlock->
GetAncestor(pindex->nHeight))
1356 if (state->pindexBestHeaderSent && pindex == state->pindexBestHeaderSent->
GetAncestor(pindex->nHeight))
1361void PeerManagerImpl::ProcessBlockAvailability(
NodeId nodeid) {
1362 CNodeState *state =
State(nodeid);
1363 assert(state !=
nullptr);
1365 if (!state->hashLastUnknownBlock.
IsNull()) {
1368 if (state->pindexBestKnownBlock ==
nullptr || pindex->
nChainWork >= state->pindexBestKnownBlock->
nChainWork) {
1369 state->pindexBestKnownBlock = pindex;
1371 state->hashLastUnknownBlock.
SetNull();
1376void PeerManagerImpl::UpdateBlockAvailability(
NodeId nodeid,
const uint256 &hash) {
1377 CNodeState *state =
State(nodeid);
1378 assert(state !=
nullptr);
1385 if (state->pindexBestKnownBlock ==
nullptr || pindex->
nChainWork >= state->pindexBestKnownBlock->
nChainWork) {
1386 state->pindexBestKnownBlock = pindex;
1390 state->hashLastUnknownBlock = hash;
1395void PeerManagerImpl::FindNextBlocksToDownload(
const Peer& peer,
unsigned int count, std::vector<const CBlockIndex*>&
vBlocks,
NodeId&
nodeStaller)
1401 CNodeState *state =
State(peer.m_id);
1402 assert(state !=
nullptr);
1419 LogDebug(
BCLog::NET,
"Not downloading blocks from peer=%d, which doesn't have the snapshot block in its best chain.\n", peer.m_id);
1428 if (state->pindexLastCommonBlock ==
nullptr ||
1430 state->pindexBestKnownBlock->
GetAncestor(state->pindexLastCommonBlock->
nHeight) != state->pindexLastCommonBlock) {
1433 if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
1476 std::vector<const CBlockIndex*>
vToFetch;
1488 for (
unsigned int i =
nToFetch - 1; i > 0; i--) {
1509 state->pindexLastCommonBlock = pindex;
1548void PeerManagerImpl::PushNodeVersion(
CNode&
pnode,
const Peer& peer)
1557 if (
pnode.IsPrivateBroadcastConn()) {
1586 pnode.GetLocalNonce(),
1592 BCLog::NET,
"send version message: version=%d, blocks=%d%s, txrelay=%d, peer=%d\n",
1625void PeerManagerImpl::ReattemptInitialBroadcast(
CScheduler& scheduler)
1632 if (tx !=
nullptr) {
1633 InitiateTxBroadcastToAll(txid, tx->GetWitnessHash());
1645void PeerManagerImpl::ReattemptPrivateBroadcast(
CScheduler& scheduler)
1657 "Reattempting broadcast of stale txid=%s wtxid=%s",
1676void PeerManagerImpl::FinalizeNode(
const CNode&
node)
1689 m_wtxid_relay_peers -= peer->m_wtxid_relay;
1690 assert(m_wtxid_relay_peers >= 0);
1692 CNodeState *state =
State(nodeid);
1693 assert(state !=
nullptr);
1695 if (state->fSyncStarted)
1698 for (
const QueuedBlock& entry : state->vBlocksInFlight) {
1710 LOCK(m_tx_download_mutex);
1713 if (m_txreconciliation) m_txreconciliation->ForgetPeer(nodeid);
1728 assert(m_wtxid_relay_peers == 0);
1732 if (
node.fSuccessfullyConnected &&
1733 !
node.IsBlockOnlyConn() && !
node.IsPrivateBroadcastConn() && !
node.IsInboundConn()) {
1741 LOCK(m_headers_presync_mutex);
1744 if (
node.IsPrivateBroadcastConn() &&
1753bool PeerManagerImpl::HasAllDesirableServiceFlags(
ServiceFlags services)
const
1756 return !(GetDesirableServiceFlags(services) & (
~services));
1774 return it !=
m_peer_map.end() ? it->second :
nullptr;
1783 ret = std::move(it->second);
1793 const CNodeState* state =
State(nodeid);
1794 if (state ==
nullptr)
1796 stats.
nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->
nHeight : -1;
1797 stats.
nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->
nHeight : -1;
1798 for (
const QueuedBlock&
queue : state->vBlocksInFlight) {
1805 if (peer ==
nullptr)
return false;
1815 if ((0 != peer->m_ping_nonce_sent) && (0 != peer->m_ping_start.load().count())) {
1836 LOCK(peer->m_headers_sync_mutex);
1837 if (peer->m_headers_sync) {
1846std::vector<node::TxOrphanage::OrphanInfo> PeerManagerImpl::GetOrphanTransactions()
1848 LOCK(m_tx_download_mutex);
1856 .ignores_incoming_txs = m_opts.ignore_incoming_txs,
1860std::vector<PrivateBroadcast::TxBroadcastInfo> PeerManagerImpl::GetPrivateBroadcastInfo()
const
1865std::vector<CTransactionRef> PeerManagerImpl::AbortPrivateBroadcast(
const uint256&
id)
1872 if (tx->GetHash().ToUint256() !=
id && tx->GetWitnessHash().ToUint256() !=
id)
continue;
1885void PeerManagerImpl::AddToCompactExtraTransactions(
const CTransactionRef& tx)
1887 if (m_opts.max_extra_txs <= 0)
1895void PeerManagerImpl::Misbehaving(Peer& peer,
const std::string& message)
1897 LOCK(peer.m_misbehavior_mutex);
1899 const std::string
message_prefixed = message.empty() ?
"" : (
": " + message);
1900 peer.m_should_discourage =
true;
1948 if (message !=
"") {
2002 return std::make_unique<PeerManagerImpl>(connman, addrman, banman, chainman, pool, warnings, opts);
2008 : m_rng{opts.deterministic_rng},
2010 m_chainparams(chainman.GetParams()),
2014 m_chainman(chainman),
2017 m_warnings{warnings},
2022 if (opts.reconcile_txs) {
2027void PeerManagerImpl::StartScheduledTasks(
CScheduler& scheduler)
2040 if (m_opts.private_broadcast) {
2053 LOCK(m_tx_download_mutex);
2067void PeerManagerImpl::BlockConnected(
2069 const std::shared_ptr<const CBlock>& pblock,
2090 LOCK(m_tx_download_mutex);
2095void PeerManagerImpl::BlockDisconnected(
const std::shared_ptr<const CBlock> &block,
const CBlockIndex* pindex)
2097 LOCK(m_tx_download_mutex);
2105void PeerManagerImpl::NewPoWValidBlock(
const CBlockIndex *pindex,
const std::shared_ptr<const CBlock>& pblock)
2117 uint256 hashBlock(pblock->GetHash());
2118 const std::shared_future<CSerializedNetMsg>
lazy_ser{
2123 for (
const auto& tx : pblock->vtx) {
2128 LOCK(m_most_recent_block_mutex);
2146 LogDebug(
BCLog::NET,
"%s sending header-and-ids %s to peer=%d\n",
"PeerManager::NewPoWValidBlock",
2147 hashBlock.ToString(),
pnode->GetId());
2151 state.pindexBestHeaderSent = pindex;
2162 SetBestBlock(
pindexNew->nHeight, std::chrono::seconds{pindexNew->GetBlockTime()});
2183 Peer& peer = *it.second;
2184 LOCK(peer.m_block_inv_mutex);
2186 peer.m_blocks_for_headers_relay.push_back(hash);
2198void PeerManagerImpl::BlockChecked(
const std::shared_ptr<const CBlock>& block,
const BlockValidationState& state)
2202 const uint256 hash(block->GetHash());
2203 std::map<uint256, std::pair<NodeId, bool>>::iterator it =
mapBlockSource.find(hash);
2209 State(it->second.first)) {
2234bool PeerManagerImpl::AlreadyHaveBlock(
const uint256& block_hash)
2239void PeerManagerImpl::SendPings()
2245void PeerManagerImpl::InitiateTxBroadcastToAll(
const Txid& txid,
const Wtxid&
wtxid)
2249 Peer& peer = *it.second;
2259 if (
tx_relay->m_next_inv_send_time == 0s)
continue;
2262 if (!
tx_relay->m_tx_inventory_known_filter.contains(hash)) {
2268void PeerManagerImpl::InitiateTxBroadcastPrivate(
const CTransactionRef& tx)
2270 const auto txstr{
strprintf(
"txid=%s, wtxid=%s", tx->GetHash().ToString(), tx->GetWitnessHash().ToString())};
2271 if (m_tx_for_private_broadcast.
Add(tx)) {
2305 std::array<std::pair<uint64_t, Peer*>, 2>
best{{{0,
nullptr}, {0,
nullptr}}};
2323 for (
unsigned int i = 0; i <
nRelayNodes &&
best[i].first != 0; i++) {
2328void PeerManagerImpl::ProcessGetBlockData(
CNode&
pfrom, Peer& peer,
const CInv& inv)
2333 LOCK(m_most_recent_block_mutex);
2381 pfrom.fDisconnect =
true;
2391 pfrom.fDisconnect =
true;
2403 std::shared_ptr<const CBlock> pblock;
2417 pfrom.fDisconnect =
true;
2423 std::shared_ptr<CBlock>
pblockRead = std::make_shared<CBlock>();
2430 pfrom.fDisconnect =
true;
2482 LOCK(peer.m_block_inv_mutex);
2484 if (inv.
hash == peer.m_continuation_block) {
2488 std::vector<CInv>
vInv;
2491 peer.m_continuation_block.SetNull();
2500 [&](
const auto&
id) {
2505 return std::move(
txinfo.tx);
2510 LOCK(m_most_recent_block_mutex);
2526 std::deque<CInv>::iterator it = peer.m_getdata_requests.begin();
2532 while (it != peer.m_getdata_requests.end() && it->IsGenTxMsg()) {
2536 if (
pfrom.fPauseSend)
break;
2538 const CInv &inv = *it++;
2558 if (it != peer.m_getdata_requests.end() && !
pfrom.fPauseSend) {
2559 const CInv &inv = *it++;
2570 peer.m_getdata_requests.erase(peer.m_getdata_requests.begin(), it);
2591uint32_t PeerManagerImpl::GetFetchFlags(
const Peer& peer)
const
2603 for (
size_t i = 0; i < req.
indexes.size(); i++) {
2605 Misbehaving(peer,
"getblocktxn with out-of-bounds tx indices");
2619bool PeerManagerImpl::CheckHeadersPoW(
const std::vector<CBlockHeader>&
headers, Peer& peer)
2623 Misbehaving(peer,
"header with invalid proof of work");
2629 Misbehaving(peer,
"non-continuous headers sequence");
2654void PeerManagerImpl::HandleUnconnectingHeaders(
CNode&
pfrom, Peer& peer,
2655 const std::vector<CBlockHeader>&
headers)
2660 LogDebug(
BCLog::NET,
"received header %s: missing prev block %s, sending getheaders (%d) to end (peer=%d)\n",
2661 headers[0].GetHash().ToString(),
2662 headers[0].hashPrevBlock.ToString(),
2673bool PeerManagerImpl::CheckHeadersAreContinuous(
const std::vector<CBlockHeader>&
headers)
const
2685bool PeerManagerImpl::IsContinuationOfLowWorkHeadersSync(Peer& peer,
CNode&
pfrom, std::vector<CBlockHeader>&
headers)
2687 if (peer.m_headers_sync) {
2688 auto result = peer.m_headers_sync->ProcessNextHeaders(
headers,
headers.size() == m_opts.max_headers_result);
2690 if (result.success) peer.m_last_getheaders_timestamp = {};
2691 if (result.request_more) {
2692 auto locator = peer.m_headers_sync->NextHeadersRequestLocator();
2694 Assume(!locator.vHave.empty());
2697 if (!locator.vHave.empty()) {
2703 locator.vHave.front().ToString(),
pfrom.GetId());
2707 if (peer.m_headers_sync->GetState() == HeadersSyncState::State::FINAL) {
2708 peer.m_headers_sync.reset(
nullptr);
2713 LOCK(m_headers_presync_mutex);
2717 HeadersPresyncStats stats;
2718 stats.first = peer.m_headers_sync->GetPresyncWork();
2719 if (peer.m_headers_sync->GetState() == HeadersSyncState::State::PRESYNC) {
2720 stats.second = {peer.m_headers_sync->GetPresyncHeight(),
2721 peer.m_headers_sync->GetPresyncTime()};
2725 LOCK(m_headers_presync_mutex);
2733 const HeadersPresyncStats*
stat_best{
nullptr};
2749 m_headers_presync_should_signal =
true;
2753 if (result.success) {
2756 headers.swap(result.pow_validated_headers);
2759 return result.success;
2782 if (
headers.size() == m_opts.max_headers_result) {
2792 LOCK(peer.m_headers_sync_mutex);
2813bool PeerManagerImpl::IsAncestorOfBestHeaderOrTip(
const CBlockIndex* header)
2815 if (header ==
nullptr) {
2817 }
else if (m_chainman.m_best_header !=
nullptr && header == m_chainman.m_best_header->GetAncestor(header->
nHeight)) {
2850 std::vector<const CBlockIndex*>
vToFetch;
2890 if (!m_opts.ignore_incoming_txs &&
2909void PeerManagerImpl::UpdatePeerStateForReceivedHeaders(
CNode&
pfrom, Peer& peer,
2939 if (
pfrom.IsOutboundOrBlockRelayConn()) {
2940 LogInfo(
"outbound peer headers chain has insufficient work, %s\n",
pfrom.DisconnectMsg(
fLogIPs));
2941 pfrom.fDisconnect =
true;
2951 if (!
pfrom.fDisconnect &&
pfrom.IsFullOutboundConn() &&
nodestate->pindexBestKnownBlock !=
nullptr) {
2954 nodestate->m_chain_sync.m_protect =
true;
2960void PeerManagerImpl::ProcessHeadersMessage(
CNode&
pfrom, Peer& peer,
2961 std::vector<CBlockHeader>&&
headers,
2971 LOCK(peer.m_headers_sync_mutex);
2972 if (peer.m_headers_sync) {
2973 peer.m_headers_sync.reset(
nullptr);
2974 LOCK(m_headers_presync_mutex);
2979 peer.m_last_getheaders_timestamp = {};
3007 LOCK(peer.m_headers_sync_mutex);
3043 peer.m_last_getheaders_timestamp = {};
3091 "If this happens with all peers, consider database corruption (that -reindex may fix) "
3092 "or a potential consensus incompatibility.",
3132 ptx->GetHash().ToString(),
3133 ptx->GetWitnessHash().ToString(),
3159 tx->GetHash().ToString(),
3160 tx->GetWitnessHash().ToString(),
3163 InitiateTxBroadcastToAll(tx->GetHash(), tx->GetWitnessHash());
3176 const auto&
package = package_to_validate.m_txns;
3228bool PeerManagerImpl::ProcessOrphanTx(Peer& peer)
3265bool PeerManagerImpl::PrepareBlockFilterRequest(
CNode&
node, Peer& peer,
3277 node.fDisconnect =
true;
3289 node.fDisconnect =
true;
3297 "start height %d and stop height %d, %s\n",
3299 node.fDisconnect =
true;
3305 node.fDisconnect =
true;
3310 if (!filter_index) {
3335 std::vector<BlockFilter>
filters;
3337 LogDebug(
BCLog::NET,
"Failed to find block filter in index: filter_type=%s, start_height=%d, stop_hash=%s\n",
3342 for (
const auto& filter :
filters) {
3369 LogDebug(
BCLog::NET,
"Failed to find block filter header in index: filter_type=%s, block_hash=%s\n",
3377 LogDebug(
BCLog::NET,
"Failed to find block filter hashes in index: filter_type=%s, start_height=%d, stop_hash=%s\n",
3401 std::numeric_limits<uint32_t>::max(),
3410 for (
int i =
headers.size() - 1; i >= 0; i--) {
3415 LogDebug(
BCLog::NET,
"Failed to find block filter header in index: filter_type=%s, block_hash=%s\n",
3446 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
3479 Misbehaving(peer,
"previous compact block reconstruction attempt failed");
3490 Misbehaving(peer,
"invalid compact block/non-matching block transactions");
3498 std::vector<CInv>
invs;
3503 LogDebug(
BCLog::NET,
"Peer %d sent us a compact block but it failed to reconstruct, waiting on first download to complete\n",
pfrom.GetId());
3543 "Saw new %sheader hash=%s height=%d peer=%d%s",
3545 index.GetBlockHash().ToString(),
3557void PeerManagerImpl::PushPrivateBroadcastTx(
CNode&
node)
3564 node.fDisconnect =
true;
3570 tx->GetHash().ToString(), tx->HasWitness() ?
strprintf(
", wtxid=%s", tx->GetWitnessHash().ToString()) :
"",
3577 const std::chrono::microseconds time_received,
3586 if (
pfrom.nVersion != 0) {
3596 std::string cleanSubVer;
3606 if (!
pfrom.IsInboundConn())
3613 if (
pfrom.ExpectServicesFromConn() && !HasAllDesirableServiceFlags(nServices))
3615 LogDebug(
BCLog::NET,
"peer does not offer the expected services (%08x offered, %08x expected), %s\n",
3617 GetDesirableServiceFlags(nServices),
3619 pfrom.fDisconnect =
true;
3626 pfrom.fDisconnect =
true;
3630 if (!
vRecv.empty()) {
3638 if (!
vRecv.empty()) {
3643 if (!
vRecv.empty()) {
3651 LogInfo(
"connected to self at %s, disconnecting\n",
pfrom.addr.ToStringAddrPort());
3652 pfrom.fDisconnect =
true;
3663 if (
pfrom.IsInboundConn()) {
3670 pfrom.nVersion = nVersion;
3672 pfrom.m_has_all_wanted_services = HasAllDesirableServiceFlags(nServices);
3673 peer.m_their_services = nServices;
3677 pfrom.cleanSubVer = cleanSubVer;
3687 if (!
pfrom.IsBlockOnlyConn() &&
3688 !
pfrom.IsFeelerConn() &&
3690 auto*
const tx_relay = peer.SetTxRelay();
3699 LogDebug(
BCLog::NET,
"receive version message: %s: version %d, blocks=%d, us=%s, txrelay=%d, peer=%d%s%s\n",
3700 cleanSubVer,
pfrom.nVersion,
3704 if (
pfrom.IsPrivateBroadcastConn()) {
3710 pfrom.fDisconnect =
true;
3735 const auto*
tx_relay = peer.GetTxRelay();
3737 !
pfrom.IsAddrFetchConn() && !m_opts.ignore_incoming_txs) {
3758 if (!
pfrom.IsInboundConn()) {
3769 peer.m_getaddr_sent =
true;
3775 if (!
pfrom.IsInboundConn()) {
3794 if (!
pfrom.IsInboundConn()) {
3797 m_outbound_time_offsets.
Add(peer.m_time_offset);
3803 constexpr auto finalAlert{
"60010000000000000000000000ffffff7f00000000ffffff7ffeffff7f01ffffff7f00000000ffffff7f00ffffff7f002f555247454e543a20416c657274206b657920636f6d70726f6d697365642c2075706772616465207265717569726564004630440220653febd6410f470f6bae11cad19c48413becb1ac2c17f908fd0fd53bdc3abd5202206d0e9c96fe88d4a0f01ed9dedae2b6f9e00da94cad0fecaae66ecf689bf71b50"_hex};
3808 if (
pfrom.IsFeelerConn()) {
3810 pfrom.fDisconnect =
true;
3815 if (
pfrom.nVersion == 0) {
3822 if (
pfrom.fSuccessfullyConnected) {
3829 return strprintf(
"New %s peer connected: transport: %s, version: %d, blocks=%d peer=%d%s%s\n",
3830 pfrom.ConnectionTypeAsString(),
3832 pfrom.nVersion.load(), peer.m_starting_height,
3834 (mapped_as ?
strprintf(
", mapped_as=%d", mapped_as) :
""));
3839 if (
pfrom.IsInboundConn()) {
3845 if (
auto tx_relay = peer.GetTxRelay()) {
3855 return tx_relay->m_tx_inventory_to_send.empty() &&
3856 tx_relay->m_next_inv_send_time == 0s));
3859 if (
pfrom.IsPrivateBroadcastConn()) {
3860 pfrom.fSuccessfullyConnected =
true;
3879 if (m_txreconciliation) {
3880 if (!peer.m_wtxid_relay || !m_txreconciliation->IsPeerRegistered(
pfrom.GetId())) {
3884 m_txreconciliation->ForgetPeer(
pfrom.GetId());
3890 const CNodeState* state =
State(
pfrom.GetId());
3892 .m_preferred = state->fPreferredDownload,
3893 .m_relay_permissions = pfrom.HasPermission(NetPermissionFlags::Relay),
3894 .m_wtxid_relay = peer.m_wtxid_relay,
3898 pfrom.fSuccessfullyConnected =
true;
3903 peer.m_prefers_headers =
true;
3917 nodestate->m_provides_cmpctblocks =
true;
3928 if (
pfrom.fSuccessfullyConnected) {
3931 pfrom.fDisconnect =
true;
3935 if (!peer.m_wtxid_relay) {
3936 peer.m_wtxid_relay =
true;
3937 m_wtxid_relay_peers++;
3950 if (
pfrom.fSuccessfullyConnected) {
3953 pfrom.fDisconnect =
true;
3956 peer.m_wants_addrv2 =
true;
3964 if (!m_txreconciliation) {
3965 LogDebug(
BCLog::NET,
"sendtxrcncl from peer=%d ignored, as our node does not have txreconciliation enabled\n",
pfrom.GetId());
3969 if (
pfrom.fSuccessfullyConnected) {
3971 pfrom.fDisconnect =
true;
3978 pfrom.fDisconnect =
true;
3985 const auto*
tx_relay = peer.GetTxRelay();
3988 pfrom.fDisconnect =
true;
4005 LogDebug(
BCLog::NET,
"txreconciliation protocol violation (sendtxrcncl received from already registered peer), %s\n",
pfrom.DisconnectMsg(
fLogIPs));
4006 pfrom.fDisconnect =
true;
4010 pfrom.fDisconnect =
true;
4016 if (!
pfrom.fSuccessfullyConnected) {
4021 if (
pfrom.IsPrivateBroadcastConn()) {
4037 std::vector<CAddress>
vAddr;
4053 std::vector<CAddress>
vAddrOk;
4069 std::shuffle(
vAddr.begin(),
vAddr.end(), m_rng);
4076 if (peer.m_addr_token_bucket < 1.0) {
4082 peer.m_addr_token_bucket -= 1.0;
4111 LogDebug(
BCLog::NET,
"Received addr: %u addresses (%u processed, %u rate-limited) from peer=%d\n",
4115 if (
vAddr.size() < 1000) peer.m_getaddr_sent =
false;
4118 if (
pfrom.IsAddrFetchConn() &&
vAddr.size() > 1) {
4120 pfrom.fDisconnect =
true;
4126 std::vector<CInv>
vInv;
4147 if (peer.m_wtxid_relay) {
4170 pfrom.fDisconnect =
true;
4200 m_chainman.m_best_header->nHeight,
best_block->ToString(),
4203 if (!state.fSyncStarted) {
4204 peer.m_inv_triggered_getheaders_before_sync =
true;
4217 std::vector<CInv>
vInv;
4227 if (
vInv.size() > 0) {
4231 if (
pfrom.IsPrivateBroadcastConn()) {
4236 pfrom.fDisconnect =
true;
4248 peer.m_ping_queued =
true;
4253 pfrom.fDisconnect =
true;
4259 LOCK(peer.m_getdata_requests_mutex);
4260 peer.m_getdata_requests.insert(peer.m_getdata_requests.end(),
vInv.begin(),
vInv.end());
4274 pfrom.fDisconnect =
true;
4288 LOCK(m_most_recent_block_mutex);
4307 for (; pindex; pindex = m_chainman.
ActiveChain().Next(pindex))
4326 WITH_LOCK(peer.m_block_inv_mutex, {peer.m_continuation_block = pindex->GetBlockHash();});
4338 for (
size_t i = 1; i < req.
indexes.size(); ++i) {
4344 LOCK(m_most_recent_block_mutex);
4389 WITH_LOCK(peer.m_getdata_requests_mutex, peer.m_getdata_requests.push_back(inv));
4401 pfrom.fDisconnect =
true;
4415 if (m_chainman.
ActiveTip() ==
nullptr ||
4417 LogDebug(
BCLog::NET,
"Ignoring getheaders from peer=%d because active chain has too little work; sending empty response\n",
pfrom.GetId());
4448 int nLimit = m_opts.max_headers_result;
4450 for (; pindex; pindex = m_chainman.
ActiveChain().Next(pindex))
4476 pfrom.fDisconnect =
true;
4488 const Txid& txid =
ptx->GetHash();
4496 "network from peer=%d%s; stopping private broadcast attempts",
4513 if (!m_mempool.
exists(txid)) {
4514 LogInfo(
"Not relaying non-mempool transaction %s (wtxid=%s) from forcerelay peer=%d\n",
4517 LogInfo(
"Force relaying tx %s (wtxid=%s) from peer=%d\n",
4519 InitiateTxBroadcastToAll(txid,
wtxid);
4526 package_result.m_state.IsValid() ?
"package accepted" :
"package rejected");
4546 package_result.m_state.IsValid() ?
"package accepted" :
"package rejected");
4612 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
4650 std::vector<CInv>
vInv(1);
4669 if (!(*queuedBlockIt)->partialBlock)
4687 std::vector<CInv>
vInv(1);
4698 for (
size_t i = 0; i <
cmpctblock.BlockTxCount(); i++) {
4709 }
else if (
pfrom.m_bip152_highbandwidth_to &&
4710 (!
pfrom.IsInboundConn() ||
4735 std::vector<CTransactionRef> dummy;
4737 status =
tempBlock.FillBlock(*pblock, dummy,
4747 std::vector<CInv>
vInv(1);
4824 std::vector<CBlockHeader>
headers;
4828 if (
nCount > m_opts.max_headers_result) {
4833 for (
unsigned int n = 0; n <
nCount; n++) {
4842 if (m_headers_presync_should_signal.exchange(
false)) {
4843 HeadersPresyncStats stats;
4845 LOCK(m_headers_presync_mutex);
4865 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
4882 const uint256 hash(pblock->GetHash());
4910 if (!
pfrom.IsInboundConn()) {
4921 if (peer.m_getaddr_recvd) {
4925 peer.m_getaddr_recvd =
true;
4927 peer.m_addrs_to_send.clear();
4928 std::vector<CAddress>
vAddr;
4948 pfrom.fDisconnect =
true;
4958 pfrom.fDisconnect =
true;
4991 const auto ping_end = time_received;
5001 if (peer.m_ping_nonce_sent != 0) {
5002 if (
nonce == peer.m_ping_nonce_sent) {
5009 if (
pfrom.IsPrivateBroadcastConn()) {
5013 pfrom.fDisconnect =
true;
5029 sProblem =
"Unsolicited pong without ping";
5041 peer.m_ping_nonce_sent,
5046 peer.m_ping_nonce_sent = 0;
5054 pfrom.fDisconnect =
true;
5070 pfrom.m_bloom_filter_loaded =
true;
5071 pfrom.m_relays_txs =
true;
5079 pfrom.fDisconnect =
true;
5082 std::vector<unsigned char> vData;
5093 tx_relay->m_bloom_filter->insert(vData);
5107 pfrom.fDisconnect =
true;
5115 tx_relay->m_bloom_filter =
nullptr;
5118 pfrom.m_bloom_filter_loaded =
false;
5119 pfrom.m_relays_txs =
true;
5151 std::vector<CInv>
vInv;
5161 LOCK(m_tx_download_mutex);
5171bool PeerManagerImpl::MaybeDiscourageAndDisconnect(
CNode&
pnode, Peer& peer)
5174 LOCK(peer.m_misbehavior_mutex);
5177 if (!peer.m_should_discourage)
return false;
5179 peer.m_should_discourage =
false;
5184 LogWarning(
"Not punishing noban peer %d!", peer.m_id);
5188 if (
pnode.IsManualConn()) {
5190 LogWarning(
"Not punishing manually connected peer %d!", peer.m_id);
5194 if (
pnode.addr.IsLocal()) {
5198 pnode.m_inbound_onion ?
"inbound onion" :
"local", peer.m_id);
5199 pnode.fDisconnect =
true;
5221 if (!
node.IsInboundConn() && !peer.m_outbound_version_message_sent)
return false;
5224 LOCK(peer.m_getdata_requests_mutex);
5225 if (!peer.m_getdata_requests.empty()) {
5232 if (
node.fDisconnect)
5240 LOCK(peer.m_getdata_requests_mutex);
5241 if (!peer.m_getdata_requests.empty())
return true;
5245 if (
node.fPauseSend)
return false;
5258 node.m_addr_name.c_str(),
5259 node.ConnectionTypeAsString().c_str(),
5265 if (m_opts.capture_messages) {
5273 LOCK(peer.m_getdata_requests_mutex);
5274 if (!peer.m_getdata_requests.empty())
fMoreWork =
true;
5281 LOCK(m_tx_download_mutex);
5283 }
catch (
const std::exception&
e) {
5296 CNodeState &state = *
State(
pto.GetId());
5298 if (!state.m_chain_sync.m_protect &&
pto.IsOutboundOrBlockRelayConn() && state.fSyncStarted) {
5307 if (state.m_chain_sync.m_timeout != 0s) {
5308 state.m_chain_sync.m_timeout = 0
s;
5309 state.m_chain_sync.m_work_header =
nullptr;
5310 state.m_chain_sync.m_sent_getheaders =
false;
5312 }
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)) {
5320 state.m_chain_sync.m_work_header = m_chainman.
ActiveChain().
Tip();
5321 state.m_chain_sync.m_sent_getheaders =
false;
5322 }
else if (state.m_chain_sync.m_timeout > 0s &&
time_in_seconds > state.m_chain_sync.m_timeout) {
5326 if (state.m_chain_sync.m_sent_getheaders) {
5328 LogInfo(
"Outbound peer has old chain, best known block = %s, %s\n", state.pindexBestKnownBlock !=
nullptr ? state.pindexBestKnownBlock->
GetBlockHash().
ToString() :
"<none>",
pto.DisconnectMsg(
fLogIPs));
5329 pto.fDisconnect =
true;
5331 assert(state.m_chain_sync.m_work_header);
5339 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());
5340 state.m_chain_sync.m_sent_getheaders =
true;
5352void PeerManagerImpl::EvictExtraOutboundPeers(std::chrono::seconds now)
5364 if (!
pnode->IsBlockOnlyConn() ||
pnode->fDisconnect)
return;
5387 pnode->fDisconnect =
true;
5388 LogDebug(
BCLog::NET,
"disconnecting extra block-relay-only peer=%d (last block received at time %d)\n",
5392 LogDebug(
BCLog::NET,
"keeping block-relay-only peer=%d chosen for eviction (connect time: %d, blocks_in_flight: %d)\n",
5411 AssertLockHeld(::cs_main);
5415 if (!pnode->IsFullOutboundConn() || pnode->fDisconnect) return;
5416 CNodeState *state = State(pnode->GetId());
5417 if (state == nullptr) return;
5419 if (state->m_chain_sync.m_protect) return;
5422 if (!m_connman.MultipleManualOrFullOutboundConns(pnode->addr.GetNetwork())) return;
5423 if (state->m_last_block_announcement < oldest_block_announcement || (state->m_last_block_announcement == oldest_block_announcement && pnode->GetId() > worst_peer)) {
5424 worst_peer = pnode->GetId();
5425 oldest_block_announcement = state->m_last_block_announcement;
5440 pnode->fDisconnect =
true;
5443 LogDebug(
BCLog::NET,
"keeping outbound peer=%d chosen for eviction (connect time: %d, blocks_in_flight: %d)\n",
5460void PeerManagerImpl::CheckForStaleTipAndEvictPeers()
5472 LogInfo(
"Potential stale tip detected, will try using extra outbound peer (last tip update: %d seconds ago)\n",
5487void PeerManagerImpl::MaybeSendPing(
CNode&
node_to, Peer& peer, std::chrono::microseconds now)
5490 peer.m_ping_nonce_sent &&
5502 if (peer.m_ping_queued) {
5507 if (peer.m_ping_nonce_sent == 0 && now > peer.m_ping_start.load() +
PING_INTERVAL) {
5516 }
while (
nonce == 0);
5517 peer.m_ping_queued =
false;
5518 peer.m_ping_start = now;
5520 peer.m_ping_nonce_sent =
nonce;
5524 peer.m_ping_nonce_sent = 0;
5533 if (!peer.m_addr_relay_enabled)
return;
5535 LOCK(peer.m_addr_send_times_mutex);
5545 if (peer.m_next_local_addr_send != 0
us) {
5546 peer.m_addr_known->reset();
5550 if (peer.m_next_local_addr_send == 0
us) {
5556 if (peer.m_wants_addrv2) {
5584 bool ret = peer.m_addr_known->contains(addr.
GetKey());
5585 if (!
ret) peer.m_addr_known->insert(addr.
GetKey());
5588 peer.m_addrs_to_send.erase(std::remove_if(peer.m_addrs_to_send.begin(), peer.m_addrs_to_send.end(),
addr_already_known),
5589 peer.m_addrs_to_send.end());
5592 if (peer.m_addrs_to_send.empty())
return;
5594 if (peer.m_wants_addrv2) {
5599 peer.m_addrs_to_send.clear();
5602 if (peer.m_addrs_to_send.capacity() > 40) {
5603 peer.m_addrs_to_send.shrink_to_fit();
5607void PeerManagerImpl::MaybeSendSendHeaders(
CNode&
node, Peer& peer)
5615 CNodeState &state = *
State(
node.GetId());
5616 if (state.pindexBestKnownBlock !=
nullptr &&
5623 peer.m_sent_sendheaders =
true;
5628void PeerManagerImpl::MaybeSendFeefilter(
CNode&
pto, Peer& peer, std::chrono::microseconds
current_time)
5630 if (m_opts.ignore_incoming_txs)
return;
5636 if (
pto.IsBlockOnlyConn())
return;
5649 peer.m_next_send_feefilter = 0
us;
5671class CompareInvMempoolOrder
5675 explicit CompareInvMempoolOrder(
CTxMemPool* mempool) : m_mempool{mempool} {}
5677 bool operator()(std::set<Wtxid>::iterator
a, std::set<Wtxid>::iterator b)
5686bool PeerManagerImpl::RejectIncomingTxs(
const CNode& peer)
const
5696bool PeerManagerImpl::SetupAddressRelay(
const CNode&
node, Peer& peer)
5701 if (
node.IsBlockOnlyConn())
return false;
5703 if (!peer.m_addr_relay_enabled.exchange(
true)) {
5707 peer.m_addr_known = std::make_unique<CRollingBloomFilter>(5000, 0.001);
5713bool PeerManagerImpl::SendMessages(
CNode&
node)
5728 if (!
node.IsInboundConn() && !peer.m_outbound_version_message_sent) {
5730 peer.m_outbound_version_message_sent =
true;
5734 if (!
node.fSuccessfullyConnected ||
node.fDisconnect)
5742 if (
node.IsPrivateBroadcastConn()) {
5746 node.fDisconnect =
true;
5753 node.fDisconnect =
true;
5760 if (
node.fDisconnect)
return true;
5769 CNodeState &state = *
State(
node.GetId());
5772 if (m_chainman.m_best_header ==
nullptr) {
5780 if (state.fPreferredDownload) {
5813 state.fSyncStarted =
true;
5837 LOCK(peer.m_block_inv_mutex);
5840 (!state.m_requested_hb_cmpctblocks || peer.m_blocks_for_headers_relay.size() > 1)) ||
5893 if (
vHeaders.size() == 1 && state.m_requested_hb_cmpctblocks) {
5901 LOCK(m_most_recent_block_mutex);
5916 }
else if (peer.m_prefers_headers) {
5920 vHeaders.front().GetHash().ToString(),
5935 if (!peer.m_blocks_for_headers_relay.empty()) {
5956 peer.m_blocks_for_headers_relay.clear();
5962 std::vector<CInv>
vInv;
5964 LOCK(peer.m_block_inv_mutex);
5975 peer.m_blocks_for_inv_relay.clear();
5984 if (
node.IsInboundConn()) {
6008 const auto inv = peer.m_wtxid_relay ?
6018 if (!
tx_relay->m_bloom_filter->IsRelevantAndUpdate(*
txinfo.tx))
continue;
6020 tx_relay->m_tx_inventory_known_filter.insert(inv.
hash);
6021 vInv.push_back(inv);
6032 std::vector<std::set<Wtxid>::iterator>
vInvTx;
6034 for (std::set<Wtxid>::iterator it =
tx_relay->m_tx_inventory_to_send.begin(); it !=
tx_relay->m_tx_inventory_to_send.end(); it++) {
6051 std::set<Wtxid>::iterator it =
vInvTx.back();
6055 tx_relay->m_tx_inventory_to_send.erase(it);
6064 const auto inv = peer.m_wtxid_relay ?
6068 if (
tx_relay->m_tx_inventory_known_filter.contains(inv.
hash)) {
6077 vInv.push_back(inv);
6083 tx_relay->m_tx_inventory_known_filter.insert(inv.
hash);
6101 node.fDisconnect =
true;
6115 if (state.vBlocksInFlight.size() > 0) {
6116 QueuedBlock &
queuedBlock = state.vBlocksInFlight.front();
6120 node.fDisconnect =
true;
6125 if (state.fSyncStarted && peer.m_headers_sync_timeout < std::chrono::microseconds::max()) {
6127 if (m_chainman.m_best_header->Time() <=
NodeClock::now() - 24h) {
6136 node.fDisconnect =
true;
6139 LogInfo(
"Timeout downloading headers from noban peer, not %s\n",
node.DisconnectMsg(
fLogIPs));
6145 state.fSyncStarted =
false;
6147 peer.m_headers_sync_timeout = 0
us;
6153 peer.m_headers_sync_timeout = std::chrono::microseconds::max();
6193 if (state.vBlocksInFlight.empty() &&
staller != -1) {
6205 LOCK(m_tx_download_mutex);
static 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.
static 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.
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
CBlockIndex * Next(const CBlockIndex *pindex) 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.
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this 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...
void ForEachNode(const NodeFn &func)
bool ForNode(NodeId id, std::function< bool(CNode *pnode)> func)
bool GetNetworkActive() const
bool ShouldRunInactivityChecks(const CNode &node, std::chrono::microseconds now) const
Return true if we should disconnect the peer for failing an inactivity check.
bool GetTryNewOutboundPeer() const
class CConnman::PrivateBroadcast m_private_broadcast
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)
int GetExtraBlockRelayCount() const
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()
bool DisconnectNode(std::string_view node)
CSipHasher GetDeterministicRandomizer(uint64_t id) const
Get a unique deterministic randomizer.
uint32_t GetMappedAS(const CNetAddr &addr) const
int GetExtraFullOutboundCount() const
std::vector< CAddress > GetAddressesUnsafe(size_t max_addresses, size_t max_pct, std::optional< Network > network, bool filtered=true) const
Return randomly selected addresses.
bool CheckIncomingNonce(uint64_t nonce)
bool GetUseAddrmanOutgoing() const
RecursiveMutex & GetNodesMutex() const LOCK_RETURNED(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 ...
bool CompareMiningScoreWithTopology(const Wtxid &hasha, const Wtxid &hashb) const
TxMempoolInfo info_for_relay(const T &id, uint64_t last_sequence) const
Returns info for a transaction if its entry_sequence < last_sequence.
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
CFeeRate GetMinFee(size_t sizelimit) const
CTransactionRef get(const Txid &hash) const
size_t DynamicMemoryUsage() const
std::vector< TxMempoolInfo > infoAll() const
TxMempoolInfo info(const T &id) const
bool exists(const Txid &txid) const
uint64_t GetSequence() const EXCLUSIVE_LOCKS_REQUIRED(cs)
std::set< Txid > GetUnbroadcastTxs() const
Returns transactions in unbroadcast set.
unsigned long size() const
void RemoveUnbroadcastTx(const Txid &txid, bool unchecked=false)
Removes a transaction from the unbroadcast set.
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...
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 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...
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.
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)
static std::unique_ptr< PeerManager > make(CConnman &connman, AddrMan &addrman, BanMan *banman, ChainstateManager &chainman, CTxMemPool &pool, node::Warnings &warnings, Options opts)
Store a list of transactions to be broadcast privately.
void NodeConfirmedReception(const NodeId &nodeid) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Mark that the node has confirmed reception of the transaction we sent it by responding with PONG to o...
std::vector< TxBroadcastInfo > GetBroadcastInfo() const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Get stats about all transactions currently being privately broadcast.
bool HavePendingTransactions() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Check if there are transactions that need to be broadcast.
bool DidNodeConfirmReception(const NodeId &nodeid) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Check if the node has confirmed reception of the transaction.
std::optional< size_t > Remove(const CTransactionRef &tx) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Forget a transaction.
std::optional< CTransactionRef > PickTxForSend(const NodeId &will_send_to_nodeid, const CService &will_send_to_address) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Pick the transaction with the fewest send attempts, and confirmations, and oldest send/confirm times.
std::optional< CTransactionRef > GetTxForNode(const NodeId &nodeid) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Get the transaction that was picked for sending to a given node by PickTxForSend().
bool Add(const CTransactionRef &tx) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Add a transaction to the storage.
std::vector< CTransactionRef > GetStale() const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Get the transactions that have not been broadcast recently.
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)
void Add(std::chrono::seconds offset) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Add a new time offset sample.
bool WarnIfOutOfSync() const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Raise warnings if the median time offset exceeds the warnings threshold.
std::chrono::seconds Median() const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Compute and return the median of the collected time offset samples.
std::string GetDebugMessage() const
std::string ToString() const
256-bit unsigned big integer.
constexpr bool IsNull() const
std::string ToString() const
CBlockIndex * LookupBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
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.
bool IsPruneMode() const
Whether running in -prune mode.
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...
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 LogDebug(category,...)
static bool LogAcceptCategory(BCLog::LogFlags category, BCLog::Level level)
Return true if log accepts specified category, at the specified level.
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 * 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...
static 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...
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
static const unsigned int MAX_SUBVERSION_LENGTH
Maximum length of the user agent string in version message.
static 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 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 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 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 uint64_t CMPCTBLOCKS_VERSION
The compactblocks version we support.
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 size_t NUM_PRIVATE_BROADCAST_PER_TX
For private broadcast, send a transaction to this many 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 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 unsigned int INVENTORY_BROADCAST_TARGET
Target number of tx inventory items to send per transmission.
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 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 unsigned int INVENTORY_BROADCAST_MAX
Maximum number of inventory items to send per transmission.
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 const unsigned int MAX_INV_SZ
The maximum number of entries in an 'inv' protocol message.
static constexpr unsigned int INVENTORY_BROADCAST_PER_SECOND
Maximum rate of inventory items to send per second.
static const unsigned int MAX_CMPCTBLOCKS_INFLIGHT_PER_BLOCK
Maximum number of outstanding CMPCTBLOCK requests for the same block.
ReachableNets g_reachable_nets
bool IsProxy(const CNetAddr &addr)
static constexpr unsigned int DEFAULT_MIN_RELAY_TX_FEE
Default for -minrelaytxfee, minimum relay fee for transactions.
static constexpr TransactionSerParams TX_NO_WITNESS
static 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.
const 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
static bool MayHaveUsefulAddressDB(ServiceFlags services)
Checks if a peer with the given service flags may be capable of having a robust address-storage DB.
static const int WTXID_RELAY_VERSION
"wtxidrelay" message type for wtxid-based relay starts with this version
static const int SHORT_IDS_BLOCKS_VERSION
short-id-based block download starts with this version
static const int SENDHEADERS_VERSION
"sendheaders" message type and announcing blocks with headers starts with this version
static const int PROTOCOL_VERSION
network protocol versioning
static const int FEEFILTER_VERSION
"feefilter" tells peers to filter invs to you by fee starts with this version
static const int MIN_PEER_PROTO_VERSION
disconnect from peers older than this proto version
static const int INVALID_CB_NO_BAN_VERSION
not banning for invalid compact blocks starts with this version
static const int BIP0031_VERSION
BIP 0031, pong message, is enabled for all versions AFTER this one.
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
#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
std::chrono::microseconds 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.
static time_point now() noexcept
Return current system time or mocked time, if set.
std::chrono::time_point< NodeClock > time_point
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
static constexpr uint32_t TXRECONCILIATION_VERSION
Supported transaction reconciliation protocol version.
std::string SanitizeString(std::string_view str, int rule)
Remove unsafe chars.
int64_t GetTime()
DEPRECATED Use either ClockType::now() or Now<TimePointType>() if a cast is needed.
constexpr int64_t count_microseconds(std::chrono::microseconds t)
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.
static const unsigned int MIN_BLOCKS_TO_KEEP
Block files containing a block-height within MIN_BLOCKS_TO_KEEP of ActiveChain().Tip() will not be pr...
@ UNVALIDATED
Blocks after an assumeutxo snapshot have been validated but the snapshot itself has not been validate...