diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index ba1080ed11f..382e4d5604e 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -47,6 +47,7 @@ using node::NodeContext; using util::Join; +using util::TrimStringView; const std::vector CONNECTION_TYPE_DOC{ "outbound-full-relay (default automatic connections)", @@ -348,6 +349,11 @@ static RPCMethod addnode() CConnman& connman = EnsureConnman(node); const auto node_arg{self.Arg("node")}; + if (TrimStringView(node_arg).empty()) { + // Such a node would never resolve, but would be retried indefinitely. + throw JSONRPCError(RPC_INVALID_PARAMETER, "Error: Node address cannot be empty"); + } + bool node_v2transport = connman.GetLocalServices() & NODE_P2P_V2; bool use_v2transport = self.MaybeArg("v2transport").value_or(node_v2transport); diff --git a/test/functional/rpc_net.py b/test/functional/rpc_net.py index 81cf4da78db..8d1bc244dc4 100755 --- a/test/functional/rpc_net.py +++ b/test/functional/rpc_net.py @@ -272,6 +272,11 @@ class NetTest(BitcoinTestFramework): assert_equal(added_nodes[0]['addednode'], "11.22.33.44") self.log.info("Check that an invalid command returns an error") assert_raises_rpc_error(-1, 'addnode "node" "command"', self.nodes[0].addnode, node=ip_port, command='abc') + self.log.info("Check that an empty node address returns an error") + for command in ['add', 'remove', 'onetry']: + assert_raises_rpc_error(-8, "Node address cannot be empty", self.nodes[0].addnode, node="", command=command) + assert_raises_rpc_error(-8, "Node address cannot be empty", self.nodes[0].addnode, node=" ", command=command) + assert_equal(len(self.nodes[0].getaddednodeinfo()), 1) self.log.info("Check that trying to remove the node again returns an error") assert_raises_rpc_error(-24, "Node could not be removed", self.nodes[0].addnode, node=ip_port, command='remove') self.log.info("Check that a non-existent node returns an error")