trie

package
v0.0.0-...-2b1eae4 Latest Latest
Warning

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

Go to latest
Published: Sep 13, 2022 License: Apache-2.0 Imports: 14 Imported by: 8

README

Package trie256p

Package contain implementation of generic trie256+. It essentially follows 256+ trie. Definition.

Documentation

Overview

Package trie implements functionality of generic verkle trie with 256 child commitment in each node + Terminal commitment + commitment to the path fragment: 258 commitments in total. It mainly follows the definition from https://hackmd.io/@Evaldas/H13YFOVGt (except commitment to the path fragment) The commitment to the path fragment is needed to provide proofs of absence of keys

The specific implementation of the commitment model is presented as a CommitmentModel interface

Index

Constants

View Source
const (
	PathArity256 = PathArity(255)
	PathArity16  = PathArity(15)
	PathArity2   = PathArity(1)
)
View Source
const (
	EndingTerminal = iota
	EndingSplit
	EndingExtend
)

Variables

View Source
var (
	ErrWrongNibble      = errors.New("key16 byte must be less than 0x0F")
	ErrEmpty            = errors.New("encoded key16 can't be empty")
	ErrWrongFormat      = errors.New("encoded key16 wrong format")
	ErrWrongBinaryValue = errors.New("key2 byte must be 1 or 0")
	ErrWrongArity       = errors.New("arity value must be 1, 15 or 255")
)
View Source
var (
	ErrNotAllBytesConsumed = xerrors.New("serialization error: not all bytes were consumed")
)

Functions

func Assert

func Assert(cond bool, format string, p ...interface{})

Assert simple assertion with message formatting

func Blake2b160

func Blake2b160(data []byte) (ret [20]byte)

func ByteSize

func ByteSize(s KVIterator) int

ByteSize computes byte size of the serialized key/value iterator assumes 2 bytes per key length and 4 bytes per value length

func CheckNils

func CheckNils(i1, i2 interface{}) (bool, bool)

CheckNils returns (conclusive comparison result, true) if at least one is nil return (false, false) if both are not nil and can both be safely dereferenced

func Concat

func Concat(par ...interface{}) []byte

Concat concatenates bytes of byte-able objects

func DangerouslyDumpToConsole

func DangerouslyDumpToConsole(title string, r KVIterator)

func DecodeToUnpackedBytes

func DecodeToUnpackedBytes(encoded []byte, arity PathArity) ([]byte, error)

func DumpToFile

func DumpToFile(r KVIterator, fname string) (int, error)

DumpToFile serializes iterator to the file in binary form. The content of the file in general is non-deterministic due to the random order of iteration

func EncodeUnpackedBytes

func EncodeUnpackedBytes(unpacked []byte, arity PathArity) ([]byte, error)

func MustBytes

func MustBytes(o interface{ Write(w io.Writer) error }) []byte

MustBytes most common way of serialization

func MustSize

func MustSize(o interface{ Write(w io.Writer) error }) int

MustSize calculates byte size of the serializable object

func MustUint32From4Bytes

func MustUint32From4Bytes(b []byte) uint32

func NumEntries

func NumEntries(s KVIterator) int

NumEntries calculates number of key/value pair in the iterator

func PackUnpackedBytes

func PackUnpackedBytes(unpacked []byte, arity PathArity) ([]byte, error)

func ReadByte

func ReadByte(r io.Reader) (byte, error)

func ReadBytes16

func ReadBytes16(r io.Reader) ([]byte, error)

func ReadBytes32

func ReadBytes32(r io.Reader) ([]byte, error)

func ReadBytes8

func ReadBytes8(r io.Reader) ([]byte, error)

func ReadUint16

func ReadUint16(r io.Reader, pval *uint16) error

func ReadUint32

func ReadUint32(r io.Reader, pval *uint32) error

func Size

func Size(o interface{ Write(w io.Writer) error }) (int, error)

Size calculates byte size of the serializable object

func ToString

func ToString(n Node) string

func Uint16From2Bytes

func Uint16From2Bytes(b []byte) (uint16, error)

func Uint16To2Bytes

func Uint16To2Bytes(val uint16) []byte

func Uint32From4Bytes

func Uint32From4Bytes(b []byte) (uint32, error)

func Uint32To4Bytes

func Uint32To4Bytes(val uint32) []byte

func UnDumpFromFile

func UnDumpFromFile(w KVWriter, fname string) (int, error)

UnDumpFromFile restores dumped set of key/value pairs into the key/value writer

func UnpackBytes

