core/state: store storageOrigin in one map

Signed-off-by: jsvisa <delweng@gmail.com>
This commit is contained in:
jsvisa 2025-03-25 12:18:28 +00:00
parent 6928ec5d92
commit f595cb6653
3 changed files with 24 additions and 26 deletions

View file

@ -375,7 +375,7 @@ func (s *stateObject) updateRoot() {
// commitStorage overwrites the clean storage with the storage changes and
// fulfills the storage diffs into the given accountUpdate struct.
func (s *stateObject) commitStorage(op *accountUpdate) {
func (s *stateObject) commitStorage(op *accountUpdate, rawStorageKey bool) {
var (
buf = crypto.NewKeccakState()
encode = func(val common.Hash) []byte {
@ -400,15 +400,15 @@ func (s *stateObject) commitStorage(op *accountUpdate) {
}
op.storages[hash] = encode(val)
if op.storagesOriginByKey == nil {
op.storagesOriginByKey = make(map[common.Hash][]byte)
}
if op.storagesOriginByHash == nil {
op.storagesOriginByHash = make(map[common.Hash][]byte)
if op.storagesOrigin == nil {
op.storagesOrigin = make(map[common.Hash][]byte)
}
origin := encode(s.originStorage[key])
op.storagesOriginByKey[key] = origin
op.storagesOriginByHash[hash] = origin
if rawStorageKey {
op.storagesOrigin[key] = origin
} else {
op.storagesOrigin[hash] = origin
}
// Overwrite the clean value of storage slots
s.originStorage[key] = val
@ -421,7 +421,7 @@ func (s *stateObject) commitStorage(op *accountUpdate) {
//
// Note, commit may run concurrently across all the state objects. Do not assume
// thread-safe access to the statedb.
func (s *stateObject) commit() (*accountUpdate, *trienode.NodeSet, error) {
func (s *stateObject) commit(rawStorageKey bool) (*accountUpdate, *trienode.NodeSet, error) {
// commit the account metadata changes
op := &accountUpdate{
address: s.address,
@ -439,7 +439,7 @@ func (s *stateObject) commit() (*accountUpdate, *trienode.NodeSet, error) {
s.dirtyCode = false // reset the dirty flag
}
// Commit storage changes and the associated storage trie
s.commitStorage(op)
s.commitStorage(op, rawStorageKey)
if len(op.storages) == 0 {
// nothing changed, don't bother to commit the trie
s.origin = s.data.Copy()

View file

@ -1213,7 +1213,7 @@ func (s *StateDB) commit(deleteEmptyObjects bool, noStorageWiping bool) (*stateU
// Run the storage updates concurrently to one another
workers.Go(func() error {
// Write any storage changes in the state object to its storage trie
update, set, err := obj.commit()
update, set, err := obj.commit(noStorageWiping)
if err != nil {
return err
}

View file

@ -46,18 +46,19 @@ type accountDelete struct {
// accountUpdate represents an operation for updating an Ethereum account.
type accountUpdate struct {
address common.Address // address is the unique account identifier
data []byte // data is the slim-RLP encoded account data.
origin []byte // origin is the original value of account data in slim-RLP encoding.
code *contractCode // code represents mutated contract code; nil means it's not modified.
storages map[common.Hash][]byte // storages stores mutated slots in prefix-zero-trimmed RLP format.
address common.Address // address is the unique account identifier
data []byte // data is the slim-RLP encoded account data.
origin []byte // origin is the original value of account data in slim-RLP encoding.
code *contractCode // code represents mutated contract code; nil means it's not modified.
// storagesOriginByKey and storagesOriginByHash both store the original values
// of mutated slots in prefix-zero-trimmed RLP format. The difference is that
// storagesOriginByKey uses the **raw** storage slot key as the map ID, while
// storagesOriginByHash uses the **hash** of the storage slot key instead.
storagesOriginByKey map[common.Hash][]byte
storagesOriginByHash map[common.Hash][]byte
// storages stores mutated slots in prefix-zero-trimmed RLP format,
// The map key refers to the **HASH** of the raw storage slot key.
storages map[common.Hash][]byte
// storagesOrigin store the original values of mutated slots in prefix-zero-trimmed RLP format.
// if `rawStorageKey` is true, the map key refers to the **RAW** storage slot key,
// else the **HASH** of the raw storage slot key.
storagesOrigin map[common.Hash][]byte
}
// stateUpdate represents the difference between two states resulting from state
@ -144,10 +145,7 @@ func newStateUpdate(rawStorageKey bool, originRoot common.Hash, root common.Hash
}
// Aggregate the storage original values. If the slot is already present
// in aggregated storagesOrigin set, skip it.
storageOriginSet := op.storagesOriginByHash
if rawStorageKey {
storageOriginSet = op.storagesOriginByKey
}
storageOriginSet := op.storagesOrigin
if len(storageOriginSet) > 0 {
origin, exist := storagesOrigin[addr]
if !exist {