pub fn canonical_peer_ip(raw: &str) -> Result<String, ControlError>Expand description
The CANONICAL textual form of a Chia peer address, or an INVALID_PARAMS error.
Every ip this crate declares — in control.chiaPeers.add / .remove params and in every
result that echoes one — is a bare IP literal in this form. A conforming node MUST canonicalise
through this function on the way IN and store the result, so add, remove and list all
spell the same peer the same way.
Why the contract owns this rather than each implementation. remove is the only way to
un-trust a peer that is believed WITHOUT corroboration, and it matches by address. If the form
is left to the implementation, an operator who adds 2001:db8::1 and removes 2001:DB8:0:0::1
has named the same peer twice and un-trusted nothing — an un-trust that silently does not
happen. Canonicalising is what makes the two spellings one key.
The rules, normatively:
- the value MUST parse as an IPv4 or IPv6 literal (
std::net::IpAddr). A hostname, an empty string, anip:port, a CIDR block or a bracketed[..]form is REJECTED. Rejecting non-literals is also what bounds the ban list:remove {ban: true}persists a row keyed by this string, so an unvalidated key is unbounded at-rest growth driven by one small call; - surrounding whitespace is trimmed before parsing, and nothing else is;
- the canonical rendering is
std::net::IpAddr’s ownDisplay— dotted-quad for v4, and for v6 the RFC 5952 lowercase, maximally-compressed form, WITHOUT brackets and WITHOUT a zone id.
Bracketing belongs to the socket-address form, never to this field: see
chia_peer_endpoint, which is the ONLY sanctioned way to join an ip to a port.
use dig_node_control_interface::params::canonical_peer_ip;
assert_eq!(canonical_peer_ip(" 2001:0DB8:0000::1 ").unwrap(), "2001:db8::1");
assert!(canonical_peer_ip("[::1]").is_err());
assert!(canonical_peer_ip("node.example.com").is_err());