diff --git a/core/state/state_object.go b/core/state/state_object.go index a6979bd361..0fa96c47f2 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -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() diff --git a/core/state/statedb.go b/core/state/statedb.go index e3f5b9e1a0..f5abfbd8ff 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -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 } diff --git a/core/state/stateupdate.go b/core/state/stateupdate.go index 75c4ca028c..210e704346 100644 --- a/core/state/stateupdate.go +++ b/core/state/stateupdate.go @@ -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 {