func UnpackBytes(src []byte, arity PathArity) []byte

func WriteByte

func WriteByte(w io.Writer, val byte) error

func WriteBytes16

func WriteBytes16(w io.Writer, data []byte) error

func WriteBytes32

func WriteBytes32(w io.Writer, data []byte) error

func WriteBytes8

func WriteBytes8(w io.Writer, data []byte) error

func WriteUint16

func WriteUint16(w io.Writer, val uint16) error

func WriteUint32

func WriteUint32(w io.Writer, val uint32) error

Types

type BinaryStreamFileIterator

type BinaryStreamFileIterator struct {
	*BinaryStreamIterator
	// contains filtered or unexported fields
}

func OpenKVStreamFile

func OpenKVStreamFile(fname string) (*BinaryStreamFileIterator, error)

OpenKVStreamFile opens existing file with key/value stream for reading

func (*BinaryStreamFileIterator) Close

func (fs *BinaryStreamFileIterator) Close() error

type BinaryStreamFileWriter

type BinaryStreamFileWriter struct {
	*BinaryStreamWriter
	// contains filtered or unexported fields
}

func CreateKVStreamFile

func CreateKVStreamFile(fname string) (*BinaryStreamFileWriter, error)

CreateKVStreamFile create a new BinaryStreamFileWriter

func (*BinaryStreamFileWriter) Close

func (fw *BinaryStreamFileWriter) Close() error

type BinaryStreamIterator

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

func NewBinaryStreamIterator

func NewBinaryStreamIterator(r io.Reader) *BinaryStreamIterator

func (BinaryStreamIterator) Iterate

func (b BinaryStreamIterator) Iterate(fun func(k []byte, v []byte) bool) error

type BinaryStreamWriter

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

func NewBinaryStreamWriter

func NewBinaryStreamWriter(w io.Writer) *BinaryStreamWriter

func (*BinaryStreamWriter) Stats

func (b *BinaryStreamWriter) Stats() (int, int)

func (*BinaryStreamWriter) Write

func (b *BinaryStreamWriter) Write(key, value []byte) error

type CommitmentModel

type CommitmentModel interface {
	// PathArity is used by implementations to optimize operations
	PathArity() PathArity
	// EqualCommitments compares two commitments
	EqualCommitments(c1, c2 Serializable) bool
	// NewVectorCommitment creates empty trie_go.VCommitment
	NewVectorCommitment() VCommitment
	// NewTerminalCommitment creates empty trie_go.TCommitment
	NewTerminalCommitment() TCommitment
	// CommitToData calculates terminal commitment to an arbitrary data
	CommitToData([]byte) TCommitment
	// CalcNodeCommitment calculates commitment of the node data
	CalcNodeCommitment(*NodeData) VCommitment
	// UpdateNodeCommitment updates mutable NodeData with the update information.
	// It also (optionally, if 'update' != nil) updates previous commitment to the node
	// If update != nil and *update != nil, parameter calcDelta specifies if commitment is calculated
	// from scratch using CalcNodeCommitment, or it can be calculated by applying additive delta
	// I can be used by implementation to optimize the computation of update. For examples KZG implementation
	// can be made dramatically faster this way than strictly computing each time whole expensive vector commitment
	// This interface takes into account different ways how updates are propagated in the trie
	UpdateNodeCommitment(mutate *NodeData, childUpdates map[byte]VCommitment, calcDelta bool, terminal TCommitment, update *VCommitment)
	// ForceStoreTerminalWithNode if == true, terminal commitment will always be serialized with the node,
	// otherwise it may be skipped to optimize storage, depending on the trie setting
	ForceStoreTerminalWithNode(c TCommitment) bool
	// Description return description of the implementation
	Description() string
	// ShortName short name
	ShortName() string
}

CommitmentModel abstracts 256+ Trie logic from the commitment logic/cryptography

type KVBatchedUpdater

type KVBatchedUpdater interface {
	Update(key, value []byte)
	Commit() error
}

KVBatchedUpdater collects mutations in the buffer then flushes it at once

type KVIterator

type KVIterator interface {
	Iterate(func(k, v []byte) bool)
}

KVIterator is an interface to iterate through a set of key/value pairs. Order of iteration is NON-DETERMINISTIC in general

type KVReader

type KVReader interface {
	// Get retrieves value by key. Returned nil means absence of the key
	Get(key []byte) []byte
	// Has checks presence of the key in the key/value store
	Has(key []byte) bool // for performance
}

KVReader is a key/value reader

type KVStore

type KVStore interface {
	KVReader
	KVWriter
	KVIterator
}

