go-ethereum/core/state/database_hasher.go
2026-04-15 14:59:05 +02:00

114 lines
4.9 KiB
Go

// Copyright 2026 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package state
import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/stateless"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/trie/trienode"
)
// AccountMutation describes a state transition for a single account.
type AccountMutation struct {
Account *Account // Null for deletion
CodeDirty bool // Flag whether the code is changed
Code []byte // Null for deletion
}
// Hasher defines the minimal interface for computing state root hashes.
//
// It abstracts over different trie implementations, such as the traditional
// two-layer Merkle Patricia Trie (separate account and storage tries) and a
// unified single-layer binary trie (a single trie covering accounts, storages
// and contract code).
//
// This abstraction also enables alternative implementations, such as a no-op
// hasher for flat-state-only nodes (i.e. nodes that do not store trie data and
// do not perform state validation).
//
// The Hash method may be invoked multiple times and must return a hash that
// reflects all preceding state mutations. This behavior is required for
// compatibility with pre-Byzantium semantics.
type Hasher interface {
// UpdateAccount writes a list of accounts into the state.
UpdateAccount(addresses []common.Address, accounts []AccountMutation) error
// UpdateStorage writes a list of storage slot value. The hasher handles
// encoding internally. Note, the value with empty data should be
// interpreted as deletion.
UpdateStorage(address common.Address, keys []common.Hash, values []common.Hash) error
// Hash computes and returns the state root hash without committing.
Hash() common.Hash
// Commit finalizes all pending changes and returns the resulting state root
// hash, along with the set of dirty trie nodes generated by the updates.
//
// Additionally, if the hasher uses a two-layer structure, the roots of the
// secondary tries together with their original hashes will also be returned
// for all mutated accounts, regardless of whether their storage was modified.
Commit() (common.Hash, *trienode.MergedNodeSet, map[common.Address]common.Hash, map[common.Address]common.Hash, error)
// Copy returns a deep-copied hasher instance.
Copy() Hasher
}
// Prefetcher is an optional extension implemented by hashers that can
// asynchronously warm up trie/state data ahead of mutations or hashing.
type Prefetcher interface {
// PrefetchAccount schedules the account for prefetching.
PrefetchAccount(addresses []common.Address)
// PrefetchStorage schedules the storage slot for prefetching.
PrefetchStorage(addr common.Address, keys []common.Hash)
}
// WitnessCollector is an optional extension implemented by hashers that can
// construct a stateless witness for the most recent committed state transition.
type WitnessCollector interface {
// Witness returns the stateless witness corresponding to the most recent
// committed state transition.
Witness() (*stateless.Witness, error)
}
// Prover is an optional extension implemented by hashers that can construct
// proofs against the current state.
type Prover interface {
// ProveAccount constructs a proof for the given account.
//
// The returned proof contains all encoded nodes on the path to the account.
// The account itself is included in the last node and can be retrieved by
// verifying the proof.
//
// If the account does not exist, the returned proof contains all nodes of
// the longest existing prefix of the account key (at least the root), ending
// with the node that proves the absence of the account.
ProveAccount(addr common.Address, proofDb ethdb.KeyValueWriter) error
// ProveStorage constructs a proof for the given storage slot of the
// specified account.
//
// The returned proof contains all encoded nodes on the path to the storage
// slot. The slot value itself is included in the last node and can be
// retrieved by verifying the proof.
//
// If the account or storage slot does not exist, the returned proof contains
// the nodes required to prove its absence.
ProveStorage(addr common.Address, key common.Hash, proofDb ethdb.KeyValueWriter) error
}