Documentation ¶
Index ¶
- Constants
- Variables
- type ChangeProof
- type Config
- type Database
- func (db *Database) Close() error
- func (db *Database) CommitChangeProof(ctx context.Context, proof *ChangeProof) error
- func (db *Database) CommitRangeProof(ctx context.Context, start []byte, proof *RangeProof) error
- func (*Database) CommitToDB(context.Context) error
- func (*Database) CommitToParent(context.Context) error
- func (db *Database) Compact(start []byte, limit []byte) error
- func (db *Database) Delete(key []byte) error
- func (db *Database) Get(key []byte) ([]byte, error)
- func (db *Database) GetChangeProof(ctx context.Context, startRootID ids.ID, endRootID ids.ID, start []byte, ...) (*ChangeProof, error)
- func (db *Database) GetMerkleRoot(ctx context.Context) (ids.ID, error)
- func (db *Database) GetProof(ctx context.Context, key []byte) (*Proof, error)
- func (db *Database) GetRangeProof(ctx context.Context, start, end []byte, maxLength int) (*RangeProof, error)
- func (db *Database) GetRangeProofAtRoot(ctx context.Context, rootID ids.ID, start, end []byte, maxLength int) (*RangeProof, error)
- func (db *Database) GetValue(ctx context.Context, key []byte) ([]byte, error)
- func (db *Database) GetValues(ctx context.Context, keys [][]byte) ([][]byte, []error)
- func (db *Database) Has(k []byte) (bool, error)
- func (db *Database) HealthCheck(ctx context.Context) (interface{}, error)
- func (db *Database) Insert(ctx context.Context, k, v []byte) error
- func (db *Database) NewBatch() database.Batch
- func (db *Database) NewIterator() database.Iterator
- func (db *Database) NewIteratorWithPrefix(prefix []byte) database.Iterator
- func (db *Database) NewIteratorWithStart(start []byte) database.Iterator
- func (db *Database) NewIteratorWithStartAndPrefix(start, prefix []byte) database.Iterator
- func (db *Database) NewPreallocatedView(estimatedSize int) (TrieView, error)
- func (db *Database) NewView() (TrieView, error)
- func (db *Database) Put(k, v []byte) error
- func (db *Database) Remove(ctx context.Context, key []byte) error
- type Decoder
- type Encoder
- type EncoderDecoder
- type KeyValue
- type Maybe
- type Proof
- type ProofNode
- type RangeProof
- type ReadOnlyTrie
- type SerializedPath
- func (s SerializedPath) AppendNibble(nibble byte) SerializedPath
- func (s SerializedPath) Equal(other SerializedPath) bool
- func (s SerializedPath) HasPrefix(prefix SerializedPath) bool
- func (s SerializedPath) HasStrictPrefix(prefix SerializedPath) bool
- func (s SerializedPath) NibbleVal(nibbleIndex int) byte
- type Trie
- type TrieView
Constants ¶
const ( NodeBranchFactor = 16 HashLength = 32 )
const EmptyPath path = ""
const (
RootPath = EmptyPath
)
Variables ¶
var ( ErrStartRootNotFound = errors.New("start root is not before end root in history") ErrRootIDNotPresent = errors.New("root id is not present in history") )
var ( ErrInvalidProof = errors.New("proof obtained an invalid root ID") ErrInvalidMaxLength = errors.New("expected max length to be > 0") ErrNonIncreasingValues = errors.New("keys sent are not in increasing order") ErrStateFromOutsideOfRange = errors.New("state key falls outside of the start->end range") ErrNonIncreasingProofNodes = errors.New("each proof node key must be a strict prefix of the next") ErrExtraProofNodes = errors.New("extra proof nodes in path") ErrDataInMissingRootProof = errors.New("there should be no state or deleted keys in a change proof that had a missing root") ErrNoMerkleProof = errors.New("empty key response must include merkle proof") ErrShouldJustBeRoot = errors.New("end proof should only contain root") ErrNoStartProof = errors.New("no start proof") ErrNoEndProof = errors.New("no end proof") ErrNoProof = errors.New("proof has no nodes") ErrProofNodeNotForKey = errors.New("the provided node has a key that is not a prefix of the specified key") ErrProofValueDoesntMatch = errors.New("the provided value does not match the proof node for the provided key's value") ErrProofNodeHasUnincludedValue = errors.New("the provided proof has a value for a key within the range that is not present in the provided key/values") )
var ( ErrCommitted = errors.New("view has been committed") ErrInvalid = errors.New("the trie this view was based on has changed, rending this view invalid") ErrOddLengthWithValue = errors.New( "the underlying db only supports whole number of byte keys, so cannot record changes with odd nibble length", ) ErrGetPathToFailure = errors.New("GetPathTo failed to return the closest node") ErrStartAfterEnd = errors.New("start key > end key") ErrViewIsNotAChild = errors.New("passed in view is required to be a child of the current view") ErrNoValidRoot = errors.New("a valid root was not provided to the trieView constructor") )
var (
Codec, Version = newCodec()
)
Functions ¶
This section is empty.
Types ¶
type ChangeProof ¶
type ChangeProof struct { // If false, the node that created this doesn't have // sufficient history to generate a change proof and // all other fields must be empty. // Otherwise at least one other field is non-empty. HadRootsInHistory bool // A proof that the smallest key in the requested range does/doesn't // exist in the trie with the requested start root. // Empty if no lower bound on the requested range was given. // Note that this may not be an entire proof -- nodes are omitted if // they are also in [EndProof]. StartProof []ProofNode // A proof that the largest key in [KeyValues] and [DeletedKeys] // does/doesn't exist in the trie with the requested start root. // Empty iff no upper bound on the requested range was given // and [KeyValues] and [DeletedKeys] are empty. EndProof []ProofNode // A subset of key-values that were added or had their values modified // between the requested start root (exclusive) and the requested // end root (inclusive). // Sorted by increasing key. KeyValues []KeyValue // A subset of keys that were removed from the trie between the requested // start root (exclusive) and the requested end root (inclusive). // Sorted by increasing key. DeletedKeys [][]byte }
func (*ChangeProof) Empty ¶
func (proof *ChangeProof) Empty() bool
func (*ChangeProof) Verify ¶
func (proof *ChangeProof) Verify( ctx context.Context, db *Database, start []byte, end []byte, expectedEndRootID ids.ID, ) error
Returns nil iff all of the following hold:
- [start] <= [end].
- [proof] is non-empty iff [proof.HadRootsInHistory].
- All keys in [proof.KeyValues] and [proof.DeletedKeys] are in [start, end]. If [start] is empty, all keys are considered > [start]. If [end] is empty, all keys are considered < [end].
- [proof.KeyValues] and [proof.DeletedKeys] are sorted in order of increasing key.
- [proof.StartProof] and [proof.EndProof] are well-formed.
- When the keys in [proof.KeyValues] are added to [db] and the keys in [proof.DeletedKeys] are removed from [db], the root ID of [db] is [expectedEndRootID].
Assumes [db.lock] isn't held.
type Config ¶
type Config struct { // The number of changes to the database that we store in memory in order to // serve change proofs. HistoryLength int NodeCacheSize int // If [Reg] is nil, metrics are collected locally but not exported through // Prometheus. // This may be useful for testing. Reg prometheus.Registerer Tracer trace.Tracer }
type Database ¶
type Database struct {
// contains filtered or unexported fields
}
Can only be edited by committing changes from a trieView.
func (*Database) CommitChangeProof ¶
func (db *Database) CommitChangeProof(ctx context.Context, proof *ChangeProof) error
Commits the key/value pairs within the [proof] to the db.
func (*Database) CommitRangeProof ¶
Commits the key/value pairs within the [proof] to the db. [start] is the smallest key in the range this [proof] covers.
func (*Database) CommitToDB ¶
CommitToDB is a No Op for db since it is already in sync with itself here to satisfy TrieView interface
func (*Database) CommitToParent ¶
CommitToParent is a no-op for the db because it has no parent
func (*Database) GetChangeProof ¶
func (db *Database) GetChangeProof( ctx context.Context, startRootID ids.ID, endRootID ids.ID, start []byte, end []byte, maxLength int, ) (*ChangeProof, error)
Returns a proof for a subset of the key/value changes in key range [start, end] that occurred between [startRootID] and [endRootID]. Returns at most [maxLength] key/value pairs.
func (*Database) GetMerkleRoot ¶
Returns the ID of the root node of the merkle trie.
func (*Database) GetRangeProof ¶
func (db *Database) GetRangeProof( ctx context.Context, start, end []byte, maxLength int, ) (*RangeProof, error)
Returns a proof for the key/value pairs in this trie within the range [start, end].
func (*Database) GetRangeProofAtRoot ¶
func (db *Database) GetRangeProofAtRoot( ctx context.Context, rootID ids.ID, start, end []byte, maxLength int, ) (*RangeProof, error)
Returns a proof for the key/value pairs in this trie within the range [start, end] when the root of the trie was [rootID].
func (*Database) GetValue ¶
GetValue returns the value associated with [key]. Returns database.ErrNotFound if it doesn't exist.
func (*Database) HealthCheck ¶
func (*Database) NewIterator ¶
func (*Database) NewIteratorWithPrefix ¶
func (*Database) NewIteratorWithStart ¶
func (*Database) NewIteratorWithStartAndPrefix ¶
func (*Database) NewPreallocatedView ¶
Returns a new view preallocated to hold at least [estimatedSize] value changes at a time. If more changes are made, additional memory will be allocated. The returned view is added to [db.childViews]. Assumes [db.lock] isn't held.
func (*Database) NewView ¶
Returns a new view on top of this trie. Changes made to the view will only be reflected in the original trie if Commit is called. Assumes [db.lock] isn't held.
type Encoder ¶
type Encoder interface { EncodeProof(version uint16, p *Proof) ([]byte, error) EncodeChangeProof(version uint16, p *ChangeProof) ([]byte, error) EncodeRangeProof(version uint16, p *RangeProof) ([]byte, error) // contains filtered or unexported methods }
TODO actually encode the version and remove version from the interface
type EncoderDecoder ¶
EncoderDecoder defines the interface needed by merkleDB to marshal and unmarshal relevant types.
type Maybe ¶
type Maybe[T any] struct { // contains filtered or unexported fields }
Maybe T = Some T | Nothing. A data wrapper that allows values to be something [Some T] or nothing Nothing. Maybe is used to wrap types: * That can't be represented by nil. * That use nil as a valid value instead of an indicator of a missing value. For more info see https://en.wikipedia.org/wiki/Option_type
type Proof ¶
type Proof struct { // Nodes in the proof path from root --> target key // (or node that would be where key is if it doesn't exist). // Must always be non-empty (i.e. have the root node). Path []ProofNode // This is a proof that [key] exists/doesn't exist. Key []byte // Nothing if [Key] isn't in the trie. // Otherwise the value corresponding to [Key]. Value Maybe[[]byte] }
An inclusion/exclustion proof of a key.
type RangeProof ¶
type RangeProof struct { // A proof that the smallest key in the requested range does/doesn't exist. // Note that this may not be an entire proof -- nodes are omitted if // they are also in [EndProof]. StartProof []ProofNode // A proof of the greatest key in [KeyValues], or, if this proof contains // no [KeyValues], just the root. // Empty if the request for this range proof gave no upper bound // on the range to fetch, unless this proof contains no [KeyValues] // and [StartProof] is empty. EndProof []ProofNode // This proof proves that the key-value pairs in [KeyValues] are in the trie. // Sorted by increasing key. KeyValues []KeyValue }
A proof that a given set of key-value pairs are in a trie.
func (*RangeProof) Verify ¶
func (proof *RangeProof) Verify( ctx context.Context, start []byte, end []byte, expectedRootID ids.ID, ) error
Returns nil iff all the following hold:
- [start] <= [end].
- [proof] is non-empty.
- All keys in [proof.KeyValues] are in the range [start, end]. If [start] is empty, all keys are considered > [start]. If [end] is empty, all keys are considered < [end].
- [proof.KeyValues] is sorted by increasing key.
- [proof.StartProof] and [proof.EndProof] are well-formed.
- One of the following holds: [end] and [proof.EndProof] are empty. [proof.StartProof], [start], [end], and [proof.KeyValues] are empty and [proof.EndProof] is just the root. [end] is non-empty and [proof.EndProof] is a valid proof of a key <= [end].
- [expectedRootID] is the root of the trie containing the given key-value pairs and start/end proofs.
type ReadOnlyTrie ¶
type ReadOnlyTrie interface { // GetValue gets the value associated with the specified key // database.ErrNotFound if the key is not present GetValue(ctx context.Context, key []byte) ([]byte, error) // GetValues gets the values associated with the specified keys // database.ErrNotFound if the key is not present GetValues(ctx context.Context, keys [][]byte) ([][]byte, []error) // GetMerkleRoot returns the merkle root of the Trie GetMerkleRoot(ctx context.Context) (ids.ID, error) // GetProof generates a proof of the value associated with a particular key, or a proof of its absence from the trie GetProof(ctx context.Context, bytesPath []byte) (*Proof, error) // GetRangeProof generates a proof of up to maxLength smallest key/values with keys between start and end GetRangeProof(ctx context.Context, start, end []byte, maxLength int) (*RangeProof, error) // contains filtered or unexported methods }
type SerializedPath ¶
SerializedPath contains a path from the trie. The trie branch factor is 16, so the path may contain an odd number of nibbles. If it did contain an odd number of nibbles, the last 4 bits of the last byte should be discarded.
func (SerializedPath) AppendNibble ¶
func (s SerializedPath) AppendNibble(nibble byte) SerializedPath
func (SerializedPath) Equal ¶
func (s SerializedPath) Equal(other SerializedPath) bool
func (SerializedPath) HasPrefix ¶
func (s SerializedPath) HasPrefix(prefix SerializedPath) bool
Returns true iff [prefix] is a prefix of [s] or equal to it.
func (SerializedPath) HasStrictPrefix ¶
func (s SerializedPath) HasStrictPrefix(prefix SerializedPath) bool
Returns true iff [prefix] is a prefix of [s] but not equal to it.
func (SerializedPath) NibbleVal ¶
func (s SerializedPath) NibbleVal(nibbleIndex int) byte
type Trie ¶
type Trie interface { ReadOnlyTrie // Remove will delete a key from the Trie Remove(ctx context.Context, key []byte) error // NewPreallocatedView returns a new view on top of this Trie with space allocated for changes NewPreallocatedView(estimatedChanges int) (TrieView, error) // NewView returns a new view on top of this Trie NewView() (TrieView, error) // Insert a key/value pair into the Trie Insert(ctx context.Context, key, value []byte) error }
type TrieView ¶
type TrieView interface { Trie // CommitToDB takes the changes of this trie and commits them down the view stack // until all changes in the stack commit to the database // Takes the DB commit lock CommitToDB(ctx context.Context) error // CommitToParent takes changes of this TrieView and commits them to its parent Trie // Takes the DB commit lock CommitToParent(ctx context.Context) error // contains filtered or unexported methods }