Skip to main content

Module pointer

Module pointer 

Source
Expand description

Pointers — paid mutable references with an immutable owner.

A pointer is a mutable, owner-signed reference stored at an address derived from its owner’s public key. Unlike a DataChunk its address is not its content hash: the address is fixed for the pointer’s life while the bytes under it change with every update.

Ownership is fixed at creation. There is no transfer, no lineage, no certificates and no key rotation: a former owner keeps its key forever, so transferable ownership cannot be made fork-proof by a local rule. An earlier draft of this module implemented transfer through a genesis object and a chain of transfer certificates; it was reviewed and withdrawn. See ADR-0016 in ant-node.

That choice is what lets the design be this small: the owner key is inlined in the record, so validating a pointer needs nothing but the pointer — no fetch, no cache, no second close group, nothing that can be missing.

§Encoding

Encoded by hand: canonical, fixed-width, big-endian, no length prefixes and no serde. The signed payload must not depend on a serializer whose output can change — 1.0’s pointer called rmp_serde inside its signing routine and silently signed nothing when it failed.

format_version  1     byte
owner        1952     bytes   ML-DSA-65 public key
counter         8     bytes   big-endian u64
target         33     bytes   1-byte kind tag + 32-byte address, opaque here
signature    3309     bytes   ML-DSA-65 over the preceding 1994 bytes
            -----
             5303     bytes

§Identity

A        = BLAKE3::derive_key("autonomi.pointer.address.v1", owner)
state_id = BLAKE3::derive_key("autonomi.pointer.state.v1",   body)

Derive-key, not a hash of a prefix and the input. A chunk is addressed by a plain hash of its content, so a prefix would put both of these inside the chunk address space for anyone who could write the preimage down: squatting an owner’s address before they used it, or buying a pointer and a chunk with one payment. Both modes still produce 32 bytes, so the ranges overlap; what changed is that crossing them is the preimage problem BLAKE3 is assumed to resist.

A routes and decides which nodes are responsible. state_id names the authenticated state: it is what sync hints carry, what a fetch decision compares, and what a quote is paid against. They are separate because A must be stable for the pointer’s life while the paid identifier must change with every update, or updates after the first would be free — the defect this design exists to fix.

§What this module does not do

Payment verification, storage and replication. Those are the node’s job.

Structs§

ParsedPointer
Bytes that have been structurally parsed but not yet verified.
Pointer
A paid, mutable, owner-signed reference.
PointerState
The parts of a record that determine its authenticated state.
PointerTarget
A kind tag plus the address it refers to.

Enums§

PointerError
Why a pointer was refused.
PointerTargetKind
What a pointer points at, as clients interpret it.

Constants§

DATA_TYPE_POINTER
Data type identifier for pointers, alongside DATA_TYPE_CHUNK.
ML_DSA_65_PUBLIC_KEY_LEN
Length of a raw ML-DSA-65 public key.
ML_DSA_65_SIGNATURE_LEN
Length of a raw ML-DSA-65 signature.
POINTER_BODY_LEN
Length of the signed body: everything before the signature.
POINTER_FORMAT_VERSION
Wire format discriminator carried by every pointer.
POINTER_WIRE_LEN
Total size of an encoded pointer.
TARGET_WIRE_LEN
Length of an encoded PointerTarget: a kind tag plus an address.

Functions§

pointer_address
Derive a pointer address from an owner key.
state_id_for_body
Derive the authenticated-state identifier from a signed body.