Documentation ¶
Overview ¶
Package snapshot implements a journalled, dynamic state dump.
Index ¶
- Variables
- func CheckDanglingStorage(chaindb ethdb.KeyValueStore) error
- func GenerateAccountTrieRoot(it AccountIterator) (common.Hash, error)
- func GenerateStorageTrieRoot(account common.Hash, it StorageIterator) (common.Hash, error)
- func GenerateTrie(snaptree *Tree, root common.Hash, src ethdb.Database, dst ethdb.KeyValueWriter) error
- func ResetSnapshotGeneration(db ethdb.KeyValueWriter)
- func WipeSnapshot(db ethdb.KeyValueStore, full bool) chan struct{}
- type AccountIterator
- type Config
- type Iterator
- type Snapshot
- type StorageIterator
- type Tree
- func (t *Tree) AbortGeneration()
- func (t *Tree) AccountIterator(root common.Hash, seek common.Hash, force bool) (AccountIterator, error)
- func (t *Tree) Discard(blockHash common.Hash) error
- func (t *Tree) DiskAccountIterator(seek common.Hash) AccountIterator
- func (t *Tree) DiskRoot() common.Hash
- func (t *Tree) DiskStorageIterator(account common.Hash, seek common.Hash) StorageIterator
- func (t *Tree) Flatten(blockHash common.Hash) error
- func (t *Tree) NumBlockLayers() int
- func (t *Tree) NumStateLayers() int
- func (t *Tree) Rebuild(blockHash, root common.Hash)
- func (t *Tree) Size() (diffs common.StorageSize, buf common.StorageSize)
- func (t *Tree) Snapshot(stateRoot common.Hash) Snapshot
- func (t *Tree) Snapshots(blockHash common.Hash, limits int, nodisk bool) []Snapshot
- func (t *Tree) StorageIterator(root common.Hash, account common.Hash, seek common.Hash, force bool) (StorageIterator, error)
- func (t *Tree) Update(blockHash, blockRoot, parentBlockHash common.Hash, ...) error
- func (t *Tree) Verify(root common.Hash) error
Constants ¶
This section is empty.
Variables ¶
var ( // ErrSnapshotStale is returned from data accessors if the underlying snapshot // layer had been invalidated due to the chain progressing forward far enough // to not maintain the layer's original state. ErrSnapshotStale = errors.New("snapshot stale") // ErrStaleParentLayer is returned when Flatten attempts to flatten a diff layer into // a stale parent. ErrStaleParentLayer = errors.New("parent disk layer is stale") // ErrNotCoveredYet is returned from data accessors if the underlying snapshot // is being generated currently and the requested data item is not yet in the // range of accounts covered. ErrNotCoveredYet = errors.New("not covered yet") // ErrNotConstructed is returned if the callers want to iterate the snapshot // while the generation is not finished yet. ErrNotConstructed = errors.New("snapshot is not constructed") )
Functions ¶
func CheckDanglingStorage ¶
func CheckDanglingStorage(chaindb ethdb.KeyValueStore) error
CheckDanglingStorage iterates the snap storage data, and verifies that all storage also has corresponding account data.
func GenerateAccountTrieRoot ¶
func GenerateAccountTrieRoot(it AccountIterator) (common.Hash, error)
GenerateAccountTrieRoot takes an account iterator and reproduces the root hash.
func GenerateStorageTrieRoot ¶
GenerateStorageTrieRoot takes a storage iterator and reproduces the root hash.
func GenerateTrie ¶
func GenerateTrie(snaptree *Tree, root common.Hash, src ethdb.Database, dst ethdb.KeyValueWriter) error
GenerateTrie takes the whole snapshot tree as the input, traverses all the accounts as well as the corresponding storages and regenerate the whole state (account trie + all storage tries).
func ResetSnapshotGeneration ¶
func ResetSnapshotGeneration(db ethdb.KeyValueWriter)
ResetSnapshotGeneration writes a clean snapshot generator marker to [db] so no re-generation is performed after.
func WipeSnapshot ¶
func WipeSnapshot(db ethdb.KeyValueStore, full bool) chan struct{}
WipeSnapshot starts a goroutine to iterate over the entire key-value database and delete all the data associated with the snapshot (accounts, storage, metadata). After all is done, the snapshot range of the database is compacted to free up unused data blocks.
Types ¶
type AccountIterator ¶
type AccountIterator interface { Iterator // Account returns the RLP encoded slim account the iterator is currently at. // An error will be returned if the iterator becomes invalid Account() []byte }
AccountIterator is an iterator to step over all the accounts in a snapshot, which may or may not be composed of multiple layers.
type Config ¶
type Config struct { CacheSize int // Megabytes permitted to use for read caches NoBuild bool // Indicator that the snapshots generation is disallowed AsyncBuild bool // The snapshot generation is allowed to be constructed asynchronously SkipVerify bool // Indicator that all verification should be bypassed }
Config includes the configurations for snapshots.
type Iterator ¶
type Iterator interface { // Next steps the iterator forward one element, returning false if exhausted, // or an error if iteration failed for some reason (e.g. root being iterated // becomes stale and garbage collected). Next() bool // Error returns any failure that occurred during iteration, which might have // caused a premature iteration exit (e.g. snapshot stack becoming stale). Error() error // Hash returns the hash of the account or storage slot the iterator is // currently at. Hash() common.Hash // Release releases associated resources. Release should always succeed and // can be called multiple times without causing error. Release() }
Iterator is an iterator to step over all the accounts or the specific storage in a snapshot which may or may not be composed of multiple layers.
type Snapshot ¶
type Snapshot interface { // Root returns the root hash for which this snapshot was made. Root() common.Hash // Account directly retrieves the account associated with a particular hash in // the snapshot slim data format. Account(hash common.Hash) (*types.SlimAccount, error) // AccountRLP directly retrieves the account RLP associated with a particular // hash in the snapshot slim data format. AccountRLP(hash common.Hash) ([]byte, error) // Storage directly retrieves the storage data associated with a particular hash, // within a particular account. Storage(accountHash, storageHash common.Hash) ([]byte, error) // AccountIterator creates an account iterator over the account trie given by the provided root hash. AccountIterator(seek common.Hash) AccountIterator // StorageIterator creates a storage iterator over the storage trie given by the provided root hash. StorageIterator(account common.Hash, seek common.Hash) (StorageIterator, bool) }
Snapshot represents the functionality supported by a snapshot storage layer.
func NewDiskLayer ¶
func NewDiskLayer(diskdb ethdb.KeyValueStore) Snapshot
NewDiskLayer creates a diskLayer for direct access to the contents of the on-disk snapshot. Does not perform any validation.
type StorageIterator ¶
type StorageIterator interface { Iterator // Slot returns the storage slot the iterator is currently at. An error will // be returned if the iterator becomes invalid Slot() []byte }
StorageIterator is an iterator to step over the specific storage in a snapshot, which may or may not be composed of multiple layers.
type Tree ¶
type Tree struct {
// contains filtered or unexported fields
}
Tree is an Ethereum state snapshot tree. It consists of one persistent base layer backed by a key-value store, on top of which arbitrarily many in-memory diff layers are topped. The memory diffs can form a tree with branching, but the disk layer is singleton and common to all. If a reorg goes deeper than the disk layer, everything needs to be deleted.
The goal of a state snapshot is twofold: to allow direct access to account and storage data to avoid expensive multi-level trie lookups; and to allow sorted, cheap iteration of the account/storage tries for sync aid.
func New ¶
func New(config Config, diskdb ethdb.KeyValueStore, triedb *trie.Database, blockHash, root common.Hash) (*Tree, error)
New attempts to load an already existing snapshot from a persistent key-value store (with a number of memory layers from a journal), ensuring that the head of the snapshot matches the expected one.
If the snapshot is missing or the disk layer is broken, the snapshot will be reconstructed using both the existing data and the state trie. The repair happens on a background thread.
func NewTestTree ¶
func NewTestTree(diskdb ethdb.KeyValueStore, blockHash, root common.Hash) *Tree
NewTestTree creates a *Tree with a pre-populated diskLayer
func (*Tree) AbortGeneration ¶
func (t *Tree) AbortGeneration()
AbortGeneration aborts an ongoing snapshot generation process (if it hasn't stopped already).
It is not required to manually abort snapshot generation. If generation has not been manually aborted prior to invoking [diffToDisk], it will be aborted anyways.
It is safe to call this method multiple times and when there is no snapshot generation currently underway.
func (*Tree) AccountIterator ¶
func (t *Tree) AccountIterator(root common.Hash, seek common.Hash, force bool) (AccountIterator, error)
AccountIterator creates a new account iterator for the specified root hash and seeks to a starting account hash. When [force] is true, a new account iterator is created without acquiring the [snapTree] lock and without confirming that the snapshot on the disk layer is fully generated.
func (*Tree) DiskAccountIterator ¶
func (t *Tree) DiskAccountIterator(seek common.Hash) AccountIterator
func (*Tree) DiskStorageIterator ¶
func (*Tree) Flatten ¶
Flatten flattens the snapshot for [blockHash] into its parent. if its parent is not a disk layer, Flatten will return an error. Note: a blockHash is used instead of a state root so that the exact state transition between the two states is well defined. This is intended to prevent the following edge case
A / \ B C | D
In this scenario, it's possible For (A, B) and (A, C, D) to be two different paths to the resulting state. We use block hashes and parent block hashes to ensure that the exact path through which we flatten diffLayers is well defined.
func (*Tree) NumBlockLayers ¶
func (*Tree) NumStateLayers ¶
Length returns the number of snapshot layers that is currently being maintained.
func (*Tree) Rebuild ¶
Rebuild wipes all available snapshot data from the persistent database and discard all caches and diff layers. Afterwards, it starts a new snapshot generator with the given root hash.
func (*Tree) Size ¶
func (t *Tree) Size() (diffs common.StorageSize, buf common.StorageSize)
Size returns the memory usage of the diff layers above the disk layer and the dirty nodes buffered in the disk layer. Currently, the implementation uses a special diff layer (the first) as an aggregator simulating a dirty buffer, so the second return will always be 0. However, this will be made consistent with the pathdb, which will require a second return.
func (*Tree) Snapshot ¶
Snapshot retrieves a snapshot belonging to the given state root, or nil if no snapshot is maintained for that state root.
func (*Tree) Snapshots ¶
Snapshots returns all visited layers from the topmost layer with specific root and traverses downward. The layer amount is limited by the given number. If nodisk is set, then disk layer is excluded.
func (*Tree) StorageIterator ¶
func (t *Tree) StorageIterator(root common.Hash, account common.Hash, seek common.Hash, force bool) (StorageIterator, error)
StorageIterator creates a new storage iterator for the specified root hash and account. The iterator will be move to the specific start position. When [force] is true, a new account iterator is created without acquiring the [snapTree] lock and without confirming that the snapshot on the disk layer is fully generated.
func (*Tree) Update ¶
func (t *Tree) Update(blockHash, blockRoot, parentBlockHash common.Hash, destructs map[common.Hash]struct{}, accounts map[common.Hash][]byte, storage map[common.Hash]map[common.Hash][]byte) error
Update adds a new snapshot into the tree, if that can be linked to an existing old parent. It is disallowed to insert a disk layer (the origin of all).