diff options
author | Jeffrey Wilcke <jeffrey@ethereum.org> | 2017-02-23 06:29:59 +0800 |
---|---|---|
committer | Felix Lange <fjl@users.noreply.github.com> | 2017-02-23 06:29:59 +0800 |
commit | 024d41d0c2660d8f1dfbeb14921c7109e30493a2 (patch) | |
tree | a2b4ed630b84084c7f439d1539ed0551ec729cbd /core/vm | |
parent | 46ec4357e73dd0c43951d11638d9aed94f8ffd29 (diff) | |
download | dexon-024d41d0c2660d8f1dfbeb14921c7109e30493a2.tar.gz dexon-024d41d0c2660d8f1dfbeb14921c7109e30493a2.tar.zst dexon-024d41d0c2660d8f1dfbeb14921c7109e30493a2.zip |
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.
Diffstat (limited to 'core/vm')
-rw-r--r-- | core/vm/contract.go | 29 | ||||
-rw-r--r-- | core/vm/evm.go | 18 | ||||
-rw-r--r-- | core/vm/interface.go | 17 | ||||
-rw-r--r-- | core/vm/logger.go | 3 | ||||
-rw-r--r-- | core/vm/logger_test.go | 4 | ||||
-rw-r--r-- | core/vm/noop.go | 46 | ||||
-rw-r--r-- | core/vm/runtime/runtime.go | 14 |
7 files changed, 60 insertions, 71 deletions
diff --git a/core/vm/contract.go b/core/vm/contract.go index 091106d84..66748e821 100644 --- a/core/vm/contract.go +++ b/core/vm/contract.go @@ -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) -} diff --git a/core/vm/evm.go b/core/vm/evm.go index 0c5d998c2..d1fac6c10 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -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) diff --git a/core/vm/interface.go b/core/vm/interface.go index 6f15112ee..4d8ece41c 100644 --- a/core/vm/interface.go +++ b/core/vm/interface.go @@ -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 diff --git a/core/vm/logger.go b/core/vm/logger.go index db8c20e07..3845b1073 100644 --- a/core/vm/logger.go +++ b/core/vm/logger.go @@ -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 diff --git a/core/vm/logger_test.go b/core/vm/logger_test.go index ca60cba43..e755a18e2 100644 --- a/core/vm/logger_test.go +++ b/core/vm/logger_test.go @@ -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}) diff --git a/core/vm/noop.go b/core/vm/noop.go index 7835eeaf3..2a04a9565 100644 --- a/core/vm/noop.go +++ b/core/vm/noop.go @@ -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) {} diff --git a/core/vm/runtime/runtime.go b/core/vm/runtime/runtime.go index cf46603db..94265626f 100644 --- a/core/vm/runtime/runtime.go +++ b/core/vm/runtime/runtime.go @@ -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. |