Expand description
§TransportOwnershipProof — proving and verifying control of an announced address
Hashiverse peers announce themselves by address; before today, nothing in the
announce wire format proved the announcer actually controlled that address. A
peer with broken TLS / no cert could still announce, get into Kademlia, and
pollute peer lists until every receiver independently RPCed it and pruned. The
crate::protocol::payload::payload::AnnounceV2 variant fixes that by carrying an
opaque proof byte blob next to peer_self; the receiver decides whether to
admit the peer based on whether the proof verifies.
The shape of “a proof” depends on the transport. This module defines the
interface; concrete impls live alongside each TransportServer:
- HTTPS transport (
hashiverse-server-lib::HttpsTransportOwnershipProof): serialises the server’s current ACME-issued TLS chain plus a binding signature tying the chain topeer_self.id; verification is offline X.509 path validation against the bundled Mozilla NSS roots (seecrate::tools::cert_validation::is_cert_valid) plus binding-signature check. - Mem transport: an empty marker accepted by an empty-marker verifier; tests can exercise the V2 path end-to-end without real certs.
Wrong-transport mismatches surface naturally: if peer X sends bytes that
transport Y’s verifier can’t deserialise, TransportOwnershipProof::prove
returns false. No discriminator field needed on the wire.
TransportServer::get_transport_ownership_proof hands out one
Arc<dyn TransportOwnershipProof> per server. The default trait impl returns a
reject-all placeholder so old TransportServer impls keep compiling; real
transports override it.
Structs§
- Empty
Marker Ownership Proof - Empty-marker ownership proof, shared by transports that don’t (and can’t) cryptographically
model address ownership: the in-memory test transport and the plain-TCP transport used for
local-LAN / private-network deployments. Both ends agree on the empty byte string as the
“I’m a trusted-network peer” token. An HTTPS-shaped proof byte blob sent to one of these
servers fails the
is_empty()check; conversely an empty-marker proof sent to an HTTPS server fails its postcard decode (oris_cert_validon an empty chain). Cross-transport announces fall through naturally without a discriminator field on the wire. - Reject
AllTransport Ownership Proof - Reject-all placeholder used as the default for
TransportServerimpls that haven’t been taught about ownership proofs yet (notably the wasm / TCP transports during the V2 rollout). It cannot produce a proof and rejects every inbound proof — safe by default: peers using this transport won’t be admitted to Kademlia via V2, and we never accidentally accept somebody else’s proof we don’t understand.
Traits§
- Transport
Ownership Proof - A per-transport rule for producing our own proof bytes (announce-out) and verifying
other peers’ proof bytes (announce-in). A single
Arc<dyn TransportOwnershipProof>lives on aTransportServerand is used for both directions.