KVStore is a compound interface

func NewInMemoryKVStore

func NewInMemoryKVStore() KVStore

type KVStreamIterator

type KVStreamIterator interface {
	Iterate(func(k, v []byte) bool) error
}

KVStreamIterator is an interface to iterate stream In general, order is non-deterministic

type KVStreamWriter

type KVStreamWriter interface {
	// Write writes key/value pair
	Write(key, value []byte) error
	// Stats return num k/v pairs and num bytes so far
	Stats() (int, int)
}

KVStreamWriter represents an interface to write a sequence of key/value pairs

type KVWriter

type KVWriter interface {
	// Set writes new or updates existing key with the value.
	// value == nil means deletion of the key from the store
	Set(key, value []byte)
}

KVWriter is a key/value writer

type Node

type Node interface {
	// Key of the node
	Key() []byte
	// PathFragment of the node (committed)
	PathFragment() []byte
	// Terminal of the node (committed)
	Terminal() TCommitment
	// ChildCommitments can return old commitments if node is not committed
	ChildCommitments() map[byte]VCommitment
}

Node is a read-only interface to the 256+ trie node

type NodeData

type NodeData struct {
	PathFragment     []byte
	ChildCommitments map[byte]VCommitment
	Terminal         TCommitment
}

NodeData contains all data trie node needs to compute commitment

func NewNodeData

func NewNodeData() *NodeData

func NodeDataFromBytes

func NodeDataFromBytes(model CommitmentModel, data, unpackedKey []byte, arity PathArity, valueStore KVReader) (*NodeData, error)

func (*NodeData) Clone

func (n *NodeData) Clone() *NodeData

Clone deep copy

func (*NodeData) Read

func (n *NodeData) Read(r io.Reader, model CommitmentModel, unpackedKey []byte, arity PathArity, valueStore KVReader) error

Read deserialize node data

func (*NodeData) String

func (n *NodeData) String() string

func (*NodeData) Write

func (n *NodeData) Write(w io.Writer, arity PathArity, isKeyCommitment bool, skipTerminal bool) error

Write serialized node data

type NodeStore

type NodeStore interface {
	GetNode(unpackedKey []byte) (Node, bool)
	Model() CommitmentModel
	PathArity() PathArity
	Info() string
}

NodeStore is an interface to TrieReader to the trie as a set of TrieReader represented as unpackedKey/value pairs Two implementations: - TrieReader is a direct, non-cached TrieReader to unpackedKey/value storage - Trie implement a cached TrieReader

type PathArity

type PathArity byte

func (PathArity) IsChildIndex

func (a PathArity) IsChildIndex(i int) bool

func (PathArity) NumChildren

func (a PathArity) NumChildren() int

func (PathArity) PathFragmentCommitmentIndex

func (a PathArity) PathFragmentCommitmentIndex() int

func (PathArity) String

func (a PathArity) String() string

func (PathArity) TerminalCommitmentIndex

func (a PathArity) TerminalCommitmentIndex() int

func (PathArity) VectorLength

func (a PathArity) VectorLength() int

type ProofEndingCode

type ProofEndingCode byte

func (ProofEndingCode) String

func (e ProofEndingCode) String() string

type ProofGeneric

type ProofGeneric struct {
	Key    []byte
	Path   [][]byte
	Ending ProofEndingCode
}

ProofGeneric represents a generic proof of inclusion or a maximal path in the trie which corresponds to the 'unpackedKey' The Ending indicates what represent the proof: it can be either 'proof of inclusion' of a unpackedKey/value Terminal, or a reorg code, which means what operation on the trie must be performed in order to update the unpackedKey/value pair

func GetProofGeneric

func GetProofGeneric(tr NodeStore, unpackedKey []byte) *ProofGeneric

GetProofGeneric returns generic proof path. Contains references trie node cache. Should be immediately converted into the specific proof model independent of the trie Normally only called by the model

func (*ProofGeneric) String

func (p *ProofGeneric) String() string

type RandStreamIterator

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

func NewRandStreamIterator

func NewRandStreamIterator(p ...RandStreamParams) *RandStreamIterator

func (*RandStreamIterator) Iterate

func (r *RandStreamIterator) Iterate(fun func(k []byte, v []byte) bool) error

type RandStreamParams

type RandStreamParams struct {
	// Seed for deterministic randomization
	Seed int64
	// NumKVPairs maximum number of key value pairs to generate. 0 means infinite
	NumKVPairs int
	// MaxKey maximum length of key (randomly generated)
	MaxKey int
	// MaxValue maximum length of value (randomly generated)
	MaxValue int
}

RandStreamParams represents parameters of the RandStreamIterator

type Serializable

type Serializable interface {
	Read(r io.Reader) error
	Write(w io.Writer) error
	Bytes() []byte
	String() string
}

Serializable is a common interface for serialization of commitment data

type TCommitment

type TCommitment interface {
	Clone() TCommitment
	Serializable
}

TCommitment represents commitment to the terminal data. Usually it is a hash of the data of a scalar field element

type Trie

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

Trie is an updatable trie implemented on top of the unpackedKey/value store. It is virtualized and optimized by caching of the trie update operation and keeping consistent trie in the cache

func New

func New(model CommitmentModel, trieStore, valueStore KVReader, optimizeKeyCommitments ...bool) *Trie

func (*Trie) ClearCache

func (tr *Trie) ClearCache()

ClearCache clears the node cache

func (*Trie) Clone

func (tr *Trie) Clone() *Trie

Clone is a deep copy of the trie, including its buffered data

func (*Trie) Commit

func (tr *Trie) Commit()

Commit calculates a new root commitment value from the cache and commits all mutations in the cached TrieReader It is a re-calculation of the trie. bufferedNode caches are updated accordingly.

func (*Trie) DangerouslyDumpCacheToString

func (tr *Trie) DangerouslyDumpCacheToString() string

func (*Trie) Delete

func (tr *Trie) Delete(key []byte)

Delete deletes Key/value from the Trie, reorganizes the trie

func (*Trie) DeleteStr

func (tr *Trie) DeleteStr(key interface{})

DeleteStr removes node from trie

func (*Trie) GetNode

func (tr *Trie) GetNode(unpackedKey []byte) (Node, bool)

GetNode fetches node from the trie

func (*Trie) Info

func (tr *Trie) Info() string

func (*Trie) InsertKeyCommitment

func (tr *Trie) InsertKeyCommitment(key []byte)

InsertKeyCommitment inserts unpackedKey/value pair with equal unpackedKey and value. Key must not be empty. It leads to optimized serialization of trie nodes because terminal commitment is contained in the unpackedKey. It saves 33 bytes per trie node for use cases such as ledger state commitment via UTXO IDs: each UTXO ID is a commitment to the output, so we only need PoI, not the commitment itself

func (*Trie) Model

func (tr *Trie) Model() CommitmentModel

func (*Trie) PathArity

func (tr *Trie) PathArity() PathArity

func (*Trie) PersistMutations

func (tr *Trie) PersistMutations(store KVWriter) int

PersistMutations persists the cache to the unpackedKey/value store Does not clear cache

func (*Trie) Reconcile

func (tr *Trie) Reconcile(store KVIterator) [][]byte

Reconcile returns a list of keys in the store which cannot be proven in the trie Trie is consistent if empty slice is returned May be an expensive operation

func (*Trie) Update

func (tr *Trie) Update(key []byte, value []byte)

Update updates Trie with the unpackedKey/value. Reorganizes and re-calculates trie, keeps cache consistent

func (*Trie) UpdateAll

func (tr *Trie) UpdateAll(store KVIterator)

UpdateAll mass-updates trie from the unpackedKey/value store. To be used to build trie for arbitrary unpackedKey/value data sets

func (*Trie) UpdateStr

func (tr *Trie) UpdateStr(key interface{}, value interface{})

UpdateStr updates unpackedKey/value pair in the trie

func (*Trie) VectorCommitmentFromBytes

func (tr *Trie) VectorCommitmentFromBytes(data []byte) (VCommitment, error)

type TrieReader

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

TrieReader direct read-only access to trie

func NewTrieReader

func NewTrieReader(model CommitmentModel, trieStore, valueStore KVReader) *TrieReader

func (*TrieReader) GetNode

func (tr *TrieReader) GetNode(unpackedKey []byte) (Node, bool)

func (*TrieReader) Info

func (tr *TrieReader) Info() string

func (*TrieReader) Model

func (tr *TrieReader) Model() CommitmentModel

func (*TrieReader) PathArity

func (tr *TrieReader) PathArity() PathArity

type VCommitment

type VCommitment interface {
	Clone() VCommitment
	Serializable
}

VCommitment represents interface to the vector commitment. It can be hash, or it can be a curve element

func RootCommitment

func RootCommitment(tr NodeStore) VCommitment

RootCommitment computes root commitment from the root node of the trie represented as a NodeStore

Jump to

Keyboard shortcuts

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