mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 18:02:24 +00:00
core: remove resolve code mechanism from statedb, put in vm
This commit is contained in:
parent
7dceb35670
commit
f9e0222507
5 changed files with 37 additions and 60 deletions
|
|
@ -368,24 +368,6 @@ func (s *StateDB) GetCodeHash(addr common.Address) common.Hash {
|
||||||
return 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.
|
// GetState retrieves the value associated with the specific key.
|
||||||
func (s *StateDB) GetState(addr common.Address, hash common.Hash) common.Hash {
|
func (s *StateDB) GetState(addr common.Address, hash common.Hash) common.Hash {
|
||||||
stateObject := s.getStateObject(addr)
|
stateObject := s.getStateObject(addr)
|
||||||
|
|
@ -621,28 +603,6 @@ func (s *StateDB) getStateObject(addr common.Address) *stateObject {
|
||||||
return obj
|
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) {
|
func (s *StateDB) setStateObject(object *stateObject) {
|
||||||
s.stateObjects[object.Address()] = object
|
s.stateObjects[object.Address()] = object
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -73,13 +73,6 @@ func (s *hookedStateDB) GetCodeSize(addr common.Address) int {
|
||||||
return s.inner.GetCodeSize(addr)
|
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) {
|
func (s *hookedStateDB) AddRefund(u uint64) {
|
||||||
s.inner.AddRefund(u)
|
s.inner.AddRefund(u)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -337,7 +337,7 @@ func opExtCodeCopyEIP4762(pc *uint64, interpreter *EVMInterpreter, scope *ScopeC
|
||||||
uint64CodeOffset = math.MaxUint64
|
uint64CodeOffset = math.MaxUint64
|
||||||
}
|
}
|
||||||
addr := common.Address(a.Bytes20())
|
addr := common.Address(a.Bytes20())
|
||||||
code := interpreter.evm.StateDB.ResolveCode(addr)
|
code := interpreter.evm.resolveCode(addr)
|
||||||
contract := &Contract{
|
contract := &Contract{
|
||||||
Code: code,
|
Code: code,
|
||||||
self: AccountRef(addr),
|
self: AccountRef(addr),
|
||||||
|
|
@ -719,7 +719,7 @@ func opExtCodeCopyEIP7702(pc *uint64, interpreter *EVMInterpreter, scope *ScopeC
|
||||||
uint64CodeOffset = math.MaxUint64
|
uint64CodeOffset = math.MaxUint64
|
||||||
}
|
}
|
||||||
addr := common.Address(a.Bytes20())
|
addr := common.Address(a.Bytes20())
|
||||||
code := interpreter.evm.StateDB.ResolveCode(addr)
|
code := interpreter.evm.resolveCode(addr)
|
||||||
codeCopy := getData(code, uint64CodeOffset, length.Uint64())
|
codeCopy := getData(code, uint64CodeOffset, length.Uint64())
|
||||||
scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
|
scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
|
||||||
|
|
||||||
|
|
@ -729,7 +729,7 @@ func opExtCodeCopyEIP7702(pc *uint64, interpreter *EVMInterpreter, scope *ScopeC
|
||||||
// opExtCodeSizeEIP7702 implements the EIP-7702 variation of opExtCodeSize.
|
// opExtCodeSizeEIP7702 implements the EIP-7702 variation of opExtCodeSize.
|
||||||
func opExtCodeSizeEIP7702(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
func opExtCodeSizeEIP7702(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||||
slot := scope.Stack.peek()
|
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
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -740,7 +740,7 @@ func opExtCodeHashEIP7702(pc *uint64, interpreter *EVMInterpreter, scope *ScopeC
|
||||||
if interpreter.evm.StateDB.Empty(address) {
|
if interpreter.evm.StateDB.Empty(address) {
|
||||||
slot.Clear()
|
slot.Clear()
|
||||||
} else {
|
} else {
|
||||||
slot.SetBytes(interpreter.evm.StateDB.ResolveCodeHash(address).Bytes())
|
slot.SetBytes(interpreter.evm.resolveCodeHash(address).Bytes())
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -217,7 +217,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
||||||
} else {
|
} else {
|
||||||
// Initialise a new contract and set the code that is to be used by the EVM.
|
// 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.
|
// The contract is a scoped environment for this execution context only.
|
||||||
code := evm.StateDB.ResolveCode(addr)
|
code := evm.resolveCode(addr)
|
||||||
if len(code) == 0 {
|
if len(code) == 0 {
|
||||||
ret, err = nil, nil // gas is unchanged
|
ret, err = nil, nil // gas is unchanged
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -225,7 +225,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
||||||
// If the account has no code, we can abort here
|
// If the account has no code, we can abort here
|
||||||
// The depth-check is already done, and precompiles handled above
|
// The depth-check is already done, and precompiles handled above
|
||||||
contract := NewContract(caller, AccountRef(addrCopy), value, gas)
|
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)
|
ret, err = evm.interpreter.Run(contract, input, false)
|
||||||
gas = contract.Gas
|
gas = contract.Gas
|
||||||
}
|
}
|
||||||
|
|
@ -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.
|
// 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.
|
// The contract is a scoped environment for this execution context only.
|
||||||
contract := NewContract(caller, AccountRef(caller.Address()), value, gas)
|
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)
|
ret, err = evm.interpreter.Run(contract, input, false)
|
||||||
gas = contract.Gas
|
gas = contract.Gas
|
||||||
}
|
}
|
||||||
|
|
@ -332,7 +332,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
|
||||||
addrCopy := addr
|
addrCopy := addr
|
||||||
// Initialise a new contract and make initialise the delegate values
|
// Initialise a new contract and make initialise the delegate values
|
||||||
contract := NewContract(caller, AccountRef(caller.Address()), nil, gas).AsDelegate()
|
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)
|
ret, err = evm.interpreter.Run(contract, input, false)
|
||||||
gas = contract.Gas
|
gas = contract.Gas
|
||||||
}
|
}
|
||||||
|
|
@ -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.
|
// 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.
|
// The contract is a scoped environment for this execution context only.
|
||||||
contract := NewContract(caller, AccountRef(addrCopy), new(uint256.Int), gas)
|
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
|
// 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
|
// 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.
|
// when we're in Homestead this also counts for code storage gas errors.
|
||||||
|
|
@ -463,7 +463,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
|
||||||
// - the nonce is non-zero
|
// - the nonce is non-zero
|
||||||
// - the code is non-empty
|
// - the code is non-empty
|
||||||
// - the storage is non-empty
|
// - the storage is non-empty
|
||||||
contractHash := evm.StateDB.ResolveCodeHash(address)
|
contractHash := evm.resolveCodeHash(address)
|
||||||
storageRoot := evm.StateDB.GetStorageRoot(address)
|
storageRoot := evm.StateDB.GetStorageRoot(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
|
||||||
|
|
@ -567,6 +567,33 @@ func (evm *EVM) Create2(caller ContractRef, code []byte, gas uint64, endowment *
|
||||||
return evm.create(caller, codeAndHash, gas, endowment, contractAddr, CREATE2)
|
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
|
// ChainConfig returns the environment's chain configuration
|
||||||
func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig }
|
func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,9 +45,6 @@ type StateDB interface {
|
||||||
SetCode(common.Address, []byte)
|
SetCode(common.Address, []byte)
|
||||||
GetCodeSize(common.Address) int
|
GetCodeSize(common.Address) int
|
||||||
|
|
||||||
ResolveCodeHash(common.Address) common.Hash
|
|
||||||
ResolveCode(common.Address) []byte
|
|
||||||
|
|
||||||
AddRefund(uint64)
|
AddRefund(uint64)
|
||||||
SubRefund(uint64)
|
SubRefund(uint64)
|
||||||
GetRefund() uint64
|
GetRefund() uint64
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue