v30.3-roots.1 · Commit 3: [PATCH 03/68] feat(policy): preserve Roots relay and network controls on Core 30.3
src/net_processing.cpp
Before: src/net_processing.cpp · After: src/net_processing.cpp
File metadata
index 9287a67a04eaffee5838a1a9198414d950a28c89..b1dcbf122e0ab69b292923fca2123116abe2a758 100644
Download original patch · Release notes
Diff rows 1–400 of 407. Line numbers refer to the original before/after files.
+ Added− RemovedUnmarked lines are context.
Scroll the code area horizontally to read long lines. Before is on the left; after is on the right. Unified view fits narrow screens more easily.
src/net_processing.cpp
CHANGED
|
@@ -13,6 +13,7 @@
|
|
| 13 |
#include <chain.h>
|
| 14 |
#include <chainparams.h>
|
| 15 |
#include <common/bloom.h>
|
|
|
|
| 16 |
#include <consensus/amount.h>
|
| 17 |
#include <consensus/params.h>
|
| 18 |
#include <consensus/validation.h>
|
|
@@ -530,7 +531,7 @@ public:
|
|
| 530 |
/** Implement PeerManager */
|
| 531 |
void StartScheduledTasks(CScheduler& scheduler) override;
|
| 532 |
void CheckForStaleTipAndEvictPeers() override;
|
| 533 |
-
std::optional<std::string> FetchBlock(NodeId peer_id, const CBlockIndex& block_index) override
|
| 534 |
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
|
| 535 |
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) const override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
|
| 536 |
std::vector<node::TxOrphanage::OrphanInfo> GetOrphanTransactions() override EXCLUSIVE_LOCKS_REQUIRED(!m_tx_download_mutex);
|
|
@@ -807,7 +808,7 @@ private:
|
|
| 807 |
|
| 808 |
uint32_t GetFetchFlags(const Peer& peer) const;
|
| 809 |
|
| 810 |
-
std::atomic<std::chrono::microseconds> m_next_inv_to_inbounds{0us};
|
| 811 |
|
| 812 |
/** Number of nodes with fSyncStarted. */
|
| 813 |
int nSyncStarted GUARDED_BY(cs_main) = 0;
|
|
@@ -837,12 +838,14 @@ private:
|
|
| 837 |
|
| 838 |
/**
|
| 839 |
* For sending `inv`s to inbound peers, we use a single (exponentially
|
| 840 |
-
* distributed) timer for all peers. If we used a separate timer for each
|
| 841 |
* peer, a spy node could make multiple inbound connections to us to
|
| 842 |
-
* accurately determine when we received the transaction (and potentially
|
| 843 |
-
* determine the transaction's origin). */
|
|
|
|
| 844 |
std::chrono::microseconds NextInvToInbounds(std::chrono::microseconds now,
|
| 845 |
-
std::chrono::seconds average_interval) EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);
|
|
|
|
| 846 |
|
| 847 |
|
| 848 |
// All of the following cache a recent block, and are protected by m_most_recent_block_mutex
|
|
@@ -879,6 +882,9 @@ private:
|
|
| 879 |
/** Have we requested this block from an outbound peer */
|
| 880 |
bool IsBlockRequestedFromOutbound(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main, !m_peer_mutex);
|
| 881 |
|
|
|
|
|
|
|
|
|
|
| 882 |
/** Remove this block from our tracked requested blocks. Called if:
|
| 883 |
* - the block has been received from a peer
|
| 884 |
* - the request for the block has timed out
|
|
@@ -969,7 +975,7 @@ private:
|
|
| 969 |
/** Number of peers from which we're downloading blocks. */
|
| 970 |
int m_peers_downloading_from GUARDED_BY(cs_main) = 0;
|
| 971 |
|
| 972 |
-
void AddToCompactExtraTransactions(const CTransactionRef& tx) EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);
|
| 973 |
|
| 974 |
/** Orphan/conflicted/etc transactions that are kept for compact block reconstruction.
|
| 975 |
* The last -blockreconstructionextratxn/DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN of
|
|
@@ -977,6 +983,7 @@ private:
|
|
| 977 |
std::vector<std::pair<Wtxid, CTransactionRef>> vExtraTxnForCompact GUARDED_BY(g_msgproc_mutex);
|
| 978 |
/** Offset into vExtraTxnForCompact to insert the next tx */
|
| 979 |
size_t vExtraTxnForCompactIt GUARDED_BY(g_msgproc_mutex) = 0;
|
|
|
|
| 980 |
|
| 981 |
/** Check whether the last unknown block a peer advertised is not yet known. */
|
| 982 |
void ProcessBlockAvailability(NodeId nodeid) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
|
@@ -1143,15 +1150,15 @@ static bool CanServeWitnesses(const Peer& peer)
|
|
| 1143 |
}
|
| 1144 |
|
| 1145 |
std::chrono::microseconds PeerManagerImpl::NextInvToInbounds(std::chrono::microseconds now,
|
| 1146 |
-
std::chrono::seconds average_interval)
|
|
|
|
| 1147 |
{
|
| 1148 |
-
if (m_next_inv_to_inbounds.load() < now) {
|
| 1149 |
-
// If this function were called from multiple threads simultaneously
|
| 1150 |
-
// it would possible that both update the next send variable, and return a different result to their caller.
|
| 1151 |
-
// This is not possible in practice as only the net processing thread invokes this function.
|
| 1152 |
-
m_next_inv_to_inbounds = now + m_rng.rand_exp_duration(average_interval);
|
| 1153 |
}
|
| 1154 |
-
return m_next_inv_to_inbounds;
|
| 1155 |
}
|
| 1156 |
|
| 1157 |
bool PeerManagerImpl::IsBlockRequested(const uint256& hash)
|
|
@@ -1170,6 +1177,16 @@ bool PeerManagerImpl::IsBlockRequestedFromOutbound(const uint256& hash)
|
|
| 1170 |
return false;
|
| 1171 |
}
|
| 1172 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1173 |
void PeerManagerImpl::RemoveBlockRequest(const uint256& hash, std::optional<NodeId> from_peer)
|
| 1174 |
{
|
| 1175 |
auto range = mapBlocksInFlight.equal_range(hash);
|
|
@@ -1561,6 +1578,9 @@ void PeerManagerImpl::InitializeNode(const CNode& node, ServiceFlags our_service
|
|
| 1561 |
if (NetPermissions::HasFlag(node.m_permission_flags, NetPermissionFlags::BloomFilter)) {
|
| 1562 |
our_services = static_cast<ServiceFlags>(our_services | NODE_BLOOM);
|
| 1563 |
}
|
|
|
|
|
|
|
|
|
|
| 1564 |
|
| 1565 |
PeerRef peer = std::make_shared<Peer>(nodeid, our_services, node.IsInboundConn());
|
| 1566 |
{
|
|
@@ -1708,6 +1728,7 @@ bool PeerManagerImpl::GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) c
|
|
| 1708 |
if (queue.pindex)
|
| 1709 |
stats.vHeightInFlight.push_back(queue.pindex->nHeight);
|
| 1710 |
}
|
|
|
|
| 1711 |
}
|
| 1712 |
|
| 1713 |
PeerRef peer = GetPeerRef(nodeid);
|
|
@@ -1744,6 +1765,7 @@ bool PeerManagerImpl::GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) c
|
|
| 1744 |
}
|
| 1745 |
}
|
| 1746 |
stats.time_offset = peer->m_time_offset;
|
|
|
|
| 1747 |
|
| 1748 |
return true;
|
| 1749 |
}
|
|
@@ -1762,14 +1784,26 @@ PeerManagerInfo PeerManagerImpl::GetInfo() const
|
|
| 1762 |
};
|
| 1763 |
}
|
| 1764 |
|
| 1765 |
-
void PeerManagerImpl::AddToCompactExtraTransactions(const CTransactionRef& tx)
|
| 1766 |
{
|
| 1767 |
if (m_opts.max_extra_txs <= 0)
|
| 1768 |
return;
|
| 1769 |
if (!vExtraTxnForCompact.size())
|
| 1770 |
vExtraTxnForCompact.resize(m_opts.max_extra_txs);
|
| 1771 |
-
vExtraTxnForCompact[vExtraTxnForCompactIt] = std::make_pair(tx->GetWitnessHash(), tx);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1772 |
vExtraTxnForCompactIt = (vExtraTxnForCompactIt + 1) % m_opts.max_extra_txs;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1773 |
}
|
| 1774 |
|
| 1775 |
void PeerManagerImpl::Misbehaving(Peer& peer, const std::string& message)
|
|
@@ -1785,10 +1819,23 @@ void PeerManagerImpl::Misbehaving(Peer& peer, const std::string& message)
|
|
| 1785 |
);
|
| 1786 |
}
|
| 1787 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1788 |
void PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidationState& state,
|
| 1789 |
bool via_compact_block, const std::string& message)
|
| 1790 |
{
|
| 1791 |
-
PeerRef peer{GetPeerRef(nodeid)};
|
| 1792 |
switch (state.GetResult()) {
|
| 1793 |
case BlockValidationResult::BLOCK_RESULT_UNSET:
|
| 1794 |
break;
|
|
@@ -1800,7 +1847,7 @@ void PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidati
|
|
| 1800 |
case BlockValidationResult::BLOCK_CONSENSUS:
|
| 1801 |
case BlockValidationResult::BLOCK_MUTATED:
|
| 1802 |
if (!via_compact_block) {
|
| 1803 |
-
if (peer) Misbehaving(*peer, message);
|
| 1804 |
return;
|
| 1805 |
}
|
| 1806 |
break;
|
|
@@ -1808,19 +1855,19 @@ void PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidati
|
|
| 1808 |
{
|
| 1809 |
// Discourage outbound (but not inbound) peers if on an invalid chain.
|
| 1810 |
// Exempt HB compact block peers. Manual connections are always protected from discouragement.
|
| 1811 |
-
if (peer && !via_compact_block && !peer->m_is_inbound) {
|
| 1812 |
-
if (peer) Misbehaving(*peer, message);
|
| 1813 |
return;
|
| 1814 |
}
|
| 1815 |
break;
|
| 1816 |
}
|
| 1817 |
case BlockValidationResult::BLOCK_INVALID_HEADER:
|
| 1818 |
case BlockValidationResult::BLOCK_INVALID_PREV:
|
| 1819 |
-
if (peer) Misbehaving(*peer, message);
|
| 1820 |
return;
|
| 1821 |
// Conflicting (but not necessarily invalid) data or different policy:
|
| 1822 |
case BlockValidationResult::BLOCK_MISSING_PREV:
|
| 1823 |
-
if (peer) Misbehaving(*peer, message);
|
| 1824 |
return;
|
| 1825 |
case BlockValidationResult::BLOCK_TIME_FUTURE:
|
| 1826 |
break;
|
|
@@ -1839,7 +1886,7 @@ bool PeerManagerImpl::BlockRequestAllowed(const CBlockIndex* pindex)
|
|
| 1839 |
(GetBlockProofEquivalentTime(*m_chainman.m_best_header, *pindex, *m_chainman.m_best_header, m_chainparams.GetConsensus()) < STALE_RELAY_AGE_LIMIT);
|
| 1840 |
}
|
| 1841 |
|
| 1842 |
-
std::optional<std::string> PeerManagerImpl::FetchBlock(NodeId peer_id, const CBlockIndex& block_index)
|
| 1843 |
{
|
| 1844 |
if (m_chainman.m_blockman.LoadingBlocks()) return "Loading blocks ...";
|
| 1845 |
|
|
@@ -1852,14 +1899,18 @@ std::optional<std::string> PeerManagerImpl::FetchBlock(NodeId peer_id, const CBl
|
|
| 1852 |
|
| 1853 |
LOCK(cs_main);
|
| 1854 |
|
| 1855 |
-
// Forget about all prior requests
|
| 1856 |
-
RemoveBlockRequest(block_index.GetBlockHash(), std::nullopt);
|
| 1857 |
|
| 1858 |
-
// Mark block as in-flight
|
| 1859 |
-
if (!BlockRequested(peer_id, block_index)) return "Already requested from this peer";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1860 |
|
| 1861 |
// Construct message to request the block
|
| 1862 |
-
const uint256& hash{block_index.GetBlockHash()};
|
| 1863 |
std::vector<CInv> invs{CInv(MSG_BLOCK | MSG_WITNESS_FLAG, hash)};
|
| 1864 |
|
| 1865 |
// Send block request message to the peer
|
|
@@ -1875,6 +1926,12 @@ std::optional<std::string> PeerManagerImpl::FetchBlock(NodeId peer_id, const CBl
|
|
| 1875 |
return std::nullopt;
|
| 1876 |
}
|
| 1877 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1878 |
std::unique_ptr<PeerManager> PeerManager::make(CConnman& connman, AddrMan& addrman,
|
| 1879 |
BanMan* banman, ChainstateManager& chainman,
|
| 1880 |
CTxMemPool& pool, node::Warnings& warnings, Options opts)
|
|
@@ -1882,11 +1939,12 @@ std::unique_ptr<PeerManager> PeerManager::make(CConnman& connman, AddrMan& addrm
|
|
| 1882 |
return std::make_unique<PeerManagerImpl>(connman, addrman, banman, chainman, pool, warnings, opts);
|
| 1883 |
}
|
| 1884 |
|
|
|
|
| 1885 |
PeerManagerImpl::PeerManagerImpl(CConnman& connman, AddrMan& addrman,
|
| 1886 |
BanMan* banman, ChainstateManager& chainman,
|
| 1887 |
CTxMemPool& pool, node::Warnings& warnings, Options opts)
|
| 1888 |
: m_rng{opts.deterministic_rng},
|
| 1889 |
-
m_fee_filter_rounder{CFeeRate{DEFAULT_MIN_RELAY_TX_FEE}, m_rng},
|
| 1890 |
m_chainparams(chainman.GetParams()),
|
| 1891 |
m_connman(connman),
|
| 1892 |
m_addrman(addrman),
|
|
@@ -2239,7 +2297,7 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
|
|
| 2239 |
}
|
| 2240 |
// disconnect node in case we have reached the outbound limit for serving historical blocks
|
| 2241 |
if (m_connman.OutboundTargetReached(true) &&
|
| 2242 |
-
(((m_chainman.m_best_header != nullptr) && (m_chainman.m_best_header->GetBlockTime() - pindex->GetBlockTime() > HISTORICAL_BLOCK_AGE)) || inv.IsMsgFilteredBlk()) &&
|
| 2243 |
!pfrom.HasPermission(NetPermissionFlags::Download) // nodes with the download permission may exceed target
|
| 2244 |
) {
|
| 2245 |
LogDebug(BCLog::NET, "historical block serving limit reached, %s\n", pfrom.DisconnectMsg(fLogIPs));
|
|
@@ -2302,7 +2360,7 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
|
|
| 2302 |
MakeAndPushMessage(pfrom, NetMsgType::BLOCK, TX_NO_WITNESS(*pblock));
|
| 2303 |
} else if (inv.IsMsgWitnessBlk()) {
|
| 2304 |
MakeAndPushMessage(pfrom, NetMsgType::BLOCK, TX_WITH_WITNESS(*pblock));
|
| 2305 |
-
} else if (inv.IsMsgFilteredBlk()) {
|
| 2306 |
bool sendMerkleBlock = false;
|
| 2307 |
CMerkleBlock merkleBlock;
|
| 2308 |
if (auto tx_relay = peer.GetTxRelay(); tx_relay != nullptr) {
|
|
@@ -2320,8 +2378,9 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
|
|
| 2320 |
// they must either disconnect and retry or request the full block.
|
| 2321 |
// Thus, the protocol spec specified allows for us to provide duplicate txn here,
|
| 2322 |
// however we MUST always provide at least what the remote peer needs
|
|
|
|
| 2323 |
for (const auto& [tx_idx, _] : merkleBlock.vMatchedTxn)
|
| 2324 |
-
MakeAndPushMessage(pfrom, NetMsgType::TX, TX_NO_WITNESS(*pblock->vtx[tx_idx]));
|
| 2325 |
}
|
| 2326 |
// else
|
| 2327 |
// no response
|
|
@@ -2531,6 +2590,10 @@ void PeerManagerImpl::HandleUnconnectingHeaders(CNode& pfrom, Peer& peer,
|
|
| 2531 |
// eventually get the headers - even from a different peer -
|
| 2532 |
// we can use this peer to download.
|
| 2533 |
WITH_LOCK(cs_main, UpdateBlockAvailability(pfrom.GetId(), headers.back().GetHash()));
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2534 |
}
|
| 2535 |
|
| 2536 |
bool PeerManagerImpl::CheckHeadersAreContinuous(const std::vector<CBlockHeader>& headers) const
|
|
@@ -2994,8 +3057,9 @@ std::optional<node::PackageToValidate> PeerManagerImpl::ProcessInvalidTx(NodeId
|
|
| 2994 |
|
| 2995 |
const auto& [add_extra_compact_tx, unique_parents, package_to_validate] = m_txdownloadman.MempoolRejectedTx(ptx, state, nodeid, first_time_failure);
|
| 2996 |
|
| 2997 |
-
if (add_extra_compact_tx && RecursiveDynamicUsage(*ptx) < 100000) {
|
| 2998 |
-
AddToCompactExtraTransactions(ptx);
|
|
|
|
| 2999 |
}
|
| 3000 |
for (const Txid& parent_txid : unique_parents) {
|
| 3001 |
if (peer) AddKnownTx(*peer, parent_txid.ToUint256());
|
|
@@ -3021,7 +3085,8 @@ void PeerManagerImpl::ProcessValidTx(NodeId nodeid, const CTransactionRef& tx, c
|
|
| 3021 |
RelayTransaction(tx->GetHash(), tx->GetWitnessHash());
|
| 3022 |
|
| 3023 |
for (const CTransactionRef& removedTx : replaced_transactions) {
|
| 3024 |
-
AddToCompactExtraTransactions(removedTx);
|
|
|
|
| 3025 |
}
|
| 3026 |
}
|
| 3027 |
|
|
@@ -3479,7 +3544,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
|
| 3479 |
if (!vRecv.empty()) {
|
| 3480 |
std::string strSubVer;
|
| 3481 |
vRecv >> LIMITED_STRING(strSubVer, MAX_SUBVERSION_LENGTH);
|
| 3482 |
-
cleanSubVer = SanitizeString(strSubVer);
|
| 3483 |
}
|
| 3484 |
if (!vRecv.empty()) {
|
| 3485 |
vRecv >> starting_height;
|
|
@@ -3508,6 +3573,10 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
|
| 3508 |
// Change version
|
| 3509 |
const int greatest_common_version = std::min(nVersion, PROTOCOL_VERSION);
|
| 3510 |
pfrom.SetCommonVersion(greatest_common_version);
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3511 |
pfrom.nVersion = nVersion;
|
| 3512 |
|
| 3513 |
if (greatest_common_version >= WTXID_RELAY_VERSION) {
|
|
@@ -3526,10 +3595,6 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
|
| 3526 |
pfrom.m_has_all_wanted_services = HasAllDesirableServiceFlags(nServices);
|
| 3527 |
peer->m_their_services = nServices;
|
| 3528 |
pfrom.SetAddrLocal(addrMe);
|
| 3529 |
-
{
|
| 3530 |
-
LOCK(pfrom.m_subver_mutex);
|
| 3531 |
-
pfrom.cleanSubVer = cleanSubVer;
|
| 3532 |
-
}
|
| 3533 |
peer->m_starting_height = starting_height;
|
| 3534 |
|
| 3535 |
// Only initialize the Peer::TxRelay m_relay_txs data structure if:
|
|
@@ -3615,10 +3680,11 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
|
| 3615 |
}
|
| 3616 |
|
| 3617 |
const auto mapped_as{m_connman.GetMappedAS(pfrom.addr)};
|
| 3618 |
-
LogDebug(BCLog::NET, "receive version message: %s: version %d, blocks=%d, us=%s, txrelay=%d, peer=%d%s%s\n",
|
| 3619 |
-
cleanSubVer, pfrom.nVersion,
|
| 3620 |
peer->m_starting_height, addrMe.ToStringAddrPort(), fRelay, pfrom.GetId(),
|
| 3621 |
-
pfrom.LogIP(fLogIPs), (mapped_as ? strprintf(", mapped_as=%d", mapped_as) : ""));
|
|
|
|
| 3622 |
|
| 3623 |
peer->m_time_offset = NodeSeconds{std::chrono::seconds{nTime}} - Now<NodeSeconds>();
|
| 3624 |
if (!pfrom.IsInboundConn()) {
|
|
@@ -3658,11 +3724,12 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
|
| 3658 |
// can be triggered by an attacker at high rate.
|
| 3659 |
if (!pfrom.IsInboundConn() || LogAcceptCategory(BCLog::NET, BCLog::Level::Debug)) {
|
| 3660 |
const auto mapped_as{m_connman.GetMappedAS(pfrom.addr)};
|
| 3661 |
-
LogPrintf("New %s %s peer connected: version: %d, blocks=%d, peer=%d%s%s\n",
|
| 3662 |
pfrom.ConnectionTypeAsString(),
|
| 3663 |
TransportTypeAsString(pfrom.m_transport->GetInfo().transport_type),
|
| 3664 |
pfrom.nVersion.load(), peer->m_starting_height,
|
| 3665 |
-
pfrom.GetId(), pfrom.LogIP(fLogIPs),
|
|
|
|
| 3666 |
(mapped_as ? strprintf(", mapped_as=%d", mapped_as) : ""));
|
| 3667 |
}
|
| 3668 |
|
|
@@ -4939,13 +5006,13 @@ bool PeerManagerImpl::MaybeDiscourageAndDisconnect(CNode& pnode, Peer& peer)
|
|
| 4939 |
|
| 4940 |
if (pnode.HasPermission(NetPermissionFlags::NoBan)) {
|
| 4941 |
// We never disconnect or discourage peers for bad behavior if they have NetPermissionFlags::NoBan permission
|
| 4942 |
-
LogPrintf("Warning: not punishing noban peer %d!\n", peer.m_id);
|
| 4943 |
return false;
|
| 4944 |
}
|
| 4945 |
|
| 4946 |
if (pnode.IsManualConn()) {
|
| 4947 |
// We never disconnect or discourage manual peers for bad behavior
|
| 4948 |
-
LogPrintf("Warning: not punishing manually connected peer %d!\n", peer.m_id);
|
| 4949 |
return false;
|
| 4950 |
}
|
| 4951 |
|
|
@@ -5371,6 +5438,7 @@ void PeerManagerImpl::MaybeSendFeefilter(CNode& pto, Peer& peer, std::chrono::mi
|
|
| 5371 |
{
|
| 5372 |
if (m_opts.ignore_incoming_txs) return;
|
| 5373 |
if (pto.GetCommonVersion() < FEEFILTER_VERSION) return;
|
|
|
|
| 5374 |
// peers with the forcerelay permission should not filter txs to us
|
| 5375 |
if (pto.HasPermission(NetPermissionFlags::ForceRelay)) return;
|
| 5376 |
// Don't send feefilter messages to outbound block-relay-only peers since they should never announce
|
|
@@ -5711,7 +5779,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
|
| 5711 |
if (tx_relay->m_next_inv_send_time < current_time) {
|
|
|
|
| 13 |
#include <chain.h>
|
| 14 |
#include <chainparams.h>
|
| 15 |
#include <common/bloom.h>
|
| 16 |
+
#include <common/args.h>
|
| 17 |
#include <consensus/amount.h>
|
| 18 |
#include <consensus/params.h>
|
| 19 |
#include <consensus/validation.h>
|
|
|
|
| 531 |
/** Implement PeerManager */
|
| 532 |
void StartScheduledTasks(CScheduler& scheduler) override;
|
| 533 |
void CheckForStaleTipAndEvictPeers() override;
|
| 534 |
+
std::optional<std::string> FetchBlock(NodeId peer_id, const uint256& hash, const CBlockIndex* block_index) override
|
| 535 |
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
|
| 536 |
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) const override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
|
| 537 |
std::vector<node::TxOrphanage::OrphanInfo> GetOrphanTransactions() override EXCLUSIVE_LOCKS_REQUIRED(!m_tx_download_mutex);
|
|
|
|
| 808 |
|
| 809 |
uint32_t GetFetchFlags(const Peer& peer) const;
|
| 810 |
|
| 811 |
+
std::map<uint64_t, std::chrono::microseconds> m_next_inv_to_inbounds_per_network_key GUARDED_BY(g_msgproc_mutex);
|
| 812 |
|
| 813 |
/** Number of nodes with fSyncStarted. */
|
| 814 |
int nSyncStarted GUARDED_BY(cs_main) = 0;
|
|
|
|
| 838 |
|
| 839 |
/**
|
| 840 |
* For sending `inv`s to inbound peers, we use a single (exponentially
|
| 841 |
+
* distributed) timer for all peers with the same network key. If we used a separate timer for each
|
| 842 |
* peer, a spy node could make multiple inbound connections to us to
|
| 843 |
+
* accurately determine when we received a transaction (and potentially
|
| 844 |
+
* determine the transaction's origin). Each network key has its own timer
|
| 845 |
+
* to make fingerprinting harder. */
|
| 846 |
std::chrono::microseconds NextInvToInbounds(std::chrono::microseconds now,
|
| 847 |
+
std::chrono::seconds average_interval,
|
| 848 |
+
uint64_t network_key) EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);
|
| 849 |
|
| 850 |
|
| 851 |
// All of the following cache a recent block, and are protected by m_most_recent_block_mutex
|
|
|
|
| 882 |
/** Have we requested this block from an outbound peer */
|
| 883 |
bool IsBlockRequestedFromOutbound(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main, !m_peer_mutex);
|
| 884 |
|
| 885 |
+
/** Have we requested this block from a specific peer */
|
| 886 |
+
bool IsBlockRequestedFromPeer(const uint256& hash, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
| 887 |
+
|
| 888 |
/** Remove this block from our tracked requested blocks. Called if:
|
| 889 |
* - the block has been received from a peer
|
| 890 |
* - the request for the block has timed out
|
|
|
|
| 975 |
/** Number of peers from which we're downloading blocks. */
|
| 976 |
int m_peers_downloading_from GUARDED_BY(cs_main) = 0;
|
| 977 |
|
| 978 |
+
void AddToCompactExtraTransactions(const CTransactionRef& tx, size_t tx_dynamic_usage) EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);
|
| 979 |
|
| 980 |
/** Orphan/conflicted/etc transactions that are kept for compact block reconstruction.
|
| 981 |
* The last -blockreconstructionextratxn/DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN of
|
|
|
|
| 983 |
std::vector<std::pair<Wtxid, CTransactionRef>> vExtraTxnForCompact GUARDED_BY(g_msgproc_mutex);
|
| 984 |
/** Offset into vExtraTxnForCompact to insert the next tx */
|
| 985 |
size_t vExtraTxnForCompactIt GUARDED_BY(g_msgproc_mutex) = 0;
|
| 986 |
+
size_t blockreconstructionextratxn_memusage{0};
|
| 987 |
|
| 988 |
/** Check whether the last unknown block a peer advertised is not yet known. */
|
| 989 |
void ProcessBlockAvailability(NodeId nodeid) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
|
|
|
| 1150 |
}
|
| 1151 |
|
| 1152 |
std::chrono::microseconds PeerManagerImpl::NextInvToInbounds(std::chrono::microseconds now,
|
| 1153 |
+
std::chrono::seconds average_interval,
|
| 1154 |
+
uint64_t network_key)
|
| 1155 |
{
|
| 1156 |
+
auto [it, inserted] = m_next_inv_to_inbounds_per_network_key.try_emplace(network_key, 0us);
|
| 1157 |
+
auto& timer{it->second};
|
| 1158 |
+
if (timer < now) {
|
| 1159 |
+
timer = now + m_rng.rand_exp_duration(average_interval);
|
|
|
|
| 1160 |
}
|
| 1161 |
+
return timer;
|
| 1162 |
}
|
| 1163 |
|
| 1164 |
bool PeerManagerImpl::IsBlockRequested(const uint256& hash)
|
|
|
|
| 1177 |
return false;
|
| 1178 |
}
|
| 1179 |
|
| 1180 |
+
bool PeerManagerImpl::IsBlockRequestedFromPeer(const uint256& hash, NodeId peer)
|
| 1181 |
+
{
|
| 1182 |
+
for (auto range = mapBlocksInFlight.equal_range(hash); range.first != range.second; range.first++) {
|
| 1183 |
+
auto [nodeid, block_it] = range.first->second;
|
| 1184 |
+
if (nodeid == peer) return true;
|
| 1185 |
+
}
|
| 1186 |
+
|
| 1187 |
+
return false;
|
| 1188 |
+
}
|
| 1189 |
+
|
| 1190 |
void PeerManagerImpl::RemoveBlockRequest(const uint256& hash, std::optional<NodeId> from_peer)
|
| 1191 |
{
|
| 1192 |
auto range = mapBlocksInFlight.equal_range(hash);
|
|
|
|
| 1578 |
if (NetPermissions::HasFlag(node.m_permission_flags, NetPermissionFlags::BloomFilter)) {
|
| 1579 |
our_services = static_cast<ServiceFlags>(our_services | NODE_BLOOM);
|
| 1580 |
}
|
| 1581 |
+
if (NetPermissions::HasFlag(node.m_permission_flags, NetPermissionFlags::BlockFilters)) {
|
| 1582 |
+
our_services = static_cast<ServiceFlags>(our_services | NODE_COMPACT_FILTERS);
|
| 1583 |
+
}
|
| 1584 |
|
| 1585 |
PeerRef peer = std::make_shared<Peer>(nodeid, our_services, node.IsInboundConn());
|
| 1586 |
{
|
|
|
|
| 1728 |
if (queue.pindex)
|
| 1729 |
stats.vHeightInFlight.push_back(queue.pindex->nHeight);
|
| 1730 |
}
|
| 1731 |
+
stats.m_last_block_announcement = NodeSeconds{std::chrono::seconds{state->m_last_block_announcement}};
|
| 1732 |
}
|
| 1733 |
|
| 1734 |
PeerRef peer = GetPeerRef(nodeid);
|
|
|
|
| 1765 |
}
|
| 1766 |
}
|
| 1767 |
stats.time_offset = peer->m_time_offset;
|
| 1768 |
+
stats.m_misbehavior_score = WITH_LOCK(peer->m_misbehavior_mutex, return peer->m_should_discourage) ? 100 : 0;
|
| 1769 |
|
| 1770 |
return true;
|
| 1771 |
}
|
|
|
|
| 1784 |
};
|
| 1785 |
}
|
| 1786 |
|
| 1787 |
+
void PeerManagerImpl::AddToCompactExtraTransactions(const CTransactionRef& tx, const size_t tx_dynamic_usage)
|
| 1788 |
{
|
| 1789 |
if (m_opts.max_extra_txs <= 0)
|
| 1790 |
return;
|
| 1791 |
if (!vExtraTxnForCompact.size())
|
| 1792 |
vExtraTxnForCompact.resize(m_opts.max_extra_txs);
|
| 1793 |
+
{
|
| 1794 |
+
auto& entry = vExtraTxnForCompact[vExtraTxnForCompactIt];
|
| 1795 |
+
if (entry.second) blockreconstructionextratxn_memusage -= RecursiveDynamicUsage(*entry.second);
|
| 1796 |
+
entry = std::make_pair(tx->GetWitnessHash(), tx);
|
| 1797 |
+
blockreconstructionextratxn_memusage += tx_dynamic_usage;
|
| 1798 |
+
}
|
| 1799 |
vExtraTxnForCompactIt = (vExtraTxnForCompactIt + 1) % m_opts.max_extra_txs;
|
| 1800 |
+
|
| 1801 |
+
while (blockreconstructionextratxn_memusage > m_opts.max_extra_txs_size) {
|
| 1802 |
+
auto& entry = vExtraTxnForCompact[vExtraTxnForCompactIt];
|
| 1803 |
+
if (entry.second) blockreconstructionextratxn_memusage -= RecursiveDynamicUsage(*entry.second);
|
| 1804 |
+
entry = {};
|
| 1805 |
+
vExtraTxnForCompactIt = (vExtraTxnForCompactIt + 1) % m_opts.max_extra_txs;
|
| 1806 |
+
}
|
| 1807 |
}
|
| 1808 |
|
| 1809 |
void PeerManagerImpl::Misbehaving(Peer& peer, const std::string& message)
|
|
|
|
| 1819 |
);
|
| 1820 |
}
|
| 1821 |
|
| 1822 |
+
static void HandleDoSPunishment(CConnman& connman, NodeId node_id, const int nDoS, const char * const what_is_it) {
|
| 1823 |
+
// We never actually DoS ban for invalid blocks, merely disconnect nodes if we're relying on them as a primary node
|
| 1824 |
+
const std::string msg = strprintf("peer=%d got DoS score %d on invalid %s", node_id, nDoS, what_is_it);
|
| 1825 |
+
connman.ForNode(node_id, [msg](CNode* node) {
|
| 1826 |
+
if (node->PunishInvalidBlocks()) {
|
| 1827 |
+
LogDebug(BCLog::NET, "%s; simply disconnecting\n", msg);
|
| 1828 |
+
node->fDisconnect = true;
|
| 1829 |
+
} else {
|
| 1830 |
+
LogDebug(BCLog::NET, "%s; tolerating\n", msg);
|
| 1831 |
+
}
|
| 1832 |
+
return true;
|
| 1833 |
+
});
|
| 1834 |
+
}
|
| 1835 |
+
|
| 1836 |
void PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidationState& state,
|
| 1837 |
bool via_compact_block, const std::string& message)
|
| 1838 |
{
|
|
|
|
| 1839 |
switch (state.GetResult()) {
|
| 1840 |
case BlockValidationResult::BLOCK_RESULT_UNSET:
|
| 1841 |
break;
|
|
|
|
| 1847 |
case BlockValidationResult::BLOCK_CONSENSUS:
|
| 1848 |
case BlockValidationResult::BLOCK_MUTATED:
|
| 1849 |
if (!via_compact_block) {
|
| 1850 |
+
HandleDoSPunishment(m_connman, nodeid, 100, "block");
|
| 1851 |
return;
|
| 1852 |
}
|
| 1853 |
break;
|
|
|
|
| 1855 |
{
|
| 1856 |
// Discourage outbound (but not inbound) peers if on an invalid chain.
|
| 1857 |
// Exempt HB compact block peers. Manual connections are always protected from discouragement.
|
| 1858 |
+
if (!via_compact_block) {
|
| 1859 |
+
HandleDoSPunishment(m_connman, nodeid, 100, "block");
|
| 1860 |
return;
|
| 1861 |
}
|
| 1862 |
break;
|
| 1863 |
}
|
| 1864 |
case BlockValidationResult::BLOCK_INVALID_HEADER:
|
| 1865 |
case BlockValidationResult::BLOCK_INVALID_PREV:
|
| 1866 |
+
HandleDoSPunishment(m_connman, nodeid, 100, "block header");
|
| 1867 |
return;
|
| 1868 |
// Conflicting (but not necessarily invalid) data or different policy:
|
| 1869 |
case BlockValidationResult::BLOCK_MISSING_PREV:
|
| 1870 |
+
HandleDoSPunishment(m_connman, nodeid, 100, "block header");
|
| 1871 |
return;
|
| 1872 |
case BlockValidationResult::BLOCK_TIME_FUTURE:
|
| 1873 |
break;
|
|
|
|
| 1886 |
(GetBlockProofEquivalentTime(*m_chainman.m_best_header, *pindex, *m_chainman.m_best_header, m_chainparams.GetConsensus()) < STALE_RELAY_AGE_LIMIT);
|
| 1887 |
}
|
| 1888 |
|
| 1889 |
+
std::optional<std::string> PeerManagerImpl::FetchBlock(NodeId peer_id, const uint256& hash, const CBlockIndex* block_index)
|
| 1890 |
{
|
| 1891 |
if (m_chainman.m_blockman.LoadingBlocks()) return "Loading blocks ...";
|
| 1892 |
|
|
|
|
| 1899 |
|
| 1900 |
LOCK(cs_main);
|
| 1901 |
|
| 1902 |
+
if (IsBlockRequestedFromPeer(hash, peer_id)) return "Already requested from this peer";
|
|
|
|
| 1903 |
|
| 1904 |
+
// Mark block as in-flight unless we don't have the header.
|
| 1905 |
+
if (block_index != nullptr) {
|
| 1906 |
+
// Forget about all prior requests
|
| 1907 |
+
RemoveBlockRequest(hash, std::nullopt);
|
| 1908 |
+
|
| 1909 |
+
// Mark block as in-flight
|
| 1910 |
+
Assume(BlockRequested(peer_id, *block_index));
|
| 1911 |
+
}
|
| 1912 |
|
| 1913 |
// Construct message to request the block
|
|
|
|
| 1914 |
std::vector<CInv> invs{CInv(MSG_BLOCK | MSG_WITNESS_FLAG, hash)};
|
| 1915 |
|
| 1916 |
// Send block request message to the peer
|
|
|
|
| 1926 |
return std::nullopt;
|
| 1927 |
}
|
| 1928 |
|
| 1929 |
+
std::optional<std::string> PeerManager::FetchBlock(NodeId peer_id, const CBlockIndex& block_index)
|
| 1930 |
+
{
|
| 1931 |
+
const uint256& hash{block_index.GetBlockHash()};
|
| 1932 |
+
return FetchBlock(peer_id, hash, &block_index);
|
| 1933 |
+
}
|
| 1934 |
+
|
| 1935 |
std::unique_ptr<PeerManager> PeerManager::make(CConnman& connman, AddrMan& addrman,
|
| 1936 |
BanMan* banman, ChainstateManager& chainman,
|
| 1937 |
CTxMemPool& pool, node::Warnings& warnings, Options opts)
|
|
|
|
| 1939 |
return std::make_unique<PeerManagerImpl>(connman, addrman, banman, chainman, pool, warnings, opts);
|
| 1940 |
}
|
| 1941 |
|
| 1942 |
+
static_assert(CORE_INCREMENTAL_RELAY_FEE < DEFAULT_INCREMENTAL_RELAY_FEE, "Trinary logic for m_fee_filter_rounder is based on assumption that CORE_INCREMENTAL_RELAY_FEE is less than DEFAULT_INCREMENTAL_RELAY_FEE");
|
| 1943 |
PeerManagerImpl::PeerManagerImpl(CConnman& connman, AddrMan& addrman,
|
| 1944 |
BanMan* banman, ChainstateManager& chainman,
|
| 1945 |
CTxMemPool& pool, node::Warnings& warnings, Options opts)
|
| 1946 |
: m_rng{opts.deterministic_rng},
|
| 1947 |
+
m_fee_filter_rounder{CFeeRate{pool.m_opts.incremental_relay_feerate.GetFeePerK() < DEFAULT_INCREMENTAL_RELAY_FEE ? CORE_INCREMENTAL_RELAY_FEE : DEFAULT_INCREMENTAL_RELAY_FEE}, m_rng},
|
| 1948 |
m_chainparams(chainman.GetParams()),
|
| 1949 |
m_connman(connman),
|
| 1950 |
m_addrman(addrman),
|
|
|
|
| 2297 |
}
|
| 2298 |
// disconnect node in case we have reached the outbound limit for serving historical blocks
|
| 2299 |
if (m_connman.OutboundTargetReached(true) &&
|
| 2300 |
+
(((m_chainman.m_best_header != nullptr) && (m_chainman.m_best_header->GetBlockTime() - pindex->GetBlockTime() > HISTORICAL_BLOCK_AGE)) || inv.IsMsgFilteredBlk() || inv.IsMsgFilteredWitnessBlk()) &&
|
| 2301 |
!pfrom.HasPermission(NetPermissionFlags::Download) // nodes with the download permission may exceed target
|
| 2302 |
) {
|
| 2303 |
LogDebug(BCLog::NET, "historical block serving limit reached, %s\n", pfrom.DisconnectMsg(fLogIPs));
|
|
|
|
| 2360 |
MakeAndPushMessage(pfrom, NetMsgType::BLOCK, TX_NO_WITNESS(*pblock));
|
| 2361 |
} else if (inv.IsMsgWitnessBlk()) {
|
| 2362 |
MakeAndPushMessage(pfrom, NetMsgType::BLOCK, TX_WITH_WITNESS(*pblock));
|
| 2363 |
+
} else if (inv.IsMsgFilteredBlk() || inv.IsMsgFilteredWitnessBlk()) {
|
| 2364 |
bool sendMerkleBlock = false;
|
| 2365 |
CMerkleBlock merkleBlock;
|
| 2366 |
if (auto tx_relay = peer.GetTxRelay(); tx_relay != nullptr) {
|
|
|
|
| 2378 |
// they must either disconnect and retry or request the full block.
|
| 2379 |
// Thus, the protocol spec specified allows for us to provide duplicate txn here,
|
| 2380 |
// however we MUST always provide at least what the remote peer needs
|
| 2381 |
+
const auto maybe_with_witness = (inv.IsMsgFilteredWitnessBlk() ? TX_WITH_WITNESS : TX_NO_WITNESS);
|
| 2382 |
for (const auto& [tx_idx, _] : merkleBlock.vMatchedTxn)
|
| 2383 |
+
MakeAndPushMessage(pfrom, NetMsgType::TX, maybe_with_witness(*pblock->vtx[tx_idx]));
|
| 2384 |
}
|
| 2385 |
// else
|
| 2386 |
// no response
|
|
|
|
| 2590 |
// eventually get the headers - even from a different peer -
|
| 2591 |
// we can use this peer to download.
|
| 2592 |
WITH_LOCK(cs_main, UpdateBlockAvailability(pfrom.GetId(), headers.back().GetHash()));
|
| 2593 |
+
|
| 2594 |
+
if (pfrom.PunishInvalidBlocks()) {
|
| 2595 |
+
pfrom.fDisconnect = true;
|
| 2596 |
+
}
|
| 2597 |
}
|
| 2598 |
|
| 2599 |
bool PeerManagerImpl::CheckHeadersAreContinuous(const std::vector<CBlockHeader>& headers) const
|
|
|
|
| 3057 |
|
| 3058 |
const auto& [add_extra_compact_tx, unique_parents, package_to_validate] = m_txdownloadman.MempoolRejectedTx(ptx, state, nodeid, first_time_failure);
|
| 3059 |
|
| 3060 |
+
const size_t tx_dynamic_usage{RecursiveDynamicUsage(*ptx)};
|
| 3061 |
+
if (add_extra_compact_tx && tx_dynamic_usage < BLOCK_RECONSTRUCTION_EXTRA_TXN_PER_TXN_SIZE_LIMIT) {
|
| 3062 |
+
AddToCompactExtraTransactions(ptx, tx_dynamic_usage);
|
| 3063 |
}
|
| 3064 |
for (const Txid& parent_txid : unique_parents) {
|
| 3065 |
if (peer) AddKnownTx(*peer, parent_txid.ToUint256());
|
|
|
|
| 3085 |
RelayTransaction(tx->GetHash(), tx->GetWitnessHash());
|
| 3086 |
|
| 3087 |
for (const CTransactionRef& removedTx : replaced_transactions) {
|
| 3088 |
+
const size_t tx_dynamic_usage{RecursiveDynamicUsage(*removedTx)};
|
| 3089 |
+
AddToCompactExtraTransactions(removedTx, tx_dynamic_usage);
|
| 3090 |
}
|
| 3091 |
}
|
| 3092 |
|
|
|
|
| 3544 |
if (!vRecv.empty()) {
|
| 3545 |
std::string strSubVer;
|
| 3546 |
vRecv >> LIMITED_STRING(strSubVer, MAX_SUBVERSION_LENGTH);
|
| 3547 |
+
cleanSubVer = SanitizeString(strSubVer, SAFE_CHARS_PRINTABLE);
|
| 3548 |
}
|
| 3549 |
if (!vRecv.empty()) {
|
| 3550 |
vRecv >> starting_height;
|
|
|
|
| 3573 |
// Change version
|
| 3574 |
const int greatest_common_version = std::min(nVersion, PROTOCOL_VERSION);
|
| 3575 |
pfrom.SetCommonVersion(greatest_common_version);
|
| 3576 |
+
{
|
| 3577 |
+
LOCK(pfrom.m_subver_mutex);
|
| 3578 |
+
pfrom.cleanSubVer = cleanSubVer;
|
| 3579 |
+
}
|
| 3580 |
pfrom.nVersion = nVersion;
|
| 3581 |
|
| 3582 |
if (greatest_common_version >= WTXID_RELAY_VERSION) {
|
|
|
|
| 3595 |
pfrom.m_has_all_wanted_services = HasAllDesirableServiceFlags(nServices);
|
| 3596 |
peer->m_their_services = nServices;
|
| 3597 |
pfrom.SetAddrLocal(addrMe);
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3598 |
peer->m_starting_height = starting_height;
|
| 3599 |
|
| 3600 |
// Only initialize the Peer::TxRelay m_relay_txs data structure if:
|
|
|
|
| 3680 |
}
|
| 3681 |
|
| 3682 |
const auto mapped_as{m_connman.GetMappedAS(pfrom.addr)};
|
| 3683 |
+
LogDebug(BCLog::NET, "receive version message: %s: version %d, blocks=%d, us=%s, txrelay=%d, peer=%d%s%s%s\n",
|
| 3684 |
+
SanitizeString(cleanSubVer, SAFE_CHARS_DEFAULT, true), pfrom.nVersion,
|
| 3685 |
peer->m_starting_height, addrMe.ToStringAddrPort(), fRelay, pfrom.GetId(),
|
| 3686 |
+
fLogIPs ? "," : "", pfrom.LogIP(fLogIPs),
|
| 3687 |
+
(mapped_as ? strprintf(", mapped_as=%d", mapped_as) : ""));
|
| 3688 |
|
| 3689 |
peer->m_time_offset = NodeSeconds{std::chrono::seconds{nTime}} - Now<NodeSeconds>();
|
| 3690 |
if (!pfrom.IsInboundConn()) {
|
|
|
|
| 3724 |
// can be triggered by an attacker at high rate.
|
| 3725 |
if (!pfrom.IsInboundConn() || LogAcceptCategory(BCLog::NET, BCLog::Level::Debug)) {
|
| 3726 |
const auto mapped_as{m_connman.GetMappedAS(pfrom.addr)};
|
| 3727 |
+
LogPrintf("New %s %s peer connected: version: %d, blocks=%d, peer=%d%s%s%s\n",
|
| 3728 |
pfrom.ConnectionTypeAsString(),
|
| 3729 |
TransportTypeAsString(pfrom.m_transport->GetInfo().transport_type),
|
| 3730 |
pfrom.nVersion.load(), peer->m_starting_height,
|
| 3731 |
+
pfrom.GetId(),
|
| 3732 |
+
fLogIPs ? "," : "", pfrom.LogIP(fLogIPs),
|
| 3733 |
(mapped_as ? strprintf(", mapped_as=%d", mapped_as) : ""));
|
| 3734 |
}
|
| 3735 |
|
|
|
|
| 5006 |
|
| 5007 |
if (pnode.HasPermission(NetPermissionFlags::NoBan)) {
|
| 5008 |
// We never disconnect or discourage peers for bad behavior if they have NetPermissionFlags::NoBan permission
|
| 5009 |
+
LogWarning("Not punishing noban peer %d!", peer.m_id);
|
| 5010 |
return false;
|
| 5011 |
}
|
| 5012 |
|
| 5013 |
if (pnode.IsManualConn()) {
|
| 5014 |
// We never disconnect or discourage manual peers for bad behavior
|
| 5015 |
+
LogWarning("Not punishing manually connected peer %d!", peer.m_id);
|
| 5016 |
return false;
|
| 5017 |
}
|
| 5018 |
|
|
|
|
| 5438 |
{
|
| 5439 |
if (m_opts.ignore_incoming_txs) return;
|
| 5440 |
if (pto.GetCommonVersion() < FEEFILTER_VERSION) return;
|
| 5441 |
+
if (!gArgs.GetBoolArg("-feefilter", DEFAULT_FEEFILTER)) return;
|
| 5442 |
// peers with the forcerelay permission should not filter txs to us
|
| 5443 |
if (pto.HasPermission(NetPermissionFlags::ForceRelay)) return;
|
| 5444 |
// Don't send feefilter messages to outbound block-relay-only peers since they should never announce
|
|
|
|
| 5779 |
if (tx_relay->m_next_inv_send_time < current_time) {
|