Skip to content

Commit

Permalink
core: remove resolve code mechanism from statedb, put in vm
Browse files Browse the repository at this point in the history
  • Loading branch information
lightclient committed Dec 12, 2024
1 parent 7dceb35 commit f9e0222
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 60 deletions.
40 changes: 0 additions & 40 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -368,24 +368,6 @@ func (s *StateDB) GetCodeHash(addr common.Address) common.Hash {
return common.Hash{}
}

// ResolveCode retrieves the code at addr, resolving any delegation designations
// that may exist.
func (s *StateDB) ResolveCode(addr common.Address) []byte {
if obj := s.resolveCode(addr); obj != nil {
return obj.Code()
}
return nil
}

// ResolveCodeHash retrieves the code at addr, resolving any delegation
// designations that may exist.
func (s *StateDB) ResolveCodeHash(addr common.Address) common.Hash {
if obj := s.resolveCode(addr); obj != nil {
return common.BytesToHash(obj.CodeHash())
}
return common.Hash{}
}

// GetState retrieves the value associated with the specific key.
func (s *StateDB) GetState(addr common.Address, hash common.Hash) common.Hash {
stateObject := s.getStateObject(addr)
Expand Down Expand Up @@ -621,28 +603,6 @@ func (s *StateDB) getStateObject(addr common.Address) *stateObject {
return obj
}

// resolveStateObject follows delegation designations to resolve a state object
// given by the address, returning nil if the object is not found or was deleted
// in this execution context.
func (s *StateDB) resolveCode(addr common.Address) *stateObject {
obj := s.getStateObject(addr)
if obj == nil {
return nil
}
if s.witness != nil {
s.witness.AddCode(obj.Code())
}
addr, ok := types.ParseDelegation(obj.Code())
if !ok {
return obj
}
obj = s.getStateObject(addr)
if obj != nil && s.witness != nil {
s.witness.AddCode(obj.Code())
}
return obj
}

func (s *StateDB) setStateObject(object *stateObject) {
s.stateObjects[object.Address()] = object
}
Expand Down
7 changes: 0 additions & 7 deletions core/state/statedb_hooked.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,6 @@ func (s *hookedStateDB) GetCodeSize(addr common.Address) int {
return s.inner.GetCodeSize(addr)
}

func (s *hookedStateDB) ResolveCodeHash(addr common.Address) common.Hash {
return s.inner.ResolveCodeHash(addr)
}
func (s *hookedStateDB) ResolveCode(addr common.Address) []byte {
return s.inner.ResolveCode(addr)
}

func (s *hookedStateDB) AddRefund(u uint64) {
s.inner.AddRefund(u)
}
Expand Down
8 changes: 4 additions & 4 deletions core/vm/eips.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ func opExtCodeCopyEIP4762(pc *uint64, interpreter *EVMInterpreter, scope *ScopeC
uint64CodeOffset = math.MaxUint64
}
addr := common.Address(a.Bytes20())
code := interpreter.evm.StateDB.ResolveCode(addr)
code := interpreter.evm.resolveCode(addr)
contract := &Contract{
Code: code,
self: AccountRef(addr),
Expand Down Expand Up @@ -719,7 +719,7 @@ func opExtCodeCopyEIP7702(pc *uint64, interpreter *EVMInterpreter, scope *ScopeC
uint64CodeOffset = math.MaxUint64
}
addr := common.Address(a.Bytes20())
code := interpreter.evm.StateDB.ResolveCode(addr)
code := interpreter.evm.resolveCode(addr)
codeCopy := getData(code, uint64CodeOffset, length.Uint64())
scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)

Expand All @@ -729,7 +729,7 @@ func opExtCodeCopyEIP7702(pc *uint64, interpreter *EVMInterpreter, scope *ScopeC
// opExtCodeSizeEIP7702 implements the EIP-7702 variation of opExtCodeSize.
func opExtCodeSizeEIP7702(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
slot := scope.Stack.peek()
slot.SetUint64(uint64(len(interpreter.evm.StateDB.ResolveCode(slot.Bytes20()))))
slot.SetUint64(uint64(len(interpreter.evm.resolveCode(slot.Bytes20()))))
return nil, nil
}

Expand All @@ -740,7 +740,7 @@ func opExtCodeHashEIP7702(pc *uint64, interpreter *EVMInterpreter, scope *ScopeC
if interpreter.evm.StateDB.Empty(address) {
slot.Clear()
} else {
slot.SetBytes(interpreter.evm.StateDB.ResolveCodeHash(address).Bytes())
slot.SetBytes(interpreter.evm.resolveCodeHash(address).Bytes())
}
return nil, nil
}
Expand Down
39 changes: 33 additions & 6 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,15 +217,15 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
} else {
// Initialise a new contract and set the code that is to be used by the EVM.
// The contract is a scoped environment for this execution context only.
code := evm.StateDB.ResolveCode(addr)
code := evm.resolveCode(addr)
if len(code) == 0 {
ret, err = nil, nil // gas is unchanged
} else {
addrCopy := addr
// If the account has no code, we can abort here
// The depth-check is already done, and precompiles handled above
contract := NewContract(caller, AccountRef(addrCopy), value, gas)
contract.SetCallCode(&addrCopy, evm.StateDB.ResolveCodeHash(addrCopy), code)
contract.SetCallCode(&addrCopy, evm.resolveCodeHash(addrCopy), code)
ret, err = evm.interpreter.Run(contract, input, false)
gas = contract.Gas
}
Expand Down Expand Up @@ -285,7 +285,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
// Initialise a new contract and set the code that is to be used by the EVM.
// The contract is a scoped environment for this execution context only.
contract := NewContract(caller, AccountRef(caller.Address()), value, gas)
contract.SetCallCode(&addrCopy, evm.StateDB.ResolveCodeHash(addrCopy), evm.StateDB.ResolveCode(addrCopy))
contract.SetCallCode(&addrCopy, evm.resolveCodeHash(addrCopy), evm.resolveCode(addrCopy))
ret, err = evm.interpreter.Run(contract, input, false)
gas = contract.Gas
}
Expand Down Expand Up @@ -332,7 +332,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
addrCopy := addr
// Initialise a new contract and make initialise the delegate values
contract := NewContract(caller, AccountRef(caller.Address()), nil, gas).AsDelegate()
contract.SetCallCode(&addrCopy, evm.StateDB.ResolveCodeHash(addrCopy), evm.StateDB.ResolveCode(addrCopy))
contract.SetCallCode(&addrCopy, evm.resolveCodeHash(addrCopy), evm.resolveCode(addrCopy))
ret, err = evm.interpreter.Run(contract, input, false)
gas = contract.Gas
}
Expand Down Expand Up @@ -387,7 +387,7 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
// Initialise a new contract and set the code that is to be used by the EVM.
// The contract is a scoped environment for this execution context only.
contract := NewContract(caller, AccountRef(addrCopy), new(uint256.Int), gas)
contract.SetCallCode(&addrCopy, evm.StateDB.ResolveCodeHash(addrCopy), evm.StateDB.ResolveCode(addrCopy))
contract.SetCallCode(&addrCopy, evm.resolveCodeHash(addrCopy), evm.resolveCode(addrCopy))
// When an error was returned by the EVM or when setting the creation code
// above we revert to the snapshot and consume any gas remaining. Additionally
// when we're in Homestead this also counts for code storage gas errors.
Expand Down Expand Up @@ -463,7 +463,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
// - the nonce is non-zero
// - the code is non-empty
// - the storage is non-empty
contractHash := evm.StateDB.ResolveCodeHash(address)
contractHash := evm.resolveCodeHash(address)
storageRoot := evm.StateDB.GetStorageRoot(address)
if evm.StateDB.GetNonce(address) != 0 ||
(contractHash != (common.Hash{}) && contractHash != types.EmptyCodeHash) || // non-empty code
Expand Down Expand Up @@ -567,6 +567,33 @@ func (evm *EVM) Create2(caller ContractRef, code []byte, gas uint64, endowment *
return evm.create(caller, codeAndHash, gas, endowment, contractAddr, CREATE2)
}

// resolveCode returns the code associated with the provided account. After
// Prague, it can also resolve code pointed to by a delegation designator.
func (evm *EVM) resolveCode(addr common.Address) []byte {
code := evm.StateDB.GetCode(addr)
if !evm.chainRules.IsPrague {
return code
}
if target, ok := types.ParseDelegation(code); ok {
return evm.StateDB.GetCode(target)
}
return code
}

// resolveCodeHash returns the code hash associated with the provided address.
// After Prague, it can also resolve code hash of the account pointed to by a
// delegation designator.
func (evm *EVM) resolveCodeHash(addr common.Address) common.Hash {
if !evm.chainRules.IsPrague {
return evm.StateDB.GetCodeHash(addr)
}
code := evm.StateDB.GetCode(addr)
if target, ok := types.ParseDelegation(code); ok {
return evm.StateDB.GetCodeHash(target)
}
return evm.StateDB.GetCodeHash(addr)
}

// ChainConfig returns the environment's chain configuration
func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig }

Expand Down
3 changes: 0 additions & 3 deletions core/vm/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ type StateDB interface {
SetCode(common.Address, []byte)
GetCodeSize(common.Address) int

ResolveCodeHash(common.Address) common.Hash
ResolveCode(common.Address) []byte

AddRefund(uint64)
SubRefund(uint64)
GetRefund() uint64
Expand Down

0 comments on commit f9e0222

Please sign in to comment.