From adf5302f9091fbacf81119d97904b72b54fb1f63 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Thu, 23 Jul 2020 18:32:49 +0200 Subject: [PATCH] Merge #19473: net: Add -networkactive option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2aac093a3d60e446b85eebdf170ea6bed77bec92 test: Add test coverage for -networkactive option (Hennadii Stepanov) 3c58129b1293742a49aa196cb210ff345a7339e6 net: Log network activity status change unconditionally (Hennadii Stepanov) 62fe6aa87e4cdd8b06207abc1387c68d7bfc04c1 net: Add -networkactive option (Hennadii Stepanov) Pull request description: Some Bitcoin Core activity is completely local (offline), e.g., reindexing. The `setnetworkactive` RPC command is already present. This PR adds the corresponding command-line argument / config option, and allows to start the client with disabled p2p network by providing `-networkactive=0` or `-nonetworkactive`. This was done while reviewing #16981. ACKs for top commit: MarcoFalke: re-ACK 2aac093a3d60e446b85eebdf170ea6bed77bec92 🏠 LarryRuane: ACK 2aac093a3d60e446b85eebdf170ea6bed77bec92 Tree-SHA512: 446d791b46d7b556d7694df7b1f88cd4fbc09301fe4eaf036b45cb8166ed806156353cc03788a07b633d5887d5eee30a7c02a2d4307141c8ccc75e0a88145636 --- src/init.cpp | 3 ++- src/net.cpp | 5 +++-- src/net.h | 2 +- test/functional/feature_config_args.py | 27 ++++++++++++++++++++++++++ test/functional/rpc_net.py | 6 ++++-- 5 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index c1687141b8d4fa..56db3b82f03120 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -593,6 +593,7 @@ void SetupServerArgs(NodeContext& node) argsman.AddArg("-proxyrandomize", strprintf("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)", DEFAULT_PROXYRANDOMIZE), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-seednode=", "Connect to a node to retrieve peer addresses, and disconnect. This option can be specified multiple times to connect to multiple nodes.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-socketevents=", "Socket events mode, which must be one of 'select', 'poll', 'epoll' or 'kqueue', depending on your system (default: Linux - 'epoll', FreeBSD/Apple - 'kqueue', Windows - 'select')", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); + gArgs.AddArg("-networkactive", "Enable all P2P network activity (default: 1). Can be changed by the setnetworkactive RPC command", ArgsManager::ALLOW_BOOL, OptionsCategory::CONNECTION); argsman.AddArg("-timeout=", strprintf("Specify connection timeout in milliseconds (minimum: 1, default: %d)", DEFAULT_CONNECT_TIMEOUT), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-torcontrol=:", strprintf("Tor control port to use if onion listening enabled (default: %s)", DEFAULT_TOR_CONTROL), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-torpassword=", "Tor control port password (default: empty)", ArgsManager::ALLOW_ANY | ArgsManager::SENSITIVE, OptionsCategory::CONNECTION); @@ -1673,7 +1674,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc assert(!node.banman); node.banman = std::make_unique(GetDataDir() / "banlist", &uiInterface, args.GetArg("-bantime", DEFAULT_MISBEHAVING_BANTIME)); assert(!node.connman); - node.connman = std::make_unique(GetRand(std::numeric_limits::max()), GetRand(std::numeric_limits::max()), *node.addrman); + node.connman = MakeUniqueGetRand(std::numeric_limits::max()), GetRand(std::numeric_limits::max()), *node.addrman, gArgs.GetBoolArg("-networkactive", true); assert(!node.fee_estimator); // Don't initialize fee estimation with old data if we don't relay transactions, diff --git a/src/net.cpp b/src/net.cpp index d9e2af775b0d3e..1fe858e590f491 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -3041,7 +3041,7 @@ void Discover() void CConnman::SetNetworkActive(bool active) { - LogPrint(BCLog::NET, "SetNetworkActive: %s\n", active); + LogPrintf("%s: %s\n", __func__, active); if (fNetworkActive == active) { return; @@ -3056,13 +3056,14 @@ void CConnman::SetNetworkActive(bool active) uiInterface.NotifyNetworkActiveChanged(fNetworkActive); } -CConnman::CConnman(uint64_t nSeed0In, uint64_t nSeed1In, CAddrMan& addrman_in) : +CConnman::CConnman(uint64_t nSeed0In, uint64_t nSeed1In, CAddrMan& addrman_in, bool network_active) : addrman(addrman_in), nSeed0(nSeed0In), nSeed1(nSeed1In) { SetTryNewOutboundPeer(false); Options connOptions; Init(connOptions); + SetNetworkActive(network_active); } NodeId CConnman::GetNewNodeId() diff --git a/src/net.h b/src/net.h index bd802e1f21275f..d7c6d37fad54b1 100644 --- a/src/net.h +++ b/src/net.h @@ -214,7 +214,7 @@ friend class CNode; m_onion_binds = connOptions.onion_binds; } - CConnman(uint64_t seed0, uint64_t seed1, CAddrMan& addrman); + CConnman(uint64_t seed0, uint64_t seed1, CAddrMan& addrman, bool network_active = true); ~CConnman(); bool Start(CScheduler& scheduler, const Options& options); diff --git a/test/functional/feature_config_args.py b/test/functional/feature_config_args.py index d1da63fb6f417c..dafcda60b6a007 100755 --- a/test/functional/feature_config_args.py +++ b/test/functional/feature_config_args.py @@ -117,6 +117,32 @@ def test_args_log(self): ]) self.stop_node(0) + def test_networkactive(self): + self.log.info('Test -networkactive option') + with self.nodes[0].assert_debug_log(expected_msgs=['SetNetworkActive: true\n']): + self.start_node(0) + self.stop_node(0) + + with self.nodes[0].assert_debug_log(expected_msgs=['SetNetworkActive: true\n']): + self.start_node(0, extra_args=['-networkactive']) + self.stop_node(0) + + with self.nodes[0].assert_debug_log(expected_msgs=['SetNetworkActive: true\n']): + self.start_node(0, extra_args=['-networkactive=1']) + self.stop_node(0) + + with self.nodes[0].assert_debug_log(expected_msgs=['SetNetworkActive: false\n']): + self.start_node(0, extra_args=['-networkactive=0']) + self.stop_node(0) + + with self.nodes[0].assert_debug_log(expected_msgs=['SetNetworkActive: false\n']): + self.start_node(0, extra_args=['-nonetworkactive']) + self.stop_node(0) + + with self.nodes[0].assert_debug_log(expected_msgs=['SetNetworkActive: false\n']): + self.start_node(0, extra_args=['-nonetworkactive=1']) + self.stop_node(0) + def test_seed_peers(self): self.log.info('Test seed peers, this will take about 2 minutes') default_data_dir = self.nodes[0].datadir @@ -178,6 +204,7 @@ def run_test(self): self.test_log_buffer() self.test_args_log() self.test_seed_peers() + self.test_networkactive() self.test_config_file_parser() diff --git a/test/functional/rpc_net.py b/test/functional/rpc_net.py index d086db4e596abb..634773b0c05ace 100755 --- a/test/functional/rpc_net.py +++ b/test/functional/rpc_net.py @@ -99,13 +99,15 @@ def _test_getnetworkinfo(self): assert_equal(self.nodes[0].getnetworkinfo()['networkactive'], True) assert_equal(self.nodes[0].getnetworkinfo()['connections'], 3) - self.nodes[0].setnetworkactive(state=False) + with self.nodes[0].assert_debug_log(expected_msgs=['SetNetworkActive: false\n']): + self.nodes[0].setnetworkactive(state=False) assert_equal(self.nodes[0].getnetworkinfo()['networkactive'], False) # Wait a bit for all sockets to close wait_until(lambda: self.nodes[0].getnetworkinfo()['connections'] == 0, timeout=3) wait_until(lambda: self.nodes[1].getnetworkinfo()['connections'] == 0, timeout=3) - self.nodes[0].setnetworkactive(state=True) + with self.nodes[0].assert_debug_log(expected_msgs=['SetNetworkActive: true\n']): + self.nodes[0].setnetworkactive(state=True) self.log.info('Connect nodes both way') self.connect_nodes(0, 1) self.connect_nodes(1, 0)