rpc: addpeeraddress: throw on invalid IP
What changed, and why it matters
This change tightens error handling in a Bitcoin Core RPC command called addpeeraddress. Previously, if you gave it a bad IP address it would silently return {"success": false}. Now it immediately throws a clear 'Invalid IP address' error, matching how similar commands already behave. This is a small usability and input-validation improvement, not a fix for an active security vulnerability.
No urgent action required. Treat as a minor hardening/usability improvement. Operators using addpeeraddress should note that invalid inputs now raise an RPC error instead of returning a JSON success:false object.
Security signals we found
Improved input validation and explicit error reporting for RPC addpeeraddress
Prevents silent failure (opaque success:false) on invalid IP/hostname input
Aligns addpeeraddress behavior with setban/addconnection error handling
Evidence from the diff
The commit modifies addpeeraddress in src/rpc/net.cpp to call LookupHost(addr_string, false) and throw RPC_CLIENT_INVALID_IP_OR_SUBNET (-30) when the lookup fails, before any addrman mutation occurs. The functional test is updated to assert the raised error for both empty and non-IP/hostname inputs. The change removes the prior behavior of returning {“success”: false} for invalid addresses and keeps the {success, error?} object strictly for addrman outcomes.
Changed components
src/rpc/net.cpp: addpeeraddress RPC handlertest/functional/rpc_net.py: addpeeraddress testsInspect captured patch +22 / −17
diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp
index fbb70d72..1f17aea1 100644
--- a/src/rpc/net.cpp
+++ b/src/rpc/net.cpp
@@ -1000,26 +1000,28 @@ static RPCHelpMan addpeeraddress()
UniValue obj(UniValue::VOBJ);
std::optional<CNetAddr> 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<NodeSeconds>();
- // 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<NodeSeconds>();
+ // 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 41ecbbed..4ca4a36f 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)
Why this scored 20/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.