core/state: add account address to Trie slot accessors #26934 (#1140)

This changes the Trie interface to add the plain account address as a
parameter to all storage-related methods.

After the introduction of the TryAccount* functions, TryGet, TryUpdate and
TryDelete are now only meant to read an account's storage. In their current
form, they assume that an account storage is stored in a separate trie, and
that the hashing of the slot is independent of its account's address.

The proposed structure for a stateless storage breaks these two
assumptions: the hashing of a slot key requires the address and all slots
and accounts are stored in a single trie.

This PR therefore adds an address parameter to the interface. It is ignored
in the MPT version, so this change has no functional impact, however it
will reduce the diff size when merging verkle trees.

Co-authored-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
This commit is contained in:
Daniel Liu 2025-12-23 18:09:56 +08:00 committed by GitHub
parent 55c2d47c45
commit 3bb3f80f5b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 19 additions and 19 deletions

View file

@ -68,10 +68,10 @@ type Trie interface {
// 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)
// TryGetStorage 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.
TryGetStorage(addr common.Address, 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
@ -81,20 +81,20 @@ type Trie interface {
// be returned.
TryGetAccount(address common.Address) (*types.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
// TryUpdateStorage 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
TryUpdateStorage(addr common.Address, 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 common.Address, account *types.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
// TryDeleteStorage removes any existing value for key from the trie. If a node
// was not found in the database, a trie.MissingNodeError is returned.
TryDeleteStorage(addr common.Address, key []byte) error
// TryDeleteAccount abstracts an account deletion from the trie.
TryDeleteAccount(address common.Address) error

View file

@ -199,7 +199,7 @@ func (s *stateObject) GetCommittedState(db Database, key common.Hash) common.Has
s.setError(err)
return common.Hash{}
}
enc, err := tr.TryGet(key.Bytes())
enc, err := tr.TryGetStorage(s.address, key.Bytes())
s.db.StorageReads += time.Since(start)
if err != nil {
s.setError(err)
@ -275,7 +275,7 @@ func (s *stateObject) updateTrie(db Database) (Trie, error) {
s.originStorage[key] = value
if (value == common.Hash{}) {
if err := tr.TryDelete(key[:]); err != nil {
if err := tr.TryDeleteStorage(s.address, key[:]); err != nil {
s.setError(err)
return nil, err
}
@ -283,7 +283,7 @@ func (s *stateObject) updateTrie(db Database) (Trie, error) {
} else {
// Encoding []byte cannot fail, ok to ignore the error.
v, _ := rlp.EncodeToBytes(common.TrimLeftZeroes(value[:]))
if err := tr.TryUpdate(key[:], v); err != nil {
if err := tr.TryUpdateStorage(s.address, key[:], v); err != nil {
s.setError(err)
return nil, err
}

View file

@ -75,7 +75,7 @@ func NewStateTrie(id *ID, db *Database) (*StateTrie, error) {
// Get returns the value for key stored in the trie.
// The value bytes must not be modified by the caller.
func (t *StateTrie) Get(key []byte) []byte {
res, err := t.TryGet(key)
res, err := t.TryGetStorage(common.Address{}, key)
if err != nil {
log.Error("Unhandled trie error in StateTrie.Get", "err", err)
}
@ -86,7 +86,7 @@ func (t *StateTrie) Get(key []byte) []byte {
// The value bytes must not be modified by the caller.
// If the specified node is not in the trie, nil will be returned.
// If a trie node is not found in the database, a MissingNodeError is returned.
func (t *StateTrie) TryGet(key []byte) ([]byte, error) {
func (t *StateTrie) TryGetStorage(_ common.Address, key []byte) ([]byte, error) {
return t.trie.TryGet(t.hashKey(key))
}
@ -131,7 +131,7 @@ func (t *StateTrie) TryGetNode(path []byte) ([]byte, int, error) {
// The value bytes must not be modified by the caller while they are
// stored in the trie.
func (t *StateTrie) Update(key, value []byte) {
if err := t.TryUpdate(key, value); err != nil {
if err := t.TryUpdateStorage(common.Address{}, key, value); err != nil {
log.Error("Unhandled trie error in StateTrie.Update", "err", err)
}
}
@ -144,7 +144,7 @@ func (t *StateTrie) Update(key, value []byte) {
// stored in the trie.
//
// If a node is not found in the database, a MissingNodeError is returned.
func (t *StateTrie) TryUpdate(key, value []byte) error {
func (t *StateTrie) TryUpdateStorage(_ common.Address, key, value []byte) error {
hk := t.hashKey(key)
err := t.trie.TryUpdate(hk, value)
if err != nil {
@ -171,7 +171,7 @@ func (t *StateTrie) TryUpdateAccount(address common.Address, acc *types.StateAcc
// Delete removes any existing value for key from the trie.
func (t *StateTrie) Delete(key []byte) {
if err := t.TryDelete(key); err != nil {
if err := t.TryDeleteStorage(common.Address{}, key); err != nil {
log.Error("Unhandled trie error in StateTrie.Delete", "err", err)
}
}
@ -179,7 +179,7 @@ func (t *StateTrie) Delete(key []byte) {
// TryDelete removes any existing value for key from the trie.
// If the specified trie node is not in the trie, nothing will be changed.
// If a node is not found in the database, a MissingNodeError is returned.
func (t *StateTrie) TryDelete(key []byte) error {
func (t *StateTrie) TryDeleteStorage(_ common.Address, key []byte) error {
hk := t.hashKey(key)
delete(t.getSecKeyCache(), string(hk))
return t.trie.TryDelete(hk)