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 ¶
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.
const ( MaxRefMembers = store.MaxRefMembers MaxRefs = store.MaxRefs MaxMembers = store.MaxMembers MaxRefName = store.MaxRefName )
Store bounds; store says why each is what it is.
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.
const MaxDepth = cbor.MaxDepth
MaxDepth bounds nesting; cbor.MaxDepth says why sixteen.
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.
const MemberKey = store.MemberKey
MemberKey is the body key a manifest's member list lives under.
Variables ¶
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 )
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") )
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") )
var MagicV1 = [4]byte{'b', 'f', 'r', 0x01}
MagicV1 is the record's leading field: "bfr" and version 1.
var MemberOverhead = store.MemberOverhead
MemberOverhead is the encoded cost of one manifest member excluding its name and type.
Functions ¶
Types ¶
type 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 ¶
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.
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 ¶
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.