tag

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Oct 19, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Index

Constants

View Source
const (
	TagSpecLegacy int64 = 0
	TagSpecV1     int64 = 1
)

Tag specification versions recorded with a chain (docs/verification.md). TagSpecLegacy is a chain whose executor did not report debuglet-tag-v1 when it registered the chain: it predates tag spec v1 and tags with the earlier, non-standard tag, which verifiers treat as unsupported. TagSpecV1 is debuglet-tag-v1 (docs/tag-spec.md).

Variables

This section is empty.

Functions

func ChainID added in v0.3.0

func ChainID(anchor []byte) string

ChainID returns the public identifier of the chain with the given anchor k_0: the lowercase hex of the first 16 bytes of SHA-256(k_0). It is empty for an empty anchor.

func TagSpecOf added in v0.3.0

func TagSpecOf(tagging *wire.TaggingMode) int64

TagSpecOf returns the recorded tag specification version of the tagging an executor reports: TagSpecV1 for wire.TagSpecV1, and TagSpecLegacy for an absent report, an absent or unknown identifier.

Types

type Backend added in v0.3.0

type Backend interface {
	Save(executorID string, chain Chain, epoch int64, key []byte, at time.Time) error
	Latest(executorID string, anchor []byte) (epoch int64, key []byte, ok bool, err error)
	Get(executorID string, anchor []byte, epoch int64) (key []byte, ok bool, err error)
}

Backend is the durable record a KeyStore caches. Save is called once for each disclosure that verified, before the cache holds it; Latest and Get read the record for a chain the cache does not hold. A Backend must store a key at most once per (executor, chain, epoch) and keep the first.

type Chain added in v0.3.0

type Chain struct {
	Anchor          []byte
	Start           time.Time
	Interval        time.Duration
	DisclosureDelay int64
	// Length is L, the number of epochs the chain serves; zero is unknown.
	// It is recorded with the chain and does not bound a disclosure.
	Length int64
	// TagSpec is the tag specification version the executor reported when it
	// registered the chain (TagSpecLegacy or TagSpecV1). It is recorded with
	// the chain and does not affect key verification.
	TagSpec int64
}

Chain names the key chain a disclosure belongs to: its public anchor k_0 and the schedule the executor registered with it. Epoch i starts at Start + i*Interval, and its key may be disclosed from the start of epoch i+DisclosureDelay. A zero Interval means the schedule is unknown; only the absolute walk bound then limits a disclosure's epoch. A zero DisclosureDelay is an executor that predates it and discloses after one epoch.

func (Chain) DisclosableAt added in v0.3.0

func (c Chain) DisclosableAt(epoch int64) (time.Time, bool)

DisclosableAt returns when the key of epoch i may first be disclosed: the start of epoch i+d. ok is false while the schedule is unknown.

func (Chain) DueEpoch added in v0.3.0

func (c Chain) DueEpoch(now time.Time) (int64, bool)

DueEpoch returns the highest epoch whose key an honest executor must have disclosed by now: the epoch in progress at now less the disclosure delay d, without the clockSkew allowance Store grants, and at most L-1 when the chain length is known. ok is false while the schedule is unknown; a result below one means no key is due yet.

type KeyStore

type KeyStore struct {
	// contains filtered or unexported fields
}

KeyStore stores disclosed TESLA keys for retroactive packet verification. Keys are indexed by (executor_id, chain anchor, epoch). An empty anchor is the chain of an executor that published none. Without a Backend the store is memory only; with one, it is a cache over the durable record, and a chain that is not cached resumes from the latest key on record.

func NewKeyStore

func NewKeyStore() *KeyStore

func NewPersistentKeyStore added in v0.3.0

func NewPersistentKeyStore(backend Backend) *KeyStore

NewPersistentKeyStore returns a KeyStore that records every verified disclosure in backend and caches it in memory.

func (*KeyStore) CachedLatest added in v0.3.0

func (ks *KeyStore) CachedLatest(executorID string, anchor []byte) (epoch int64, cached bool)

CachedLatest returns the highest verified and recorded epoch of the chain of executorID with the given anchor as the cache holds it: zero when none yet. cached is false when the cache does not hold the chain, which it starts to on the chain's first disclosure in this process. It reads no Backend and creates no cache entry.

func (*KeyStore) DurableThrough added in v0.3.0

func (ks *KeyStore) DurableThrough(executorID string, anchor []byte) (int64, bool)

DurableThrough returns cached verified coverage backed by a successful durable write (or read of that record). Memory-only stores cannot acknowledge durable delivery. It performs no I/O and a cache miss is unknown.

func (*KeyStore) Get

func (ks *KeyStore) Get(executorID string, anchor []byte, epoch int64) ([]byte, bool)

Get retrieves a key disclosed on the chain with the given anchor. A key the cache does not hold is read from the Backend, if any.

func (*KeyStore) LatestDisclosed

func (ks *KeyStore) LatestDisclosed(executorID string, anchor []byte) (epoch int64, key []byte, ok bool)

LatestDisclosed returns the epoch index and key of the most recently disclosed key on the chain of executorID with the given anchor. ok is false if no key of that chain has been stored yet. A chain the cache does not hold is answered from the Backend, if any.

func (*KeyStore) PrintKeys

func (ks *KeyStore) PrintKeys()

func (*KeyStore) Store

func (ks *KeyStore) Store(executorID string, chain Chain, now time.Time, epoch int64, key []byte) error

Store saves a key disclosed at now on the given chain once it verifies against the chain: H^(epoch-l)(key) must equal the last verified key k_l, or the anchor k_0 when none is stored yet. An epoch ahead of what the chain's schedule allows at now (see Chain) is rejected before any hashing, which bounds the work one heartbeat can cause. Disclosures are monotonic: an epoch below the latest is ignored, a repeat of a stored key is a no-op, and a different key for a stored epoch is rejected. An empty key is no disclosure. A rejection returns a *RejectedError and stores nothing.

type RejectedError added in v0.3.0

type RejectedError struct {
	Epoch  int64
	Reason string
	First  bool
	Early  bool
}

RejectedError reports a disclosure that was not stored because it does not extend its chain. First is set for the first rejection on that chain, so a caller can log a misbehaving executor once rather than on every heartbeat; early disclosures count separately, so the first is logged even after another rejection. Early is set when the key was disclosed before its schedule allows: that is evidence of a misbehaving executor, since anyone who saw the key could forge tags for packets verifiers still attribute to its epoch.

func (*RejectedError) Error added in v0.3.0

func (e *RejectedError) Error() string

Jump to

Keyboard shortcuts

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