core, core/state, core/vm: remove exported account getters (#3618)
Removed exported statedb object accessors, reducing the chance for nasty bugs to creep in. It's also ugly and unnecessary to have these methods.
This commit is contained in:
committed by
Felix Lange
parent
46ec4357e7
commit
024d41d0c2
@ -25,11 +25,20 @@ import (
|
||||
// ContractRef is a reference to the contract's backing object
|
||||
type ContractRef interface {
|
||||
Address() common.Address
|
||||
Value() *big.Int
|
||||
SetCode(common.Hash, []byte)
|
||||
ForEachStorage(callback func(key, value common.Hash) bool)
|
||||
}
|
||||
|
||||
// AccountRef implements ContractRef.
|
||||
//
|
||||
// Account references are used during EVM initialisation and
|
||||
// it's primary use is to fetch addresses. Removing this object
|
||||
// proves difficult because of the cached jump destinations which
|
||||
// are fetched from the parent contract (i.e. the caller), which
|
||||
// is a ContractRef.
|
||||
type AccountRef common.Address
|
||||
|
||||
// Address casts AccountRef to a Address
|
||||
func (ar AccountRef) Address() common.Address { return (common.Address)(ar) }
|
||||
|
||||
// Contract represents an ethereum contract in the state database. It contains
|
||||
// the the contract code, calling arguments. Contract implements ContractRef
|
||||
type Contract struct {
|
||||
@ -69,7 +78,8 @@ func NewContract(caller ContractRef, object ContractRef, value *big.Int, gas uin
|
||||
// Gas should be a pointer so it can safely be reduced through the run
|
||||
// This pointer will be off the state transition
|
||||
c.Gas = gas
|
||||
c.value = new(big.Int).Set(value)
|
||||
// ensures a value is set
|
||||
c.value = value
|
||||
|
||||
return c
|
||||
}
|
||||
@ -80,7 +90,10 @@ func (c *Contract) AsDelegate() *Contract {
|
||||
c.DelegateCall = true
|
||||
// NOTE: caller must, at all times be a contract. It should never happen
|
||||
// that caller is something other than a Contract.
|
||||
c.CallerAddress = c.caller.(*Contract).CallerAddress
|
||||
parent := c.caller.(*Contract)
|
||||
c.CallerAddress = parent.CallerAddress
|
||||
c.value = parent.value
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
@ -138,9 +151,3 @@ func (self *Contract) SetCallCode(addr *common.Address, hash common.Hash, code [
|
||||
self.CodeHash = hash
|
||||
self.CodeAddr = addr
|
||||
}
|
||||
|
||||
// EachStorage iterates the contract's storage and calls a method for every key
|
||||
// value pair.
|
||||
func (self *Contract) ForEachStorage(cb func(key, value common.Hash) bool) {
|
||||
self.caller.ForEachStorage(cb)
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
||||
}
|
||||
|
||||
var (
|
||||
to Account
|
||||
to = AccountRef(addr)
|
||||
snapshot = evm.StateDB.Snapshot()
|
||||
)
|
||||
if !evm.StateDB.Exist(addr) {
|
||||
@ -124,9 +124,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
||||
return nil, gas, nil
|
||||
}
|
||||
|
||||
to = evm.StateDB.CreateAccount(addr)
|
||||
} else {
|
||||
to = evm.StateDB.GetAccount(addr)
|
||||
evm.StateDB.CreateAccount(addr)
|
||||
}
|
||||
evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value)
|
||||
|
||||
@ -169,7 +167,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
|
||||
|
||||
var (
|
||||
snapshot = evm.StateDB.Snapshot()
|
||||
to = evm.StateDB.GetAccount(caller.Address())
|
||||
to = AccountRef(caller.Address())
|
||||
)
|
||||
// initialise a new contract and set the code that is to be used by the
|
||||
// E The contract is a scoped evmironment for this execution context
|
||||
@ -205,11 +203,11 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
|
||||
|
||||
var (
|
||||
snapshot = evm.StateDB.Snapshot()
|
||||
to = evm.StateDB.GetAccount(caller.Address())
|
||||
to = AccountRef(caller.Address())
|
||||
)
|
||||
|
||||
// Iinitialise a new contract and make initialise the delegate values
|
||||
contract := NewContract(caller, to, caller.Value(), gas).AsDelegate()
|
||||
contract := NewContract(caller, to, nil, gas).AsDelegate()
|
||||
contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr))
|
||||
|
||||
ret, err = evm.interpreter.Run(contract, input)
|
||||
@ -243,16 +241,16 @@ func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.I
|
||||
|
||||
snapshot := evm.StateDB.Snapshot()
|
||||
contractAddr = crypto.CreateAddress(caller.Address(), nonce)
|
||||
to := evm.StateDB.CreateAccount(contractAddr)
|
||||
evm.StateDB.CreateAccount(contractAddr)
|
||||
if evm.ChainConfig().IsEIP158(evm.BlockNumber) {
|
||||
evm.StateDB.SetNonce(contractAddr, 1)
|
||||
}
|
||||
evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value)
|
||||
evm.Transfer(evm.StateDB, caller.Address(), contractAddr, value)
|
||||
|
||||
// initialise a new contract and set the code that is to be used by the
|
||||
// E The contract is a scoped evmironment for this execution context
|
||||
// only.
|
||||
contract := NewContract(caller, to, value, gas)
|
||||
contract := NewContract(caller, AccountRef(contractAddr), value, gas)
|
||||
contract.SetCallCode(&contractAddr, crypto.Keccak256Hash(code), code)
|
||||
|
||||
ret, err = evm.interpreter.Run(contract, nil)
|
||||
|
@ -25,8 +25,7 @@ import (
|
||||
|
||||
// StateDB is an EVM database for full state querying.
|
||||
type StateDB interface {
|
||||
GetAccount(common.Address) Account
|
||||
CreateAccount(common.Address) Account
|
||||
CreateAccount(common.Address)
|
||||
|
||||
SubBalance(common.Address, *big.Int)
|
||||
AddBalance(common.Address, *big.Int)
|
||||
@ -61,20 +60,8 @@ type StateDB interface {
|
||||
|
||||
AddLog(*types.Log)
|
||||
AddPreimage(common.Hash, []byte)
|
||||
}
|
||||
|
||||
// Account represents a contract or basic ethereum account.
|
||||
type Account interface {
|
||||
SubBalance(amount *big.Int)
|
||||
AddBalance(amount *big.Int)
|
||||
SetBalance(*big.Int)
|
||||
SetNonce(uint64)
|
||||
Balance() *big.Int
|
||||
Address() common.Address
|
||||
ReturnGas(*big.Int)
|
||||
SetCode(common.Hash, []byte)
|
||||
ForEachStorage(cb func(key, value common.Hash) bool)
|
||||
Value() *big.Int
|
||||
ForEachStorage(common.Address, func(common.Hash, common.Hash) bool)
|
||||
}
|
||||
|
||||
// CallContext provides a basic interface for the EVM calling conventions. The EVM EVM
|
||||
|
@ -144,7 +144,8 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost *b
|
||||
storage = make(Storage)
|
||||
// Get the contract account and loop over each storage entry. This may involve looping over
|
||||
// the trie and is a very expensive process.
|
||||
env.StateDB.GetAccount(contract.Address()).ForEachStorage(func(key, value common.Hash) bool {
|
||||
|
||||
env.StateDB.ForEachStorage(contract.Address(), func(key, value common.Hash) bool {
|
||||
storage[key] = value
|
||||
// Return true, indicating we'd like to continue.
|
||||
return true
|
||||
|
@ -46,10 +46,6 @@ type dummyStateDB struct {
|
||||
ref *dummyContractRef
|
||||
}
|
||||
|
||||
func (d dummyStateDB) GetAccount(common.Address) Account {
|
||||
return d.ref
|
||||
}
|
||||
|
||||
func TestStoreCapture(t *testing.T) {
|
||||
var (
|
||||
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{EnableJit: false, ForceJit: false})
|
||||
|
@ -45,26 +45,26 @@ func (NoopEVMCallContext) DelegateCall(me ContractRef, addr common.Address, data
|
||||
|
||||
type NoopStateDB struct{}
|
||||
|
||||
func (NoopStateDB) GetAccount(common.Address) Account { return nil }
|
||||
func (NoopStateDB) CreateAccount(common.Address) Account { return nil }
|
||||
func (NoopStateDB) SubBalance(common.Address, *big.Int) {}
|
||||
func (NoopStateDB) AddBalance(common.Address, *big.Int) {}
|
||||
func (NoopStateDB) GetBalance(common.Address) *big.Int { return nil }
|
||||
func (NoopStateDB) GetNonce(common.Address) uint64 { return 0 }
|
||||
func (NoopStateDB) SetNonce(common.Address, uint64) {}
|
||||
func (NoopStateDB) GetCodeHash(common.Address) common.Hash { return common.Hash{} }
|
||||
func (NoopStateDB) GetCode(common.Address) []byte { return nil }
|
||||
func (NoopStateDB) SetCode(common.Address, []byte) {}
|
||||
func (NoopStateDB) GetCodeSize(common.Address) int { return 0 }
|
||||
func (NoopStateDB) AddRefund(*big.Int) {}
|
||||
func (NoopStateDB) GetRefund() *big.Int { return nil }
|
||||
func (NoopStateDB) GetState(common.Address, common.Hash) common.Hash { return common.Hash{} }
|
||||
func (NoopStateDB) SetState(common.Address, common.Hash, common.Hash) {}
|
||||
func (NoopStateDB) Suicide(common.Address) bool { return false }
|
||||
func (NoopStateDB) HasSuicided(common.Address) bool { return false }
|
||||
func (NoopStateDB) Exist(common.Address) bool { return false }
|
||||
func (NoopStateDB) Empty(common.Address) bool { return false }
|
||||
func (NoopStateDB) RevertToSnapshot(int) {}
|
||||
func (NoopStateDB) Snapshot() int { return 0 }
|
||||
func (NoopStateDB) AddLog(*types.Log) {}
|
||||
func (NoopStateDB) AddPreimage(common.Hash, []byte) {}
|
||||
func (NoopStateDB) CreateAccount(common.Address) {}
|
||||
func (NoopStateDB) SubBalance(common.Address, *big.Int) {}
|
||||
func (NoopStateDB) AddBalance(common.Address, *big.Int) {}
|
||||
func (NoopStateDB) GetBalance(common.Address) *big.Int { return nil }
|
||||
func (NoopStateDB) GetNonce(common.Address) uint64 { return 0 }
|
||||
func (NoopStateDB) SetNonce(common.Address, uint64) {}
|
||||
func (NoopStateDB) GetCodeHash(common.Address) common.Hash { return common.Hash{} }
|
||||
func (NoopStateDB) GetCode(common.Address) []byte { return nil }
|
||||
func (NoopStateDB) SetCode(common.Address, []byte) {}
|
||||
func (NoopStateDB) GetCodeSize(common.Address) int { return 0 }
|
||||
func (NoopStateDB) AddRefund(*big.Int) {}
|
||||
func (NoopStateDB) GetRefund() *big.Int { return nil }
|
||||
func (NoopStateDB) GetState(common.Address, common.Hash) common.Hash { return common.Hash{} }
|
||||
func (NoopStateDB) SetState(common.Address, common.Hash, common.Hash) {}
|
||||
func (NoopStateDB) Suicide(common.Address) bool { return false }
|
||||
func (NoopStateDB) HasSuicided(common.Address) bool { return false }
|
||||
func (NoopStateDB) Exist(common.Address) bool { return false }
|
||||
func (NoopStateDB) Empty(common.Address) bool { return false }
|
||||
func (NoopStateDB) RevertToSnapshot(int) {}
|
||||
func (NoopStateDB) Snapshot() int { return 0 }
|
||||
func (NoopStateDB) AddLog(*types.Log) {}
|
||||
func (NoopStateDB) AddPreimage(common.Hash, []byte) {}
|
||||
func (NoopStateDB) ForEachStorage(common.Address, func(common.Hash, common.Hash) bool) {}
|
||||
|
@ -105,17 +105,17 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
|
||||
cfg.State, _ = state.New(common.Hash{}, db)
|
||||
}
|
||||
var (
|
||||
vmenv = NewEnv(cfg, cfg.State)
|
||||
sender = cfg.State.CreateAccount(cfg.Origin)
|
||||
receiver = cfg.State.CreateAccount(common.StringToAddress("contract"))
|
||||
address = common.StringToAddress("contract")
|
||||
vmenv = NewEnv(cfg, cfg.State)
|
||||
sender = vm.AccountRef(cfg.Origin)
|
||||
)
|
||||
cfg.State.CreateAccount(address)
|
||||
// set the receiver's (the executing contract) code for execution.
|
||||
receiver.SetCode(crypto.Keccak256Hash(code), code)
|
||||
|
||||
cfg.State.SetCode(address, code)
|
||||
// Call the code with the given configuration.
|
||||
ret, _, err := vmenv.Call(
|
||||
sender,
|
||||
receiver.Address(),
|
||||
common.StringToAddress("contract"),
|
||||
input,
|
||||
cfg.GasLimit,
|
||||
cfg.Value,
|
||||
@ -137,7 +137,7 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, error) {
|
||||
}
|
||||
var (
|
||||
vmenv = NewEnv(cfg, cfg.State)
|
||||
sender = cfg.State.CreateAccount(cfg.Origin)
|
||||
sender = vm.AccountRef(cfg.Origin)
|
||||
)
|
||||
|
||||
// Call the code with the given configuration.
|
||||
|
Reference in New Issue
Block a user