diff --git a/doc/release-notes.md b/doc/release-notes.md --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -5,3 +5,6 @@ <https://download.bitcoinabc.org/0.23.8/> This release includes the following features and fixes: + - Add a new option `-networkactive` to enable all P2P network activity + (default 1). To start a node offline, you can provide + `-networkactive=0` or `-nonetworkactive`. diff --git a/src/init.cpp b/src/init.cpp --- a/src/init.cpp +++ b/src/init.cpp @@ -750,6 +750,10 @@ "-seednode=<ip>", "Connect to a node to retrieve peer addresses, and disconnect", 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=<n>", strprintf("Specify connection timeout in milliseconds " "(minimum: 1, default: %d)", @@ -2278,7 +2282,8 @@ assert(!node.connman); node.connman = std::make_unique<CConnman>( config, GetRand(std::numeric_limits<uint64_t>::max()), - GetRand(std::numeric_limits<uint64_t>::max())); + GetRand(std::numeric_limits<uint64_t>::max()), + gArgs.GetBoolArg("-networkactive", true)); // Make mempool generally available in the node context. For example the // connection manager, wallet, or RPC threads, which are all started after diff --git a/src/net.h b/src/net.h --- a/src/net.h +++ b/src/net.h @@ -236,7 +236,8 @@ } } - CConnman(const Config &configIn, uint64_t seed0, uint64_t seed1); + CConnman(const Config &configIn, uint64_t seed0, uint64_t seed1, + bool network_active = true); ~CConnman(); bool Start(CScheduler &scheduler, const Options &options); diff --git a/src/net.cpp b/src/net.cpp --- a/src/net.cpp +++ b/src/net.cpp @@ -2522,7 +2522,7 @@ } void CConnman::SetNetworkActive(bool active) { - LogPrint(BCLog::NET, "SetNetworkActive: %s\n", active); + LogPrintf("%s: %s\n", __func__, active); if (fNetworkActive == active) { return; @@ -2532,12 +2532,14 @@ uiInterface.NotifyNetworkActiveChanged(fNetworkActive); } -CConnman::CConnman(const Config &configIn, uint64_t nSeed0In, uint64_t nSeed1In) +CConnman::CConnman(const Config &configIn, uint64_t nSeed0In, uint64_t nSeed1In, + bool network_active) : config(&configIn), nSeed0(nSeed0In), nSeed1(nSeed1In) { SetTryNewOutboundPeer(false); Options connOptions; Init(connOptions); + SetNetworkActive(network_active); } NodeId CConnman::GetNewNodeId() { diff --git a/test/functional/feature_config_args.py b/test/functional/feature_config_args.py --- a/test/functional/feature_config_args.py +++ b/test/functional/feature_config_args.py @@ -127,11 +127,38 @@ ]) 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 run_test(self): self.stop_node(0) self.test_log_buffer() self.test_args_log() + self.test_networkactive() self.test_config_file_parser() diff --git a/test/functional/rpc_net.py b/test/functional/rpc_net.py --- a/test/functional/rpc_net.py +++ b/test/functional/rpc_net.py @@ -121,13 +121,15 @@ assert_equal(self.nodes[0].getnetworkinfo()['networkactive'], True) assert_equal(self.nodes[0].getnetworkinfo()['connections'], 2) - 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) - self.nodes[0].setnetworkactive(state=True) + with self.nodes[0].assert_debug_log(expected_msgs=['SetNetworkActive: true\n']): + self.nodes[0].setnetworkactive(state=True) # Connect nodes both ways. connect_nodes(self.nodes[0], self.nodes[1]) connect_nodes(self.nodes[1], self.nodes[0])