Problem: no efficient GetStorageRoot impl in cosmos/evm (#9)

Solution:
- create a new method IsStorageEmpty to use in core evm
This commit is contained in:
yihuang 2025-08-20 23:23:15 +08:00 committed by GitHub
parent 2fc7571efa
commit 9a3ffad54d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 13 additions and 2 deletions

View file

@ -335,6 +335,12 @@ func (s *StateDB) GetStorageRoot(addr common.Address) common.Hash {
return common.Hash{} return common.Hash{}
} }
// IsStorageEmpty returns if the contract storage is empty
func (s *StateDB) IsStorageEmpty(addr common.Address) bool {
storageRoot := s.GetStorageRoot(addr)
return storageRoot == (common.Hash{}) || storageRoot == types.EmptyRootHash
}
// TxIndex returns the current transaction index set by SetTxContext. // TxIndex returns the current transaction index set by SetTxContext.
func (s *StateDB) TxIndex() int { func (s *StateDB) TxIndex() int {
return s.txIndex return s.txIndex

View file

@ -97,6 +97,10 @@ func (s *hookedStateDB) GetStorageRoot(addr common.Address) common.Hash {
return s.inner.GetStorageRoot(addr) return s.inner.GetStorageRoot(addr)
} }
func (s *hookedStateDB) IsStorageEmpty(addr common.Address) bool {
return s.inner.IsStorageEmpty(addr)
}
func (s *hookedStateDB) GetTransientState(addr common.Address, key common.Hash) common.Hash { func (s *hookedStateDB) GetTransientState(addr common.Address, key common.Hash) common.Hash {
return s.inner.GetTransientState(addr, key) return s.inner.GetTransientState(addr, key)
} }

View file

@ -499,10 +499,10 @@ func (evm *EVM) create(caller common.Address, code []byte, gas uint64, value *ui
// - the code is non-empty // - the code is non-empty
// - the storage is non-empty // - the storage is non-empty
contractHash := evm.StateDB.GetCodeHash(address) contractHash := evm.StateDB.GetCodeHash(address)
storageRoot := evm.StateDB.GetStorageRoot(address) isStorageEmpty := evm.StateDB.IsStorageEmpty(address)
if evm.StateDB.GetNonce(address) != 0 || if evm.StateDB.GetNonce(address) != 0 ||
(contractHash != (common.Hash{}) && contractHash != types.EmptyCodeHash) || // non-empty code (contractHash != (common.Hash{}) && contractHash != types.EmptyCodeHash) || // non-empty code
(storageRoot != (common.Hash{}) && storageRoot != types.EmptyRootHash) { // non-empty storage !isStorageEmpty { // non-empty storage
if evm.Config.Tracer != nil && evm.Config.Tracer.OnGasChange != nil { if evm.Config.Tracer != nil && evm.Config.Tracer.OnGasChange != nil {
evm.Config.Tracer.OnGasChange(gas, 0, tracing.GasChangeCallFailedExecution) evm.Config.Tracer.OnGasChange(gas, 0, tracing.GasChangeCallFailedExecution)
} }

View file

@ -54,6 +54,7 @@ type StateDB interface {
GetState(common.Address, common.Hash) common.Hash GetState(common.Address, common.Hash) common.Hash
SetState(common.Address, common.Hash, common.Hash) common.Hash SetState(common.Address, common.Hash, common.Hash) common.Hash
GetStorageRoot(addr common.Address) common.Hash GetStorageRoot(addr common.Address) common.Hash
IsStorageEmpty(addr common.Address) bool
GetTransientState(addr common.Address, key common.Hash) common.Hash GetTransientState(addr common.Address, key common.Hash) common.Hash
SetTransientState(addr common.Address, key, value common.Hash) SetTransientState(addr common.Address, key, value common.Hash)