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. The two line-number columns refer to before and after.
src/net_processing.cpp
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
#include <chain.h>
|
|
14
14
|
#include <chainparams.h>
|
|
15
15
|
#include <common/bloom.h>
|
|
16
|
+
#include <common/args.h>
|
|
16
17
|
#include <consensus/amount.h>
|
|
17
18
|
#include <consensus/params.h>
|
|
18
19
|
#include <consensus/validation.h>
|
|
@@ -530,7 +531,7 @@ public:
|
|
|
530
531
|
/** Implement PeerManager */
|
|
531
532
|
void StartScheduledTasks(CScheduler& scheduler) override;
|
|
532
533
|
void CheckForStaleTipAndEvictPeers() override;
|
|
533
|
-
std::optional<std::string> FetchBlock(NodeId peer_id, const CBlockIndex& block_index) override
|
|
534
|
+
std::optional<std::string> FetchBlock(NodeId peer_id, const uint256& hash, const CBlockIndex* block_index) override
|
|
534
535
|
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
|
|
535
536
|
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) const override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
|
|
536
537
|
std::vector<node::TxOrphanage::OrphanInfo> GetOrphanTransactions() override EXCLUSIVE_LOCKS_REQUIRED(!m_tx_download_mutex);
|
|
@@ -807,7 +808,7 @@ private:
|
|
|
807
808
|
|
|
808
809
|
uint32_t GetFetchFlags(const Peer& peer) const;
|
|
809
810
|
|
|
810
|
-
std::atomic<std::chrono::microseconds> m_next_inv_to_inbounds{0us};
|
|
811
|
+
std::map<uint64_t, std::chrono::microseconds> m_next_inv_to_inbounds_per_network_key GUARDED_BY(g_msgproc_mutex);
|
|
811
812
|
|
|
812
813
|
/** Number of nodes with fSyncStarted. */
|
|
813
814
|
int nSyncStarted GUARDED_BY(cs_main) = 0;
|
|
@@ -837,12 +838,14 @@ private:
|
|
|
837
838
|
|
|
838
839
|
/**
|
|
839
840
|
* 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
|
+
* distributed) timer for all peers with the same network key. If we used a separate timer for each
|
|
841
842
|
* 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). */
|
|
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. */
|
|
844
846
|
std::chrono::microseconds NextInvToInbounds(std::chrono::microseconds now,
|
|
845
|
-
std::chrono::seconds average_interval) EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);
|
|
847
|
+
std::chrono::seconds average_interval,
|
|
848
|
+
uint64_t network_key) EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);
|
|
846
849
|
|
|
847
850
|
|
|
848
851
|
// All of the following cache a recent block, and are protected by m_most_recent_block_mutex
|
|
@@ -879,6 +882,9 @@ private:
|
|
|
879
882
|
/** Have we requested this block from an outbound peer */
|
|
880
883
|
bool IsBlockRequestedFromOutbound(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main, !m_peer_mutex);
|
|
881
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
|
+
|
|
882
888
|
/** Remove this block from our tracked requested blocks. Called if:
|
|
883
889
|
* - the block has been received from a peer
|
|
884
890
|
* - the request for the block has timed out
|
|
@@ -969,7 +975,7 @@ private:
|
|
|
969
975
|
/** Number of peers from which we're downloading blocks. */
|
|
970
976
|
int m_peers_downloading_from GUARDED_BY(cs_main) = 0;
|
|
971
977
|
|
|
972
|
-
void AddToCompactExtraTransactions(const CTransactionRef& tx) EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);
|
|
978
|
+
void AddToCompactExtraTransactions(const CTransactionRef& tx, size_t tx_dynamic_usage) EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);
|
|
973
979
|
|
|
974
980
|
/** Orphan/conflicted/etc transactions that are kept for compact block reconstruction.
|
|
975
981
|
* The last -blockreconstructionextratxn/DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN of
|
|
@@ -977,6 +983,7 @@ private:
|
|
|
977
983
|
std::vector<std::pair<Wtxid, CTransactionRef>> vExtraTxnForCompact GUARDED_BY(g_msgproc_mutex);
|
|
978
984
|
/** Offset into vExtraTxnForCompact to insert the next tx */
|
|
979
985
|
size_t vExtraTxnForCompactIt GUARDED_BY(g_msgproc_mutex) = 0;
|
|
986
|
+
size_t blockreconstructionextratxn_memusage{0};
|
|
980
987
|
|
|
981
988
|
/** Check whether the last unknown block a peer advertised is not yet known. */
|
|
982
989
|
void ProcessBlockAvailability(NodeId nodeid) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
|
@@ -1143,15 +1150,15 @@ static bool CanServeWitnesses(const Peer& peer)
|
|
|
1143
1150
|
}
|
|
1144
1151
|
|
|
1145
1152
|
std::chrono::microseconds PeerManagerImpl::NextInvToInbounds(std::chrono::microseconds now,
|
|
1146
|
-
std::chrono::seconds average_interval)
|
|
1153
|
+
std::chrono::seconds average_interval,
|
|
1154
|
+
uint64_t network_key)
|
|
1147
1155
|
{
|
|
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);
|
|
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);
|
|
1153
1160
|
}
|
|
1154
|
-
return m_next_inv_to_inbounds;
|
|
1161
|
+
return timer;
|
|
1155
1162
|
}
|
|
1156
1163
|
|
|
1157
1164
|
bool PeerManagerImpl::IsBlockRequested(const uint256& hash)
|
|
@@ -1170,6 +1177,16 @@ bool PeerManagerImpl::IsBlockRequestedFromOutbound(const uint256& hash)
|
|
|
1170
1177
|
return false;
|
|
1171
1178
|
}
|
|
1172
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
|
+
|
|
1173
1190
|
void PeerManagerImpl::RemoveBlockRequest(const uint256& hash, std::optional<NodeId> from_peer)
|
|
1174
1191
|
{
|
|
1175
1192
|
auto range = mapBlocksInFlight.equal_range(hash);
|
|
@@ -1561,6 +1578,9 @@ void PeerManagerImpl::InitializeNode(const CNode& node, ServiceFlags our_service
|
|
|
1561
1578
|
if (NetPermissions::HasFlag(node.m_permission_flags, NetPermissionFlags::BloomFilter)) {
|
|
1562
1579
|
our_services = static_cast<ServiceFlags>(our_services | NODE_BLOOM);
|
|
1563
1580
|
}
|
|
1581
|
+
if (NetPermissions::HasFlag(node.m_permission_flags, NetPermissionFlags::BlockFilters)) {
|
|
1582
|
+
our_services = static_cast<ServiceFlags>(our_services | NODE_COMPACT_FILTERS);
|
|
1583
|
+
}
|
|
1564
1584
|
|
|
1565
1585
|
PeerRef peer = std::make_shared<Peer>(nodeid, our_services, node.IsInboundConn());
|
|
1566
1586
|
{
|
|
@@ -1708,6 +1728,7 @@ bool PeerManagerImpl::GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) c
|
|
|
1708
1728
|
if (queue.pindex)
|
|
1709
1729
|
stats.vHeightInFlight.push_back(queue.pindex->nHeight);
|
|
1710
1730
|
}
|
|
1731
|
+
stats.m_last_block_announcement = NodeSeconds{std::chrono::seconds{state->m_last_block_announcement}};
|
|
1711
1732
|
}
|
|
1712
1733
|
|
|
1713
1734
|
PeerRef peer = GetPeerRef(nodeid);
|
|
@@ -1744,6 +1765,7 @@ bool PeerManagerImpl::GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) c
|
|
|
1744
1765
|
}
|
|
1745
1766
|
}
|
|
1746
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;
|
|
1747
1769
|
|
|
1748
1770
|
return true;
|
|
1749
1771
|
}
|
|
@@ -1762,14 +1784,26 @@ PeerManagerInfo PeerManagerImpl::GetInfo() const
|
|
|
1762
1784
|
};
|
|
1763
1785
|
}
|
|
1764
1786
|
|
|
1765
|
-
void PeerManagerImpl::AddToCompactExtraTransactions(const CTransactionRef& tx)
|
|
1787
|
+
void PeerManagerImpl::AddToCompactExtraTransactions(const CTransactionRef& tx, const size_t tx_dynamic_usage)
|
|
1766
1788
|
{
|
|
1767
1789
|
if (m_opts.max_extra_txs <= 0)
|
|
1768
1790
|
return;
|
|
1769
1791
|
if (!vExtraTxnForCompact.size())
|
|
1770
1792
|
vExtraTxnForCompact.resize(m_opts.max_extra_txs);
|
|
1771
|
-
vExtraTxnForCompact[vExtraTxnForCompactIt] = std::make_pair(tx->GetWitnessHash(), tx);
|
|
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
|
+
}
|
|
1772
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
|
+
}
|
|
1773
1807
|
}
|
|
1774
1808
|
|
|
1775
1809
|
void PeerManagerImpl::Misbehaving(Peer& peer, const std::string& message)
|
|
@@ -1785,10 +1819,23 @@ void PeerManagerImpl::Misbehaving(Peer& peer, const std::string& message)
|
|
|
1785
1819
|
);
|
|
1786
1820
|
}
|
|
1787
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
|
+
|
|
1788
1836
|
void PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidationState& state,
|
|
1789
1837
|
bool via_compact_block, const std::string& message)
|
|
1790
1838
|
{
|
|
1791
|
-
PeerRef peer{GetPeerRef(nodeid)};
|
|
1792
1839
|
switch (state.GetResult()) {
|
|
1793
1840
|
case BlockValidationResult::BLOCK_RESULT_UNSET:
|
|
1794
1841
|
break;
|
|
@@ -1800,7 +1847,7 @@ void PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidati
|
|
|
1800
1847
|
case BlockValidationResult::BLOCK_CONSENSUS:
|
|
1801
1848
|
case BlockValidationResult::BLOCK_MUTATED:
|
|
1802
1849
|
if (!via_compact_block) {
|
|
1803
|
-
if (peer) Misbehaving(*peer, message);
|
|
1850
|
+
HandleDoSPunishment(m_connman, nodeid, 100, "block");
|
|
1804
1851
|
return;
|
|
1805
1852
|
}
|
|
1806
1853
|
break;
|
|
@@ -1808,19 +1855,19 @@ void PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidati
|
|
|
1808
1855
|
{
|
|
1809
1856
|
// Discourage outbound (but not inbound) peers if on an invalid chain.
|
|
1810
1857
|
// 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);
|
|
1858
|
+
if (!via_compact_block) {
|
|
1859
|
+
HandleDoSPunishment(m_connman, nodeid, 100, "block");
|
|
1813
1860
|
return;
|
|
1814
1861
|
}
|
|
1815
1862
|
break;
|
|
1816
1863
|
}
|
|
1817
1864
|
case BlockValidationResult::BLOCK_INVALID_HEADER:
|
|
1818
1865
|
case BlockValidationResult::BLOCK_INVALID_PREV:
|
|
1819
|
-
if (peer) Misbehaving(*peer, message);
|
|
1866
|
+
HandleDoSPunishment(m_connman, nodeid, 100, "block header");
|
|
1820
1867
|
return;
|
|
1821
1868
|
// Conflicting (but not necessarily invalid) data or different policy:
|
|
1822
1869
|
case BlockValidationResult::BLOCK_MISSING_PREV:
|
|
1823
|
-
if (peer) Misbehaving(*peer, message);
|
|
1870
|
+
HandleDoSPunishment(m_connman, nodeid, 100, "block header");
|
|
1824
1871
|
return;
|
|
1825
1872
|
case BlockValidationResult::BLOCK_TIME_FUTURE:
|
|
1826
1873
|
break;
|
|
@@ -1839,7 +1886,7 @@ bool PeerManagerImpl::BlockRequestAllowed(const CBlockIndex* pindex)
|
|
|
1839
1886
|
(GetBlockProofEquivalentTime(*m_chainman.m_best_header, *pindex, *m_chainman.m_best_header, m_chainparams.GetConsensus()) < STALE_RELAY_AGE_LIMIT);
|
|
1840
1887
|
}
|
|
1841
1888
|
|
|
1842
|
-
std::optional<std::string> PeerManagerImpl::FetchBlock(NodeId peer_id, const CBlockIndex& block_index)
|
|
1889
|
+
std::optional<std::string> PeerManagerImpl::FetchBlock(NodeId peer_id, const uint256& hash, const CBlockIndex* block_index)
|
|
1843
1890
|
{
|
|
1844
1891
|
if (m_chainman.m_blockman.LoadingBlocks()) return "Loading blocks ...";
|
|
1845
1892
|
|
|
@@ -1852,14 +1899,18 @@ std::optional<std::string> PeerManagerImpl::FetchBlock(NodeId peer_id, const CBl
|
|
|
1852
1899
|
|
|
1853
1900
|
LOCK(cs_main);
|
|
1854
1901
|
|
|
1855
|
-
// Forget about all prior requests
|
|
1856
|
-
RemoveBlockRequest(block_index.GetBlockHash(), std::nullopt);
|
|
1902
|
+
if (IsBlockRequestedFromPeer(hash, peer_id)) return "Already requested from this peer";
|
|
1857
1903
|
|
|
1858
|
-
// Mark block as in-flight
|
|
1859
|
-
if (!BlockRequested(peer_id, block_index)) return "Already requested from this peer";
|
|
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
|
+
}
|
|
1860
1912
|
|
|
1861
1913
|
// Construct message to request the block
|
|
1862
|
-
const uint256& hash{block_index.GetBlockHash()};
|
|
1863
1914
|
std::vector<CInv> invs{CInv(MSG_BLOCK | MSG_WITNESS_FLAG, hash)};
|
|
1864
1915
|
|
|
1865
1916
|
// Send block request message to the peer
|
|
@@ -1875,6 +1926,12 @@ std::optional<std::string> PeerManagerImpl::FetchBlock(NodeId peer_id, const CBl
|
|
|
1875
1926
|
return std::nullopt;
|
|
1876
1927
|
}
|
|
1877
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
|
+
|
|
1878
1935
|
std::unique_ptr<PeerManager> PeerManager::make(CConnman& connman, AddrMan& addrman,
|
|
1879
1936
|
BanMan* banman, ChainstateManager& chainman,
|
|
1880
1937
|
CTxMemPool& pool, node::Warnings& warnings, Options opts)
|
|
@@ -1882,11 +1939,12 @@ std::unique_ptr<PeerManager> PeerManager::make(CConnman& connman, AddrMan& addrm
|
|
|
1882
1939
|
return std::make_unique<PeerManagerImpl>(connman, addrman, banman, chainman, pool, warnings, opts);
|
|
1883
1940
|
}
|
|
1884
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");
|
|
1885
1943
|
PeerManagerImpl::PeerManagerImpl(CConnman& connman, AddrMan& addrman,
|
|
1886
1944
|
BanMan* banman, ChainstateManager& chainman,
|
|
1887
1945
|
CTxMemPool& pool, node::Warnings& warnings, Options opts)
|
|
1888
1946
|
: m_rng{opts.deterministic_rng},
|
|
1889
|
-
m_fee_filter_rounder{CFeeRate{DEFAULT_MIN_RELAY_TX_FEE}, m_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},
|
|
1890
1948
|
m_chainparams(chainman.GetParams()),
|
|
1891
1949
|
m_connman(connman),
|
|
1892
1950
|
m_addrman(addrman),
|
|
@@ -2239,7 +2297,7 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
|
|
|
2239
2297
|
}
|
|
2240
2298
|
// disconnect node in case we have reached the outbound limit for serving historical blocks
|
|
2241
2299
|
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()) &&
|
|
2300
|
+
(((m_chainman.m_best_header != nullptr) && (m_chainman.m_best_header->GetBlockTime() - pindex->GetBlockTime() > HISTORICAL_BLOCK_AGE)) || inv.IsMsgFilteredBlk() || inv.IsMsgFilteredWitnessBlk()) &&
|
|
2243
2301
|
!pfrom.HasPermission(NetPermissionFlags::Download) // nodes with the download permission may exceed target
|
|
2244
2302
|
) {
|
|
2245
2303
|
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
2360
|
MakeAndPushMessage(pfrom, NetMsgType::BLOCK, TX_NO_WITNESS(*pblock));
|
|
2303
2361
|
} else if (inv.IsMsgWitnessBlk()) {
|
|
2304
2362
|
MakeAndPushMessage(pfrom, NetMsgType::BLOCK, TX_WITH_WITNESS(*pblock));
|
|
2305
|
-
} else if (inv.IsMsgFilteredBlk()) {
|
|
2363
|
+
} else if (inv.IsMsgFilteredBlk() || inv.IsMsgFilteredWitnessBlk()) {
|
|
2306
2364
|
bool sendMerkleBlock = false;
|
|
2307
2365
|
CMerkleBlock merkleBlock;
|
|
2308
2366
|
if (auto tx_relay = peer.GetTxRelay(); tx_relay != nullptr) {
|
|
@@ -2320,8 +2378,9 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
|
|
|
2320
2378
|
// they must either disconnect and retry or request the full block.
|
|
2321
2379
|
// Thus, the protocol spec specified allows for us to provide duplicate txn here,
|
|
2322
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);
|
|
2323
2382
|
for (const auto& [tx_idx, _] : merkleBlock.vMatchedTxn)
|
|
2324
|
-
MakeAndPushMessage(pfrom, NetMsgType::TX, TX_NO_WITNESS(*pblock->vtx[tx_idx]));
|
|
2383
|
+
MakeAndPushMessage(pfrom, NetMsgType::TX, maybe_with_witness(*pblock->vtx[tx_idx]));
|
|
2325
2384
|
}
|
|
2326
2385
|
// else
|
|
2327
2386
|
// no response
|
|
@@ -2531,6 +2590,10 @@ void PeerManagerImpl::HandleUnconnectingHeaders(CNode& pfrom, Peer& peer,
|
|
|
2531
2590
|
// eventually get the headers - even from a different peer -
|
|
2532
2591
|
// we can use this peer to download.
|
|
2533
2592
|
WITH_LOCK(cs_main, UpdateBlockAvailability(pfrom.GetId(), headers.back().GetHash()));
|
|
2593
|
+
|
|
2594
|
+
if (pfrom.PunishInvalidBlocks()) {
|
|
2595
|
+
pfrom.fDisconnect = true;
|
|
2596
|
+
}
|
|
2534
2597
|
}
|
|
2535
2598
|
|
|
2536
2599
|
bool PeerManagerImpl::CheckHeadersAreContinuous(const std::vector<CBlockHeader>& headers) const
|
|
@@ -2994,8 +3057,9 @@ std::optional<node::PackageToValidate> PeerManagerImpl::ProcessInvalidTx(NodeId
|
|
|
2994
3057
|
|
|
2995
3058
|
const auto& [add_extra_compact_tx, unique_parents, package_to_validate] = m_txdownloadman.MempoolRejectedTx(ptx, state, nodeid, first_time_failure);
|
|
2996
3059
|
|
|
2997
|
-
if (add_extra_compact_tx && RecursiveDynamicUsage(*ptx) < 100000) {
|
|
2998
|
-
AddToCompactExtraTransactions(ptx);
|
|
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);
|
|
2999
3063
|
}
|
|
3000
3064
|
for (const Txid& parent_txid : unique_parents) {
|
|
3001
3065
|
if (peer) AddKnownTx(*peer, parent_txid.ToUint256());
|
|
@@ -3021,7 +3085,8 @@ void PeerManagerImpl::ProcessValidTx(NodeId nodeid, const CTransactionRef& tx, c
|
|
|
3021
3085
|
RelayTransaction(tx->GetHash(), tx->GetWitnessHash());
|
|
3022
3086
|
|
|
3023
3087
|
for (const CTransactionRef& removedTx : replaced_transactions) {
|
|
3024
|
-
AddToCompactExtraTransactions(removedTx);
|
|
3088
|
+
const size_t tx_dynamic_usage{RecursiveDynamicUsage(*removedTx)};
|
|
3089
|
+
AddToCompactExtraTransactions(removedTx, tx_dynamic_usage);
|
|
3025
3090
|
}
|
|
3026
3091
|
}
|
|
3027
3092
|
|
|
@@ -3479,7 +3544,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
|
|
3479
3544
|
if (!vRecv.empty()) {
|
|
3480
3545
|
std::string strSubVer;
|
|
3481
3546
|
vRecv >> LIMITED_STRING(strSubVer, MAX_SUBVERSION_LENGTH);
|
|
3482
|
-
cleanSubVer = SanitizeString(strSubVer);
|
|
3547
|
+
cleanSubVer = SanitizeString(strSubVer, SAFE_CHARS_PRINTABLE);
|
|
3483
3548
|
}
|
|
3484
3549
|
if (!vRecv.empty()) {
|
|
3485
3550
|
vRecv >> starting_height;
|
|
@@ -3508,6 +3573,10 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
|
|
3508
3573
|
// Change version
|
|
3509
3574
|
const int greatest_common_version = std::min(nVersion, PROTOCOL_VERSION);
|
|
3510
3575
|
pfrom.SetCommonVersion(greatest_common_version);
|
|
3576
|
+
{
|
|
3577
|
+
LOCK(pfrom.m_subver_mutex);
|
|
3578
|
+
pfrom.cleanSubVer = cleanSubVer;
|
|
3579
|
+
}
|
|
3511
3580
|
pfrom.nVersion = nVersion;
|
|
3512
3581
|
|
|
3513
3582
|
if (greatest_common_version >= WTXID_RELAY_VERSION) {
|
|
@@ -3526,10 +3595,6 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
|
|
3526
3595
|
pfrom.m_has_all_wanted_services = HasAllDesirableServiceFlags(nServices);
|
|
3527
3596
|
peer->m_their_services = nServices;
|
|
3528
3597
|
pfrom.SetAddrLocal(addrMe);
|
|
3529
|
-
{
|
|
3530
|
-
LOCK(pfrom.m_subver_mutex);
|
|
3531
|
-
pfrom.cleanSubVer = cleanSubVer;
|
|
3532
|
-
}
|
|
3533
3598
|
peer->m_starting_height = starting_height;
|
|
3534
3599
|
|
|
3535
3600
|
// 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
3680
|
}
|
|
3616
3681
|
|
|
3617
3682
|
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,
|
|
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,
|
|
3620
3685
|
peer->m_starting_height, addrMe.ToStringAddrPort(), fRelay, pfrom.GetId(),
|
|
3621
|
-
pfrom.LogIP(fLogIPs), (mapped_as ? strprintf(", mapped_as=%d", mapped_as) : ""));
|
|
3686
|
+
fLogIPs ? "," : "", pfrom.LogIP(fLogIPs),
|
|
3687
|
+
(mapped_as ? strprintf(", mapped_as=%d", mapped_as) : ""));
|
|
3622
3688
|
|
|
3623
3689
|
peer->m_time_offset = NodeSeconds{std::chrono::seconds{nTime}} - Now<NodeSeconds>();
|
|
3624
3690
|
if (!pfrom.IsInboundConn()) {
|
|
@@ -3658,11 +3724,12 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
|
|
3658
3724
|
// can be triggered by an attacker at high rate.
|
|
3659
3725
|
if (!pfrom.IsInboundConn() || LogAcceptCategory(BCLog::NET, BCLog::Level::Debug)) {
|
|
3660
3726
|
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",
|
|
3727
|
+
LogPrintf("New %s %s peer connected: version: %d, blocks=%d, peer=%d%s%s%s\n",
|
|
3662
3728
|
pfrom.ConnectionTypeAsString(),
|
|
3663
3729
|
TransportTypeAsString(pfrom.m_transport->GetInfo().transport_type),
|
|
3664
3730
|
pfrom.nVersion.load(), peer->m_starting_height,
|
|
3665
|
-
pfrom.GetId(), pfrom.LogIP(fLogIPs),
|
|
3731
|
+
pfrom.GetId(),
|
|
3732
|
+
fLogIPs ? "," : "", pfrom.LogIP(fLogIPs),
|
|
3666
3733
|
(mapped_as ? strprintf(", mapped_as=%d", mapped_as) : ""));
|
|
3667
3734
|
}
|
|
3668
3735
|
|
|
@@ -4939,13 +5006,13 @@ bool PeerManagerImpl::MaybeDiscourageAndDisconnect(CNode& pnode, Peer& peer)
|
|
|
4939
5006
|
|
|
4940
5007
|
if (pnode.HasPermission(NetPermissionFlags::NoBan)) {
|
|
4941
5008
|
// 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);
|
|
5009
|
+
LogWarning("Not punishing noban peer %d!", peer.m_id);
|
|
4943
5010
|
return false;
|
|
4944
5011
|
}
|
|
4945
5012
|
|
|
4946
5013
|
if (pnode.IsManualConn()) {
|
|
4947
5014
|
// We never disconnect or discourage manual peers for bad behavior
|
|
4948
|
-
LogPrintf("Warning: not punishing manually connected peer %d!\n", peer.m_id);
|
|
5015
|
+
LogWarning("Not punishing manually connected peer %d!", peer.m_id);
|
|
4949
5016
|
return false;
|
|
4950
5017
|
}
|
|
4951
5018
|
|
|
@@ -5371,6 +5438,7 @@ void PeerManagerImpl::MaybeSendFeefilter(CNode& pto, Peer& peer, std::chrono::mi
|
|
|
5371
5438
|
{
|
|
5372
5439
|
if (m_opts.ignore_incoming_txs) return;
|
|
5373
5440
|
if (pto.GetCommonVersion() < FEEFILTER_VERSION) return;
|
|
5441
|
+
if (!gArgs.GetBoolArg("-feefilter", DEFAULT_FEEFILTER)) return;
|
|
5374
5442
|
// peers with the forcerelay permission should not filter txs to us
|
|
5375
5443
|
if (pto.HasPermission(NetPermissionFlags::ForceRelay)) return;
|
|
5376
5444
|
// 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
5779
|
if (tx_relay->m_next_inv_send_time < current_time) {
|