record

package
v0.3.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 29, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Overview

Package record is the committed record: the state document a carrier transaction carries.

The deterministic CBOR it is written in is package cbor of github.com/lightwebinc/bcommon, which every record-shaped application shares. The names in this file re-export that codec so the record's callers do not change with it: the types are aliases, so a record.Map is a cbor.Map with its methods, and each sentinel is the codec's own value, so errors.Is matches under either name and the refusal texts stay the codec's. A refusal that names a Go type still spells it record.Map, record.Pair or record.Value; see typeName.

The refs entries a record commits to its stores through, and the manifest a store is read through, are package store beside it. Their names are re-exported the same way, except that a store refusal is reworded onto record's own sentinel with the rest of its text unchanged, so a reader's refusal reason reads as it did when this package decoded both itself.

Index

Constants

View Source
const (
	KindCreate uint8 = 1
	KindUpdate uint8 = 2
	KindRotate uint8 = 3
	KindRetire uint8 = 4
	// KindSub is a sub-record: a store member the primary record commits to
	// through refs. It has a create's shape (seq 1, zero prev, no witness
	// reveal) and is never a transition: a host indexes it and answers it by
	// its commitment, and never advances an identity's chain on it. Without
	// its own kind a sub-record would be a second create for the identity,
	// which is refused live and, on a restart that replays carriers by
	// sequence (ties by commitment), could win the chain start and orphan every real
	// transition behind it.
	KindSub uint8 = 5
	// KindManifest is a store's manifest: a sub-record whose body lists the
	// store's members in order. It is the head of a store of more than one
	// member and is not itself a member, so the store's root is over what it
	// lists and not over it. Its own kind rather than a sub-record's, so that
	// "the thing at the head is a manifest" is something a reader checks
	// rather than infers from the count, and so that it stays visible when
	// the body is sealed.
	KindManifest uint8 = 6
)

Kinds of transition.

View Source
const (
	MaxRefMembers = store.MaxRefMembers
	MaxRefs       = store.MaxRefs
	MaxMembers    = store.MaxMembers
	MaxRefName    = store.MaxRefName
)

Store bounds; store says why each is what it is.

View Source
const MaxBodyBytes = 16384

MaxBodyBytes bounds the encoded body. A profile is delivered to every subscribed host and billed by the byte; an unbounded body is somebody else's bandwidth. 16 KiB holds a multi-line plan with room to spare; a record that needs more belongs in a sub-store under refs.

View Source
const MaxDepth = cbor.MaxDepth

MaxDepth bounds nesting; cbor.MaxDepth says why sixteen.

View Source
const MaxSubBodyBytes = 65536

MaxSubBodyBytes bounds the encoded body of a sub-record or a manifest. A record is delivered to every reader of the identity; a sub-store is fetched only by a reader that wants it, so it can carry more. The number is a function of the plane's minimum path MTU rather than a preference: at the 1280-byte IPv6 floor a 64 KiB object is 59 fragments, and one object in eighteen needs a repair round at a healthy loss rate, which is where that curve turns. It rises when the plane's minimum path rises.

View Source
const MemberKey = store.MemberKey

MemberKey is the body key a manifest's member list lives under.

Variables

View Source
var (
	ErrNotCanonical = cbor.ErrNotCanonical
	ErrUnsupported  = cbor.ErrUnsupported
	ErrTruncated    = cbor.ErrTruncated
	ErrTrailing     = cbor.ErrTrailing
	ErrDepth        = cbor.ErrDepth
	ErrDuplicateKey = cbor.ErrDuplicateKey
	ErrKeyOrder     = cbor.ErrKeyOrder
	ErrUTF8         = cbor.ErrUTF8
)
View Source
var (
	ErrShape    = errors.New("record: not a record")
	ErrMagic    = errors.New("record: unknown magic")
	ErrMissing  = errors.New("record: required field missing")
	ErrField    = errors.New("record: field has the wrong shape")
	ErrBodySize = errors.New("record: body exceeds bound")
	ErrKind     = errors.New("record: kind and fields disagree")
	ErrWindow   = errors.New("record: notBefore is after notAfter")
	ErrDupRef   = errors.New("record: two refs entries name the same store")
)
View Source
var (
	// ErrNotManifest is a body that is not a member list.
	ErrNotManifest = errors.New("record: not a manifest body")
	// ErrMemberCount is a manifest with no members or more than MaxMembers.
	ErrMemberCount = errors.New("record: manifest member count out of range")
)
View Source
var MagicV1 = [4]byte{'b', 'f', 'r', 0x01}

MagicV1 is the record's leading field: "bfr" and version 1.

View Source
var MemberOverhead = store.MemberOverhead

MemberOverhead is the encoded cost of one manifest member excluding its name and type.

Functions

func BodyBound

func BodyBound(kind uint8) int

BodyBound is the encoded-body bound for a kind: a sub-record and a manifest get MaxSubBodyBytes, everything that is a transition gets MaxBodyBytes.

func Encode

func Encode(v Value) ([]byte, error)

Encode writes v in core deterministic encoding.

Types

type Manifest

type Manifest store.Manifest

Manifest is a store's member list. It is a type of its own rather than an alias so that its Body carries this application's bound and its refusals read as record's.

func ParseManifest

func ParseManifest(body Map) (*Manifest, error)

ParseManifest reads a manifest out of a record body. It is deliberately strict: a body with anything else in it is not a manifest, because a manifest's body is the whole of what that record is for.

func (*Manifest) Body

func (m *Manifest) Body() (Map, error)

Body encodes the manifest as the body of a KindManifest record, refusing one that will not fit under MaxSubBodyBytes.

func (*Manifest) Leaves

func (m *Manifest) Leaves() [][32]byte

Leaves is the member commitments in order, which is what the store's root is computed over.

type Map

type Map = cbor.Map

type Member

type Member = store.Member

Member is one entry of a manifest.

type Pair

type Pair = cbor.Pair

type Record

type Record struct {
	Magic       [4]byte
	IdentityKey [33]byte
	Seq         uint64
	Kind        uint8
	Prev        [32]byte
	Salt        [32]byte
	WC          [32]byte
	PrevWitness *[32]byte
	NotBefore   uint64
	NotAfter    uint64
	Body        Map
	Refs        []Ref
	Successor   *[33]byte
	Unknown     Map
}

Record is the state document. Fixed-width fields are arrays; optional ones are pointers; Body keys are text; Unknown carries every integer key this version does not define, verbatim, so a re-encode by an older reader never drops a newer field.

func Decode

func Decode(b []byte) (*Record, error)

Decode parses canonical bytes into a Record, checking every defined field's shape and preserving undefined keys. It does not apply the transition rules; call Validate for those.

func (*Record) Encode

func (r *Record) Encode() ([]byte, error)

Encode writes the record in canonical CBOR, checking shape but not the transition rules (see Validate), so a partially built record can still be serialised for a test or a golden.

func (*Record) Validate

func (r *Record) Validate() error

Validate applies the transition rules a record must satisfy on its own, without the previous record: the fields a kind requires, the validity window, and a sequence that starts at one.

type Ref

type Ref = store.Ref

Ref names a sub-store and commits to it; see store.Ref.

type Value

type Value = cbor.Value

func DecodeValue

func DecodeValue(b []byte) (Value, error)

DecodeValue parses exactly one canonical item and refuses trailing bytes.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL