package core import ( "math/big" ) // Trie is a Ethereum Merkle Patricia trie. type Trie interface { // GetKey returns the sha3 preimage of a hashed key that was previously used // to store a value. // // TODO(fjl): remove this when StateTrie is removed GetKey([]byte) []byte // TryGet returns the value for key stored in the trie. The value bytes must // not be modified by the caller. If a node was not found in the database, a // trie.MissingNodeError is returned. TryGet(key []byte) ([]byte, error) // TryGetAccount abstracts an account read from the trie. It retrieves the // account blob from the trie with provided account address and decodes it // with associated decoding algorithm. If the specified account is not in // the trie, nil will be returned. If the trie is corrupted(e.g. some nodes // are missing or the account blob is incorrect for decoding), an error will // be returned. TryGetAccount(address Address) (*StateAccount, error) // TryUpdate associates key with value in the trie. If value has length zero, any // existing value is deleted from the trie. The value bytes must not be modified // by the caller while they are stored in the trie. If a node was not found in the // database, a trie.MissingNodeError is returned. // TryUpdate(key, value []byte) error // TryUpdateAccount abstracts an account write to the trie. It encodes the // provided account object with associated algorithm and then updates it // in the trie with provided address. // TryUpdateAccount(address Address, account *StateAccount) error // TryDelete removes any existing value for key from the trie. If a node was not // found in the database, a trie.MissingNodeError is returned. // TryDelete(key []byte) error // TryDeleteAccount abstracts an account deletion from the trie. // TryDeleteAccount(address Address) error // Hash returns the root hash of the trie. It does not write to the database and // can be used even if the trie doesn't have one. Hash() Hash // Commit collects all dirty nodes in the trie and replace them with the // corresponding node hash. All collected nodes(including dirty leaves if // collectLeaf is true) will be encapsulated into a nodeset for return. // The returned nodeset can be nil if the trie is clean(nothing to commit). // Once the trie is committed, it's not usable anymore. A new trie must // be created with new root and updated trie database for following usage // Commit(collectLeaf bool) (Hash, *NodeSet) // NodeIterator returns an iterator that returns nodes of the trie. Iteration // starts at the key after the given start key. NodeIterator(startKey []byte) NodeIterator // Prove constructs a Merkle proof for key. The result contains all encoded nodes // on the path to the value at key. The value itself is also included in the last // node and can be retrieved by verifying the proof. // // If the trie does not contain a value for key, the returned proof contains all // nodes of the longest existing prefix of the key (at least the root), ending // with the node that proves the absence of the key. Prove(key []byte, fromLevel uint, proofDb KeyValueWriter) error } // StateAccount is the Ethereum consensus representation of accounts. // These objects are stored in the main account trie. type StateAccount struct { Nonce uint64 Balance *big.Int Root Hash // merkle root of the storage trie CodeHash []byte } // NodeIterator is an iterator to traverse the trie pre-order. type NodeIterator interface { // Next moves the iterator to the next node. If the parameter is false, any child // nodes will be skipped. Next(bool) bool // Error returns the error status of the iterator. Error() error // Hash returns the hash of the current node. Hash() Hash // Parent returns the hash of the parent of the current node. The hash may be the one // grandparent if the immediate parent is an internal node with no hash. Parent() Hash // Path returns the hex-encoded path to the current node. // Callers must not retain references to the return value after calling Next. // For leaf nodes, the last element of the path is the 'terminator symbol' 0x10. Path() []byte // NodeBlob returns the rlp-encoded value of the current iterated node. // If the node is an embedded node in its parent, nil is returned then. NodeBlob() []byte // Leaf returns true iff the current node is a leaf node. Leaf() bool // LeafKey returns the key of the leaf. The method panics if the iterator is not // positioned at a leaf. Callers must not retain references to the value after // calling Next. LeafKey() []byte // LeafBlob returns the content of the leaf. The method panics if the iterator // is not positioned at a leaf. Callers must not retain references to the value // after calling Next. LeafBlob() []byte // LeafProof returns the Merkle proof of the leaf. The method panics if the // iterator is not positioned at a leaf. Callers must not retain references // to the value after calling Next. LeafProof() [][]byte // AddResolver sets a node resolver to use for looking up trie nodes before // reaching into the real persistent layer. // // This is not required for normal operation, rather is an optimization for // cases where trie nodes can be recovered from some external mechanism without // reading from disk. In those cases, this resolver allows short circuiting // accesses and returning them from memory. // // Before adding a similar mechanism to any other place in Geth, consider // making trie.Database an interface and wrapping at that level. It's a huge // refactor, but it could be worth it if another occurrence arises. AddResolver(NodeResolver) } // NodeResolver is used for looking up trie nodes before reaching into the real // persistent layer. This is not mandatory, rather is an optimization for cases // where trie nodes can be recovered from some external mechanism without reading // from disk. In those cases, this resolver allows short circuiting accesses and // returning them from memory. type NodeResolver func(owner Hash, path []byte, hash Hash) []byte // KeyValueWriter wraps the Put method of a backing data store. type KeyValueWriter interface { // Put inserts the given value into the key-value data store. Put(key []byte, value []byte) error // Delete removes the key from the key-value data store. Delete(key []byte) error }