Skip to content

Commit 147d50d

Browse files
author
MarcoFalke
committed
Merge #19791: [net processing] Move Misbehaving() to PeerManager
bb6a32c [net processing] Move Misbehaving() to PeerManager (John Newbery) aa114b1 [net_processing] Move SendBlockTransactions into PeerManager (John Newbery) 3115e00 [net processing] Move MaybePunishPeerForTx to PeerManager (John Newbery) e662e2d [net processing] Move ProcessOrphanTx to PeerManager (John Newbery) b70cd89 [net processing] Move MaybePunishNodeForBlock into PeerManager (John Newbery) d777835 [net processing] Move ProcessHeadersMessage to PeerManager (John Newbery) 64f6162 [whitespace] tidy up indentation after scripted diff (John Newbery) 58bd369 scripted-diff: [net processing] Rename PeerLogicValidation to PeerManager (John Newbery) 2297b26 [net_processing] Pass chainparams to PeerLogicValidation constructor (John Newbery) 824bbd1 [move only] Collect all private members of PeerLogicValidation together (John Newbery) Pull request description: Continues the work of moving net_processing logic into PeerLogicValidation. See bitcoin/bitcoin#19704 and bitcoin/bitcoin#19607 (comment) for motivation. This PR also renames `PeerLogicValidation` to `PeerManager` as suggested in bitcoin/bitcoin#10756 (review). ACKs for top commit: MarcoFalke: re-ACK bb6a32c only change is rebase due to conflict in struct NodeContext and variable rename 🤸 hebasto: re-ACK bb6a32c, only rebased, and added renaming `s/peer_logic/peerman/` into scripted-diff since my [previous](bitcoin/bitcoin#19791 (review)) review (verified with `git range-diff`). Tree-SHA512: a2de4a521688fd25125b401e5575402c52b328a0fa27b3010567008d4f596b960aabbd02b2d81f42658f88f4365443fadb1008150a62fbcea123fb42d85a2c21
2 parents 2583966 + bb6a32c commit 147d50d

File tree

9 files changed

+147
-123
lines changed

9 files changed

+147
-123
lines changed

src/init.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ void Shutdown(NodeContext& node)
200200

201201
// Because these depend on each-other, we make sure that neither can be
202202
// using the other before destroying them.
203-
if (node.peer_logic) UnregisterValidationInterface(node.peer_logic.get());
203+
if (node.peerman) UnregisterValidationInterface(node.peerman.get());
204204
// Follow the lock order requirements:
205205
// * CheckForStaleTipAndEvictPeers locks cs_main before indirectly calling GetExtraOutboundCount
206206
// which locks cs_vNodes.
@@ -227,7 +227,7 @@ void Shutdown(NodeContext& node)
227227

228228
// After the threads that potentially access these pointers have been stopped,
229229
// destruct and reset all to nullptr.
230-
node.peer_logic.reset();
230+
node.peerman.reset();
231231
node.connman.reset();
232232
node.banman.reset();
233233

@@ -1376,8 +1376,8 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA
13761376
node.chainman = &g_chainman;
13771377
ChainstateManager& chainman = *Assert(node.chainman);
13781378

1379-
node.peer_logic.reset(new PeerLogicValidation(*node.connman, node.banman.get(), *node.scheduler, chainman, *node.mempool));
1380-
RegisterValidationInterface(node.peer_logic.get());
1379+
node.peerman.reset(new PeerManager(chainparams, *node.connman, node.banman.get(), *node.scheduler, chainman, *node.mempool));
1380+
RegisterValidationInterface(node.peerman.get());
13811381

13821382
// sanitize comments per BIP-0014, format user agent and check total size
13831383
std::vector<std::string> uacomments;
@@ -1911,7 +1911,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA
19111911
connOptions.nBestHeight = chain_active_height;
19121912
connOptions.uiInterface = &uiInterface;
19131913
connOptions.m_banman = node.banman.get();
1914-
connOptions.m_msgproc = node.peer_logic.get();
1914+
connOptions.m_msgproc = node.peerman.get();
19151915
connOptions.nSendBufferMaxSize = 1000 * args.GetArg("-maxsendbuffer", DEFAULT_MAXSENDBUFFER);
19161916
connOptions.nReceiveFloodSize = 1000 * args.GetArg("-maxreceivebuffer", DEFAULT_MAXRECEIVEBUFFER);
19171917
connOptions.m_added_nodes = args.GetArgs("-addnode");

src/net_processing.cpp

Lines changed: 64 additions & 84 deletions
Large diffs are not rendered by default.

src/net_processing.h

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,13 @@
1111
#include <sync.h>
1212
#include <validationinterface.h>
1313

14+
class BlockTransactionsRequest;
15+
class BlockValidationState;
16+
class CBlockHeader;
1417
class CChainParams;
1518
class CTxMemPool;
1619
class ChainstateManager;
20+
class TxValidationState;
1721

1822
extern RecursiveMutex cs_main;
1923
extern RecursiveMutex g_cs_orphans;
@@ -27,18 +31,10 @@ static const bool DEFAULT_PEERBLOCKFILTERS = false;
2731
/** Threshold for marking a node to be discouraged, e.g. disconnected and added to the discouragement filter. */
2832
static const int DISCOURAGEMENT_THRESHOLD{100};
2933

30-
class PeerLogicValidation final : public CValidationInterface, public NetEventsInterface {
31-
private:
32-
CConnman& m_connman;
33-
/** Pointer to this node's banman. May be nullptr - check existence before dereferencing. */
34-
BanMan* const m_banman;
35-
ChainstateManager& m_chainman;
36-
CTxMemPool& m_mempool;
37-
38-
bool MaybeDiscourageAndDisconnect(CNode& pnode);
39-
34+
class PeerManager final : public CValidationInterface, public NetEventsInterface {
4035
public:
41-
PeerLogicValidation(CConnman& connman, BanMan* banman, CScheduler& scheduler, ChainstateManager& chainman, CTxMemPool& pool);
36+
PeerManager(const CChainParams& chainparams, CConnman& connman, BanMan* banman,
37+
CScheduler& scheduler, ChainstateManager& chainman, CTxMemPool& pool);
4238

4339
/**
4440
* Overridden from CValidationInterface.
@@ -88,12 +84,58 @@ class PeerLogicValidation final : public CValidationInterface, public NetEventsI
8884

8985
/** Process a single message from a peer. Public for fuzz testing */
9086
void ProcessMessage(CNode& pfrom, const std::string& msg_type, CDataStream& vRecv,
91-
const std::chrono::microseconds time_received, const CChainParams& chainparams,
92-
const std::atomic<bool>& interruptMsgProc);
87+
const std::chrono::microseconds time_received, const std::atomic<bool>& interruptMsgProc);
88+
89+
/**
90+
* Increment peer's misbehavior score. If the new value >= DISCOURAGEMENT_THRESHOLD, mark the node
91+
* to be discouraged, meaning the peer might be disconnected and added to the discouragement filter.
92+
* Public for unit testing.
93+
*/
94+
void Misbehaving(const NodeId pnode, const int howmuch, const std::string& message);
9395

9496
private:
95-
int64_t m_stale_tip_check_time; //!< Next time to check for stale tip
97+
/**
98+
* Potentially mark a node discouraged based on the contents of a BlockValidationState object
99+
*
100+
* @param[in] via_compact_block this bool is passed in because net_processing should
101+
* punish peers differently depending on whether the data was provided in a compact
102+
* block message or not. If the compact block had a valid header, but contained invalid
103+
* txs, the peer should not be punished. See BIP 152.
104+
*
105+
* @return Returns true if the peer was punished (probably disconnected)
106+
*/
107+
bool MaybePunishNodeForBlock(NodeId nodeid, const BlockValidationState& state,
108+
bool via_compact_block, const std::string& message = "");
96109

110+
/**
111+
* Potentially disconnect and discourage a node based on the contents of a TxValidationState object
112+
*
113+
* @return Returns true if the peer was punished (probably disconnected)
114+
*/
115+
bool MaybePunishNodeForTx(NodeId nodeid, const TxValidationState& state, const std::string& message = "");
116+
117+
/** Maybe disconnect a peer and discourage future connections from its address.
118+
*
119+
* @param[in] pnode The node to check.
120+
* @return True if the peer was marked for disconnection in this function
121+
*/
122+
bool MaybeDiscourageAndDisconnect(CNode& pnode);
123+
124+
void ProcessOrphanTx(std::set<uint256>& orphan_work_set, std::list<CTransactionRef>& removed_txn)
125+
EXCLUSIVE_LOCKS_REQUIRED(cs_main, g_cs_orphans);
126+
/** Process a single headers message from a peer. */
127+
void ProcessHeadersMessage(CNode& pfrom, const std::vector<CBlockHeader>& headers, bool via_compact_block);
128+
129+
void SendBlockTransactions(CNode& pfrom, const CBlock& block, const BlockTransactionsRequest& req);
130+
131+
const CChainParams& m_chainparams;
132+
CConnman& m_connman;
133+
/** Pointer to this node's banman. May be nullptr - check existence before dereferencing. */
134+
BanMan* const m_banman;
135+
ChainstateManager& m_chainman;
136+
CTxMemPool& m_mempool;
137+
138+
int64_t m_stale_tip_check_time; //!< Next time to check for stale tip
97139
};
98140

99141
struct CNodeStateStats {

src/node/context.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class CConnman;
1616
class CScheduler;
1717
class CTxMemPool;
1818
class ChainstateManager;
19-
class PeerLogicValidation;
19+
class PeerManager;
2020
namespace interfaces {
2121
class Chain;
2222
class ChainClient;
@@ -36,7 +36,7 @@ class WalletClient;
3636
struct NodeContext {
3737
std::unique_ptr<CConnman> connman;
3838
std::unique_ptr<CTxMemPool> mempool;
39-
std::unique_ptr<PeerLogicValidation> peer_logic;
39+
std::unique_ptr<PeerManager> peerman;
4040
ChainstateManager* chainman{nullptr}; // Currently a raw pointer because the memory is not managed by this struct
4141
std::unique_ptr<BanMan> banman;
4242
ArgsManager* args{nullptr}; // Currently a raw pointer because the memory is not managed by this struct

src/test/denialofservice_tests.cpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ struct CConnmanTest : public CConnman {
4747
extern bool AddOrphanTx(const CTransactionRef& tx, NodeId peer);
4848
extern void EraseOrphansFor(NodeId peer);
4949
extern unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans);
50-
extern void Misbehaving(NodeId nodeid, int howmuch, const std::string& message="");
5150

5251
struct COrphanTx {
5352
CTransactionRef tx;
@@ -79,8 +78,9 @@ BOOST_FIXTURE_TEST_SUITE(denialofservice_tests, TestingSetup)
7978
// work.
8079
BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
8180
{
81+
const CChainParams& chainparams = Params();
8282
auto connman = MakeUnique<CConnman>(0x1337, 0x1337);
83-
auto peerLogic = MakeUnique<PeerLogicValidation>(*connman, nullptr, *m_node.scheduler, *m_node.chainman, *m_node.mempool);
83+
auto peerLogic = MakeUnique<PeerManager>(chainparams, *connman, nullptr, *m_node.scheduler, *m_node.chainman, *m_node.mempool);
8484

8585
// Mock an outbound peer
8686
CAddress addr1(ip(0xa0b0c001), NODE_NONE);
@@ -133,7 +133,7 @@ BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
133133
peerLogic->FinalizeNode(dummyNode1.GetId(), dummy);
134134
}
135135

136-
static void AddRandomOutboundPeer(std::vector<CNode *> &vNodes, PeerLogicValidation &peerLogic, CConnmanTest* connman)
136+
static void AddRandomOutboundPeer(std::vector<CNode *> &vNodes, PeerManager &peerLogic, CConnmanTest* connman)
137137
{
138138
CAddress addr(ip(g_insecure_rand_ctx.randbits(32)), NODE_NONE);
139139
vNodes.emplace_back(new CNode(id++, ServiceFlags(NODE_NETWORK | NODE_WITNESS), 0, INVALID_SOCKET, addr, 0, 0, CAddress(), "", ConnectionType::OUTBOUND_FULL_RELAY));
@@ -149,8 +149,9 @@ static void AddRandomOutboundPeer(std::vector<CNode *> &vNodes, PeerLogicValidat
149149

150150
BOOST_AUTO_TEST_CASE(stale_tip_peer_management)
151151
{
152+
const CChainParams& chainparams = Params();
152153
auto connman = MakeUnique<CConnmanTest>(0x1337, 0x1337);
153-
auto peerLogic = MakeUnique<PeerLogicValidation>(*connman, nullptr, *m_node.scheduler, *m_node.chainman, *m_node.mempool);
154+
auto peerLogic = MakeUnique<PeerManager>(chainparams, *connman, nullptr, *m_node.scheduler, *m_node.chainman, *m_node.mempool);
154155

155156
const Consensus::Params& consensusParams = Params().GetConsensus();
156157
constexpr int max_outbound_full_relay = MAX_OUTBOUND_FULL_RELAY_CONNECTIONS;
@@ -221,9 +222,10 @@ BOOST_AUTO_TEST_CASE(stale_tip_peer_management)
221222

222223
BOOST_AUTO_TEST_CASE(peer_discouragement)
223224
{
225+
const CChainParams& chainparams = Params();
224226
auto banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
225227
auto connman = MakeUnique<CConnman>(0x1337, 0x1337);
226-
auto peerLogic = MakeUnique<PeerLogicValidation>(*connman, banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool);
228+
auto peerLogic = MakeUnique<PeerManager>(chainparams, *connman, banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool);
227229

228230
banman->ClearBanned();
229231
CAddress addr1(ip(0xa0b0c001), NODE_NONE);
@@ -232,7 +234,7 @@ BOOST_AUTO_TEST_CASE(peer_discouragement)
232234
peerLogic->InitializeNode(&dummyNode1);
233235
dummyNode1.nVersion = 1;
234236
dummyNode1.fSuccessfullyConnected = true;
235-
Misbehaving(dummyNode1.GetId(), DISCOURAGEMENT_THRESHOLD); // Should be discouraged
237+
peerLogic->Misbehaving(dummyNode1.GetId(), DISCOURAGEMENT_THRESHOLD, /* message */ ""); // Should be discouraged
236238
{
237239
LOCK(dummyNode1.cs_sendProcessing);
238240
BOOST_CHECK(peerLogic->SendMessages(&dummyNode1));
@@ -246,14 +248,14 @@ BOOST_AUTO_TEST_CASE(peer_discouragement)
246248
peerLogic->InitializeNode(&dummyNode2);
247249
dummyNode2.nVersion = 1;
248250
dummyNode2.fSuccessfullyConnected = true;
249-
Misbehaving(dummyNode2.GetId(), DISCOURAGEMENT_THRESHOLD - 1);
251+
peerLogic->Misbehaving(dummyNode2.GetId(), DISCOURAGEMENT_THRESHOLD - 1, /* message */ "");
250252
{
251253
LOCK(dummyNode2.cs_sendProcessing);
252254
BOOST_CHECK(peerLogic->SendMessages(&dummyNode2));
253255
}
254256
BOOST_CHECK(!banman->IsDiscouraged(addr2)); // 2 not discouraged yet...
255257
BOOST_CHECK(banman->IsDiscouraged(addr1)); // ... but 1 still should be
256-
Misbehaving(dummyNode2.GetId(), 1); // 2 reaches discouragement threshold
258+
peerLogic->Misbehaving(dummyNode2.GetId(), 1, /* message */ ""); // 2 reaches discouragement threshold
257259
{
258260
LOCK(dummyNode2.cs_sendProcessing);
259261
BOOST_CHECK(peerLogic->SendMessages(&dummyNode2));
@@ -268,9 +270,10 @@ BOOST_AUTO_TEST_CASE(peer_discouragement)
268270

269271
BOOST_AUTO_TEST_CASE(DoS_bantime)
270272
{
273+
const CChainParams& chainparams = Params();
271274
auto banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
272275
auto connman = MakeUnique<CConnman>(0x1337, 0x1337);
273-
auto peerLogic = MakeUnique<PeerLogicValidation>(*connman, banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool);
276+
auto peerLogic = MakeUnique<PeerManager>(chainparams, *connman, banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool);
274277

275278
banman->ClearBanned();
276279
int64_t nStartTime = GetTime();
@@ -283,7 +286,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
283286
dummyNode.nVersion = 1;
284287
dummyNode.fSuccessfullyConnected = true;
285288

286-
Misbehaving(dummyNode.GetId(), DISCOURAGEMENT_THRESHOLD);
289+
peerLogic->Misbehaving(dummyNode.GetId(), DISCOURAGEMENT_THRESHOLD, /* message */ "");
287290
{
288291
LOCK(dummyNode.cs_sendProcessing);
289292
BOOST_CHECK(peerLogic->SendMessages(&dummyNode));

src/test/fuzz/process_message.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,10 @@ void test_one_input(const std::vector<uint8_t>& buffer)
7373
p2p_node.nVersion = PROTOCOL_VERSION;
7474
p2p_node.SetSendVersion(PROTOCOL_VERSION);
7575
connman.AddTestNode(p2p_node);
76-
g_setup->m_node.peer_logic->InitializeNode(&p2p_node);
76+
g_setup->m_node.peerman->InitializeNode(&p2p_node);
7777
try {
78-
g_setup->m_node.peer_logic->ProcessMessage(p2p_node, random_message_type, random_bytes_data_stream,
79-
GetTime<std::chrono::microseconds>(), Params(),
80-
std::atomic<bool>{false});
78+
g_setup->m_node.peerman->ProcessMessage(p2p_node, random_message_type, random_bytes_data_stream,
79+
GetTime<std::chrono::microseconds>(), std::atomic<bool>{false});
8180
} catch (const std::ios_base::failure&) {
8281
}
8382
SyncWithValidationInterfaceQueue();

src/test/fuzz/process_messages.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
5252
p2p_node.fPauseSend = false;
5353
p2p_node.nVersion = PROTOCOL_VERSION;
5454
p2p_node.SetSendVersion(PROTOCOL_VERSION);
55-
g_setup->m_node.peer_logic->InitializeNode(&p2p_node);
55+
g_setup->m_node.peerman->InitializeNode(&p2p_node);
5656

5757
connman.AddTestNode(p2p_node);
5858
}

src/test/util/setup_common.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,10 +169,10 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const
169169

170170
m_node.banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
171171
m_node.connman = MakeUnique<CConnman>(0x1337, 0x1337); // Deterministic randomness for tests.
172-
m_node.peer_logic = MakeUnique<PeerLogicValidation>(*m_node.connman, m_node.banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool);
172+
m_node.peerman = MakeUnique<PeerManager>(chainparams, *m_node.connman, m_node.banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool);
173173
{
174174
CConnman::Options options;
175-
options.m_msgproc = m_node.peer_logic.get();
175+
options.m_msgproc = m_node.peerman.get();
176176
m_node.connman->Init(options);
177177
}
178178
}

test/sanitizer_suppressions/tsan

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ mutex:CConnman::ThreadOpenConnections
1111
mutex:CConnman::ThreadOpenAddedConnections
1212
mutex:CConnman::SocketHandler
1313
mutex:UpdateTip
14-
mutex:PeerLogicValidation::UpdatedBlockTip
14+
mutex:PeerManager::UpdatedBlockTip
1515
mutex:g_best_block_mutex
1616
# race (TODO fix)
1717
race:CConnman::WakeMessageHandler

0 commit comments

Comments
 (0)