mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-12 09:51:36 +00:00
139 lines
5.7 KiB
Go
139 lines
5.7 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"
|
|
)
|
|
|
|
// CodeMut represents a mutation to contract code.
|
|
type CodeMut struct {
|
|
Code []byte // Null for deletion
|
|
}
|
|
|
|
// AccountMut represents a mutation to an account.
|
|
// Semantics:
|
|
// - Account == nil: delete the account
|
|
// - Code == nil: leave code unchanged
|
|
// - Code != nil: apply the given code mutation
|
|
type AccountMut struct {
|
|
Account *Account // Null for deletion
|
|
Code *CodeMut // Null for unchanged
|
|
}
|
|
|
|
// Hashes encapsulates a trie root together with its original (pre-update) root.
|
|
type Hashes struct {
|
|
Hash common.Hash // Post-mutation root
|
|
Prev common.Hash // Pre-mutation root
|
|
}
|
|
|
|
// 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 []AccountMut) error
|
|
|
|
// UpdateStorage writes a list of storage slot value.
|
|
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]Hashes, 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 hashing.
|
|
type Prefetcher interface {
|
|
// PrefetchAccount schedules the account for prefetching.
|
|
PrefetchAccount(addresses []common.Address, read bool)
|
|
|
|
// PrefetchStorage schedules the storage slot for prefetching.
|
|
PrefetchStorage(addr common.Address, keys []common.Hash, read bool)
|
|
}
|
|
|
|
// WitnessCollector is an optional extension implemented by hashers that can
|
|
// construct a state witness for the most recent committed state transition.
|
|
type WitnessCollector interface {
|
|
// Witness returns the state 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
|
|
}
|
|
|
|
// noopHasher is a Hasher implementation that performs no work and always
|
|
// returns an empty state root.
|
|
type noopHasher struct{}
|
|
|
|
func (n *noopHasher) UpdateAccount([]common.Address, []AccountMut) error { return nil }
|
|
func (n *noopHasher) UpdateStorage(common.Address, []common.Hash, []common.Hash) error {
|
|
return nil
|
|
}
|
|
func (n *noopHasher) Hash() common.Hash { return common.Hash{} }
|
|
func (n *noopHasher) Commit() (common.Hash, *trienode.MergedNodeSet, map[common.Address]Hashes, error) {
|
|
return common.Hash{}, trienode.NewMergedNodeSet(), make(map[common.Address]Hashes), nil
|
|
}
|
|
func (n *noopHasher) Copy() Hasher { return &noopHasher{} }
|