Expand description
The signed payment address (SPEC §3.4) — how a peer says “pay my earnings here” in a way a third party can check.
§Why a signature is not optional here
Every other field of a PeerEntry is self-correcting: a wrong address simply
fails to dial, and the mTLS handshake proves identity on connect, so a lie costs the liar nothing
but is caught immediately. A payee field inverts that. PEX records are relayed, so an
unauthenticated payee means the incentive layer pays whoever last forwarded the record rather than
whoever earned it — and the victim never finds out, because a payment that succeeds looks
identical either way. An unauthenticated field naming a payee is a theft primitive, not a
convenience.
§The binding: the record proves itself, with no lookup
A DIG peer_id is defined as SHA-256(TLS SPKI DER). That makes a self-contained proof
available: the claim carries the peer’s SPKI DER, a verifier recomputes
SHA-256(SPKI) == peer_id, and then checks the signature over the canonical bytes against that
key. No directory, no resolution step, no second identity concept, and no new trust root — which
matters because the parties that most need to check a claim (relays, and any node that received
the record second- or third-hand) are exactly the parties least likely to have a resolution path.
§The canonical bytes (payment_signing_bytes)
"dig-pex/payment-address/v1\0"
|| u32be(len(peer_id)) || peer_id
|| u32be(len(network_id)) || network_id
|| u32be(len(address)) || addressDomain-separated (so a signature made for another DIG protocol cannot be replayed in here) and length-prefixed (so no concatenation of different field values can produce the same bytes).
What a valid signature therefore proves: the holder of the private key whose SPKI hashes to
peer_id designated this address as its payee on this network.
What it does NOT prove, and callers must not assume: that the peer is reachable, that it is
honest, that the address is well-formed or spendable, that the claim is recent (last_seen is
deliberately outside the signed bytes — see below), or that it has not been superseded by a newer
claim the verifier has not seen.
§Why last_seen is excluded
Including it would make every signature expire on the advertiser’s next heartbeat, forcing the advertised peer to re-sign continuously and the advertiser to re-request a signature it cannot produce itself — an availability dependency on the very peer the record exists to route around. Excluding it makes the claim a durable, cacheable, relayable credential, at the stated cost that a revoked address stays verifiable until the peer’s newer claim propagates. Superseding a claim is therefore the incentive layer’s concern (prefer the claim on the freshest first-hand record), not this signature’s.
Structs§
- Payment
Claim - A peer’s self-signed designation of where to pay it (SPEC §3.4).
Enums§
- Payment
Claim Error - Why a claim did not yield a payment address. Every variant means the same thing to a caller — there is no payee here — and they differ only in what to log.
Constants§
- PEX_
MAX_ PAYMENT_ ADDRESS_ LEN - Maximum characters in a payment address (SPEC §3.4.2). A Chia bech32m address is 62 characters; the headroom accommodates longer address forms without leaving the field unbounded to a hostile sender.
- PEX_
MAX_ PAYMENT_ SIG_ LEN - Maximum characters in the base64
sigfield. An ASN.1 DER P-256 signature is at most 72 bytes (96 base64 characters). - PEX_
MAX_ PAYMENT_ SPKI_ LEN - Maximum characters in the base64
spkifield. An ECDSA P-256 SPKI DER is 91 bytes (124 base64 characters); the headroom covers other key types without unbounding the field.
Traits§
- Signature
Verifier - The signature-verification capability a caller injects (SPEC §3.4.3).
Functions§
- payment_
signing_ bytes - The exact bytes a peer signs to designate
addressas its payee (SPEC §3.4.1). Identical when signing and when verifying — never construct these bytes anywhere else. - peer_
id_ for_ spki - The
peer_ida TLS SPKI induces —SHA-256(SPKI DER)as 64 lowercase hex characters, the same derivationdig-tlsperforms on connect. This is the function that turns a carried key into a checkable claim of identity.