aboutsummaryrefslogtreecommitdiffstats
path: root/core/vm
diff options
context:
space:
mode:
authorJeffrey Wilcke <jeffrey@ethereum.org>2017-02-23 06:29:59 +0800
committerFelix Lange <fjl@users.noreply.github.com>2017-02-23 06:29:59 +0800
commit024d41d0c2660d8f1dfbeb14921c7109e30493a2 (patch)
treea2b4ed630b84084c7f439d1539ed0551ec729cbd /core/vm
parent46ec4357e73dd0c43951d11638d9aed94f8ffd29 (diff)
downloaddexon-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.go29
-rw-r--r--core/vm/evm.go18
-rw-r--r--core/vm/interface.go17
-rw-r--r--core/vm/logger.go3
-rw-r--r--core/vm/logger_test.go4
-rw-r--r--core/vm/noop.go46
-rw-r--r--core/vm/runtime/runtime.go14
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.