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
- Variables
- func Assert(cond bool, format string, p ...interface{})
- func Blake2b160(data []byte) (ret [20]byte)
- func ByteSize(s KVIterator) int
- func CheckNils(i1, i2 interface{}) (bool, bool)
- func Concat(par ...interface{}) []byte
- func DangerouslyDumpToConsole(title string, r KVIterator)
- func DecodeToUnpackedBytes(encoded []byte, arity PathArity) ([]byte, error)
- func DumpToFile(r KVIterator, fname string) (int, error)
- func EncodeUnpackedBytes(unpacked []byte, arity PathArity) ([]byte, error)
- func MustBytes(o interface{ ... }) []byte
- func MustSize(o interface{ ... }) int
- func MustUint32From4Bytes(b []byte) uint32
- func NumEntries(s KVIterator) int
- func PackUnpackedBytes(unpacked []byte, arity PathArity) ([]byte, error)
- func ReadByte(r io.Reader) (byte, error)
- func ReadBytes16(r io.Reader) ([]byte, error)
- func ReadBytes32(r io.Reader) ([]byte, error)
- func ReadBytes8(r io.Reader) ([]byte, error)
- func ReadUint16(r io.Reader, pval *uint16) error
- func ReadUint32(r io.Reader, pval *uint32) error
- func Size(o interface{ ... }) (int, error)
- func ToString(n Node) string
- func Uint16From2Bytes(b []byte) (uint16, error)
- func Uint16To2Bytes(val uint16) []byte
- func Uint32From4Bytes(b []byte) (uint32, error)
- func Uint32To4Bytes(val uint32) []byte
- func UnDumpFromFile(w KVWriter, fname string) (int, error)
- func UnpackBytes(src []byte, arity PathArity) []byte
- func WriteByte(w io.Writer, val byte) error
- func WriteBytes16(w io.Writer, data []byte) error
- func WriteBytes32(w io.Writer, data []byte) error
- func WriteBytes8(w io.Writer, data []byte) error
- func WriteUint16(w io.Writer, val uint16) error
- func WriteUint32(w io.Writer, val uint32) error
- type BinaryStreamFileIterator
- type BinaryStreamFileWriter
- type BinaryStreamIterator
- type BinaryStreamWriter
- type CommitmentModel
- type KVBatchedUpdater
- type KVIterator
- type KVReader
- type KVStore
- type KVStreamIterator
- type KVStreamWriter
- type KVWriter
- type Node
- type NodeData
- type NodeStore
- type PathArity
- type ProofEndingCode
- type ProofGeneric
- type RandStreamIterator
- type RandStreamParams
- type Serializable
- type TCommitment
- type Trie
- func (tr *Trie) ClearCache()
- func (tr *Trie) Clone() *Trie
- func (tr *Trie) Commit()
- func (tr *Trie) DangerouslyDumpCacheToString() string
- func (tr *Trie) Delete(key []byte)
- func (tr *Trie) DeleteStr(key interface{})
- func (tr *Trie) GetNode(unpackedKey []byte) (Node, bool)
- func (tr *Trie) Info() string
- func (tr *Trie) InsertKeyCommitment(key []byte)
- func (tr *Trie) Model() CommitmentModel
- func (tr *Trie) PathArity() PathArity
- func (tr *Trie) PersistMutations(store KVWriter) int
- func (tr *Trie) Reconcile(store KVIterator) [][]byte
- func (tr *Trie) Update(key []byte, value []byte)
- func (tr *Trie) UpdateAll(store KVIterator)
- func (tr *Trie) UpdateStr(key interface{}, value interface{})
- func (tr *Trie) VectorCommitmentFromBytes(data []byte) (VCommitment, error)
- type TrieReader
- type VCommitment
Constants ¶
const ( PathArity256 = PathArity(255) PathArity16 = PathArity(15) PathArity2 = PathArity(1) )
const ( EndingTerminal = iota EndingSplit EndingExtend )
Variables ¶
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") )
var AllPathArity = []PathArity{PathArity256, PathArity16, PathArity2}
var (
ErrNotAllBytesConsumed = xerrors.New("serialization error: not all bytes were consumed")
)
Functions ¶
func Blake2b160 ¶
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 ¶
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 DangerouslyDumpToConsole ¶
func DangerouslyDumpToConsole(title string, r KVIterator)
func DecodeToUnpackedBytes ¶
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 MustUint32From4Bytes ¶
func NumEntries ¶
func NumEntries(s KVIterator) int
NumEntries calculates number of key/value pair in the iterator
func Uint16From2Bytes ¶
func Uint16To2Bytes ¶
func Uint32From4Bytes ¶
func Uint32To4Bytes ¶
func UnDumpFromFile ¶
UnDumpFromFile restores dumped set of key/value pairs into the key/value writer
func UnpackBytes ¶
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
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 ¶
KVBatchedUpdater collects mutations in the buffer then flushes it at once
type KVIterator ¶
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 ¶
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 ¶
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 (PathArity) NumChildren ¶
func (PathArity) PathFragmentCommitmentIndex ¶
func (PathArity) TerminalCommitmentIndex ¶
func (PathArity) VectorLength ¶
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
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) 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 (*Trie) DeleteStr ¶
func (tr *Trie) DeleteStr(key interface{})
DeleteStr removes node from trie
func (*Trie) InsertKeyCommitment ¶
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) PersistMutations ¶
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 ¶
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) 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