aboutsummaryrefslogtreecommitdiffstats
path: root/light/vm_env.go
diff options
context:
space:
mode:
authorJeffrey Wilcke <jeffrey@ethereum.org>2016-12-06 09:16:03 +0800
committerFelix Lange <fjl@twurst.com>2016-12-06 09:16:03 +0800
commit3fc7c978277051391f8ea7831559e9f4f83c3166 (patch)
treeb11b41c1723e02adc098ddc9f4188a8bad782ed8 /light/vm_env.go
parent7f79d249a64ee72b185ffa9a9ed78f137b7938de (diff)
downloadgo-tangerine-3fc7c978277051391f8ea7831559e9f4f83c3166.tar.gz
go-tangerine-3fc7c978277051391f8ea7831559e9f4f83c3166.tar.zst
go-tangerine-3fc7c978277051391f8ea7831559e9f4f83c3166.zip
core, core/vm: implemented a generic environment (#3348)
Environment is now a struct (not an interface). This reduces a lot of tech-debt throughout the codebase where a virtual machine environment had to be implemented in order to test or run it. The new environment is suitable to be used en the json tests, core consensus and light client.
Diffstat (limited to 'light/vm_env.go')
-rw-r--r--light/vm_env.go119
1 files changed, 20 insertions, 99 deletions
diff --git a/light/vm_env.go b/light/vm_env.go
index d4d7bcce7..cc0c568c9 100644
--- a/light/vm_env.go
+++ b/light/vm_env.go
@@ -20,123 +20,38 @@ import (
"math/big"
"github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/params"
"golang.org/x/net/context"
)
-// VMEnv is the light client version of the vm execution environment.
-// Unlike other structures, VMEnv holds a context that is applied by state
-// retrieval requests through the entire execution. If any state operation
-// returns an error, the execution fails.
-type VMEnv struct {
- vm.Environment
- ctx context.Context
- chainConfig *params.ChainConfig
- evm *vm.EVM
- state *VMState
- header *types.Header
- msg core.Message
- depth int
- chain *LightChain
- err error
-}
-
-// NewEnv creates a new execution environment based on an ODR capable light state
-func NewEnv(ctx context.Context, state *LightState, chainConfig *params.ChainConfig, chain *LightChain, msg core.Message, header *types.Header, cfg vm.Config) *VMEnv {
- env := &VMEnv{
- chainConfig: chainConfig,
- chain: chain,
- header: header,
- msg: msg,
- }
- env.state = &VMState{ctx: ctx, state: state, env: env}
-
- env.evm = vm.New(env, cfg)
- return env
-}
-
-func (self *VMEnv) ChainConfig() *params.ChainConfig { return self.chainConfig }
-func (self *VMEnv) Vm() vm.Vm { return self.evm }
-func (self *VMEnv) Origin() common.Address { return self.msg.From() }
-func (self *VMEnv) BlockNumber() *big.Int { return self.header.Number }
-func (self *VMEnv) Coinbase() common.Address { return self.header.Coinbase }
-func (self *VMEnv) Time() *big.Int { return self.header.Time }
-func (self *VMEnv) Difficulty() *big.Int { return self.header.Difficulty }
-func (self *VMEnv) GasLimit() *big.Int { return self.header.GasLimit }
-func (self *VMEnv) Db() vm.Database { return self.state }
-func (self *VMEnv) Depth() int { return self.depth }
-func (self *VMEnv) SetDepth(i int) { self.depth = i }
-func (self *VMEnv) GetHash(n uint64) common.Hash {
- for header := self.chain.GetHeader(self.header.ParentHash, self.header.Number.Uint64()-1); header != nil; header = self.chain.GetHeader(header.ParentHash, header.Number.Uint64()-1) {
- if header.Number.Uint64() == n {
- return header.Hash()
- }
- }
-
- return common.Hash{}
-}
-
-func (self *VMEnv) AddLog(log *vm.Log) {
- //self.state.AddLog(log)
-}
-func (self *VMEnv) CanTransfer(from common.Address, balance *big.Int) bool {
- return self.state.GetBalance(from).Cmp(balance) >= 0
-}
-
-func (self *VMEnv) SnapshotDatabase() int {
- return self.state.SnapshotDatabase()
-}
-
-func (self *VMEnv) RevertToSnapshot(idx int) {
- self.state.RevertToSnapshot(idx)
-}
-
-func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) {
- core.Transfer(from, to, amount)
-}
-
-func (self *VMEnv) Call(me vm.ContractRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) {
- return core.Call(self, me, addr, data, gas, price, value)
-}
-func (self *VMEnv) CallCode(me vm.ContractRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) {
- return core.CallCode(self, me, addr, data, gas, price, value)
-}
-
-func (self *VMEnv) DelegateCall(me vm.ContractRef, addr common.Address, data []byte, gas, price *big.Int) ([]byte, error) {
- return core.DelegateCall(self, me, addr, data, gas, price)
-}
-
-func (self *VMEnv) Create(me vm.ContractRef, data []byte, gas, price, value *big.Int) ([]byte, common.Address, error) {
- return core.Create(self, me, data, gas, price, value)
-}
-
-// Error returns the error (if any) that happened during execution.
-func (self *VMEnv) Error() error {
- return self.err
-}
-
// VMState is a wrapper for the light state that holds the actual context and
// passes it to any state operation that requires it.
type VMState struct {
- vm.Database
ctx context.Context
state *LightState
snapshots []*LightState
- env *VMEnv
+ err error
+}
+
+func NewVMState(ctx context.Context, state *LightState) *VMState {
+ return &VMState{ctx: ctx, state: state}
+}
+
+func (s *VMState) Error() error {
+ return s.err
}
+func (s *VMState) AddLog(log *vm.Log) {}
+
// errHandler handles and stores any state error that happens during execution.
func (s *VMState) errHandler(err error) {
- if err != nil && s.env.err == nil {
- s.env.err = err
+ if err != nil && s.err == nil {
+ s.err = err
}
}
-func (self *VMState) SnapshotDatabase() int {
+func (self *VMState) Snapshot() int {
self.snapshots = append(self.snapshots, self.state.Copy())
return len(self.snapshots) - 1
}
@@ -175,6 +90,12 @@ func (s *VMState) AddBalance(addr common.Address, amount *big.Int) {
s.errHandler(err)
}
+// SubBalance adds the given amount to the balance of the specified account
+func (s *VMState) SubBalance(addr common.Address, amount *big.Int) {
+ err := s.state.SubBalance(s.ctx, addr, amount)
+ s.errHandler(err)
+}
+
// GetBalance retrieves the balance from the given address or 0 if the account does
// not exist
func (s *VMState) GetBalance(addr common.Address) *big.Int {