From 316a0c513278d53cb25f42ea502d20691962aad6 Mon Sep 17 00:00:00 2001 From: John Moffett Date: Thu, 18 Sep 2025 14:02:21 -0400 Subject: [PATCH] rpc: addpeeraddress: throw on invalid IP Throw RPC_CLIENT_INVALID_IP_OR_SUBNET when LookupHost(addr, false) fails in addpeeraddress. This aligns with setban/addconnection and avoids the opaque {"success": false} result for input errors. The JSON {success, error?} object remains for addrman outcomes only. Update test to match. --- src/rpc/net.cpp | 34 ++++++++++++++++++---------------- test/functional/rpc_net.py | 5 ++++- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index fbb70d72161..1f17aea1151 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -1000,26 +1000,28 @@ static RPCHelpMan addpeeraddress() UniValue obj(UniValue::VOBJ); std::optional net_addr{LookupHost(addr_string, false)}; + if (!net_addr.has_value()) { + throw JSONRPCError(RPC_CLIENT_INVALID_IP_OR_SUBNET, "Invalid IP address"); + } + bool success{false}; - if (net_addr.has_value()) { - CService service{net_addr.value(), port}; - CAddress address{MaybeFlipIPv6toCJDNS(service), ServiceFlags{NODE_NETWORK | NODE_WITNESS}}; - address.nTime = Now(); - // The source address is set equal to the address. This is equivalent to the peer - // announcing itself. - if (addrman.Add({address}, address)) { - success = true; - if (tried) { - // Attempt to move the address to the tried addresses table. - if (!addrman.Good(address)) { - success = false; - obj.pushKV("error", "failed-adding-to-tried"); - } + CService service{net_addr.value(), port}; + CAddress address{MaybeFlipIPv6toCJDNS(service), ServiceFlags{NODE_NETWORK | NODE_WITNESS}}; + address.nTime = Now(); + // The source address is set equal to the address. This is equivalent to the peer + // announcing itself. + if (addrman.Add({address}, address)) { + success = true; + if (tried) { + // Attempt to move the address to the tried addresses table. + if (!addrman.Good(address)) { + success = false; + obj.pushKV("error", "failed-adding-to-tried"); } - } else { - obj.pushKV("error", "failed-adding-to-new"); } + } else { + obj.pushKV("error", "failed-adding-to-new"); } obj.pushKV("success", success); diff --git a/test/functional/rpc_net.py b/test/functional/rpc_net.py index 41ecbbed22d..4ca4a36f110 100755 --- a/test/functional/rpc_net.py +++ b/test/functional/rpc_net.py @@ -344,9 +344,12 @@ class NetTest(BitcoinTestFramework): assert "unknown command: addpeeraddress" not in node.help("addpeeraddress") self.log.debug("Test that adding an empty address fails") - assert_equal(node.addpeeraddress(address="", port=8333), {"success": False}) + assert_raises_rpc_error(-30, "Invalid IP address", node.addpeeraddress, address="", port=8333) assert_equal(node.getnodeaddresses(count=0), []) + self.log.debug("Test that adding a non-IP/hostname fails (no DNS lookup allowed)") + assert_raises_rpc_error(-30, "Invalid IP address", node.addpeeraddress, address="not_an_ip", port=8333) + self.log.debug("Test that non-bool tried fails") assert_raises_rpc_error(-3, "JSON value of type string is not of expected type bool", self.nodes[0].addpeeraddress, address="1.2.3.4", tried="True", port=1234)