mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 06:36:43 +00:00
cmd/evm, core, tests: review changes
This commit is contained in:
parent
36d8203678
commit
bfade2679f
12 changed files with 36 additions and 62 deletions
|
|
@ -226,7 +226,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
|
|||
// Execute the call.
|
||||
msg := callmsg{call}
|
||||
|
||||
evmContext := core.ToEVMContext(msg, block.Header(), b.blockchain)
|
||||
evmContext := core.NewEVMContext(msg, block.Header(), b.blockchain)
|
||||
// Create a new environment which holds all relevant information
|
||||
// about the transaction and calling mechanisms.
|
||||
vmenv := vm.NewEnvironment(evmContext, statedb, chainConfig, vm.Config{})
|
||||
|
|
|
|||
|
|
@ -162,6 +162,7 @@ func run(ctx *cli.Context) error {
|
|||
Origin: sender.Address(),
|
||||
State: statedb,
|
||||
GasLimit: common.Big(ctx.GlobalString(GasFlag.Name)),
|
||||
GasPrice: common.Big(ctx.GlobalString(PriceFlag.Name)),
|
||||
Value: common.Big(ctx.GlobalString(ValueFlag.Name)),
|
||||
EVMConfig: vm.Config{
|
||||
Tracer: logger,
|
||||
|
|
@ -175,6 +176,7 @@ func run(ctx *cli.Context) error {
|
|||
Origin: sender.Address(),
|
||||
State: statedb,
|
||||
GasLimit: common.Big(ctx.GlobalString(GasFlag.Name)),
|
||||
GasPrice: common.Big(ctx.GlobalString(PriceFlag.Name)),
|
||||
Value: common.Big(ctx.GlobalString(ValueFlag.Name)),
|
||||
EVMConfig: vm.Config{
|
||||
Tracer: logger,
|
||||
|
|
|
|||
14
core/evm.go
14
core/evm.go
|
|
@ -1,5 +1,4 @@
|
|||
// Copyright 2014 The go-ethereum Authors
|
||||
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
|
|
@ -26,13 +25,13 @@ import (
|
|||
)
|
||||
|
||||
// BlockFetcher retrieves headers by their hash
|
||||
type BlockFetcher interface {
|
||||
type HeaderFetcher interface {
|
||||
// GetHeader returns the hash corresponding to their hash
|
||||
GetHeader(common.Hash, uint64) *types.Header
|
||||
}
|
||||
|
||||
// ToEVMContext creates a new context for use in the EVM.
|
||||
func ToEVMContext(msg Message, header *types.Header, chain BlockFetcher) vm.Context {
|
||||
// NewEVMContext creates a new context for use in the EVM.
|
||||
func NewEVMContext(msg Message, header *types.Header, chain HeaderFetcher) vm.Context {
|
||||
return vm.Context{
|
||||
CanTransfer: CanTransfer,
|
||||
Transfer: Transfer,
|
||||
|
|
@ -48,10 +47,8 @@ func ToEVMContext(msg Message, header *types.Header, chain BlockFetcher) vm.Cont
|
|||
}
|
||||
}
|
||||
|
||||
// GetHashFn returns a function for which the VM env can query block hashes through
|
||||
// up to the limit defined by the Yellow Paper and uses the given block chain
|
||||
// to query for information.
|
||||
func GetHashFn(ref *types.Header, chain BlockFetcher) func(n uint64) common.Hash {
|
||||
// GetHashFn returns a GetHashFunc which retrieves header hashes by number
|
||||
func GetHashFn(ref *types.Header, chain HeaderFetcher) func(n uint64) common.Hash {
|
||||
return func(n uint64) common.Hash {
|
||||
for header := chain.GetHeader(ref.ParentHash, ref.Number.Uint64()-1); header != nil; header = chain.GetHeader(header.ParentHash, header.Number.Uint64()-1) {
|
||||
if header.Number.Uint64() == n {
|
||||
|
|
@ -64,6 +61,7 @@ func GetHashFn(ref *types.Header, chain BlockFetcher) func(n uint64) common.Hash
|
|||
}
|
||||
|
||||
// CanTransfer checks wether there are enough funds in the address' account to make a transfer.
|
||||
// This does not take the necessary gas in to account to make the transfer valid.
|
||||
func CanTransfer(db vm.StateDB, addr common.Address, amount *big.Int) bool {
|
||||
return db.GetBalance(addr).Cmp(amount) >= 0
|
||||
}
|
||||
|
|
|
|||
|
|
@ -293,6 +293,7 @@ func (self *StateDB) HasSuicided(addr common.Address) bool {
|
|||
* SETTERS
|
||||
*/
|
||||
|
||||
// AddBalance adds amount to the account associated with addr
|
||||
func (self *StateDB) AddBalance(addr common.Address, amount *big.Int) {
|
||||
stateObject := self.GetOrNewStateObject(addr)
|
||||
if stateObject != nil {
|
||||
|
|
@ -300,6 +301,7 @@ func (self *StateDB) AddBalance(addr common.Address, amount *big.Int) {
|
|||
}
|
||||
}
|
||||
|
||||
// SubBalance subtracts amount from the account associated with addr
|
||||
func (self *StateDB) SubBalance(addr common.Address, amount *big.Int) {
|
||||
stateObject := self.GetOrNewStateObject(addr)
|
||||
if stateObject != nil {
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, gp *GasPool, s
|
|||
return nil, nil, nil, err
|
||||
}
|
||||
// Create a new context to be used in the EVM environment
|
||||
context := ToEVMContext(msg, header, bc)
|
||||
context := NewEVMContext(msg, header, bc)
|
||||
// Create a new environment which holds all relevant information
|
||||
// about the transaction and calling mechanisms.
|
||||
vmenv := vm.NewEnvironment(context, statedb, config, vm.Config{})
|
||||
|
|
|
|||
|
|
@ -74,17 +74,20 @@ type Environment struct {
|
|||
}
|
||||
|
||||
// NewEnvironment retutrns a new EVM environment.
|
||||
func NewEnvironment(context Context, statedb StateDB, chainConfig *params.ChainConfig, vmCfg Config) *Environment {
|
||||
func NewEnvironment(context Context, statedb StateDB, chainConfig *params.ChainConfig, vmConfig Config) *Environment {
|
||||
env := &Environment{
|
||||
Context: context,
|
||||
StateDB: statedb,
|
||||
vmConfig: vmCfg,
|
||||
vmConfig: vmConfig,
|
||||
chainConfig: chainConfig,
|
||||
}
|
||||
env.evm = New(env, vmCfg)
|
||||
env.evm = New(env, vmConfig)
|
||||
return env
|
||||
}
|
||||
|
||||
// Call executes the contract associated with the addr with the given input as paramaters. It also handles any
|
||||
// necessary value transfer required and takes the necessary steps to create accounts and reverses the state in
|
||||
// case of an execution error or failed value transfer.
|
||||
func (env *Environment) Call(caller ContractRef, addr common.Address, input []byte, gas, value *big.Int) ([]byte, error) {
|
||||
if env.vmConfig.NoRecursion && env.Depth > 0 {
|
||||
caller.ReturnGas(gas)
|
||||
|
|
@ -140,7 +143,11 @@ func (env *Environment) Call(caller ContractRef, addr common.Address, input []by
|
|||
return ret, err
|
||||
}
|
||||
|
||||
// Take another's contract code and execute within our own context
|
||||
// CallCode executes the contract associated with the addr with the given input as paramaters. It also handles any
|
||||
// necessary value transfer required and takes the necessary steps to create accounts and reverses the state in
|
||||
// case of an execution error or failed value transfer.
|
||||
//
|
||||
// CallCode differs from Call in the sense that it executes the given address' code with the caller as context.
|
||||
func (env *Environment) CallCode(caller ContractRef, addr common.Address, input []byte, gas, value *big.Int) ([]byte, error) {
|
||||
if env.vmConfig.NoRecursion && env.Depth > 0 {
|
||||
caller.ReturnGas(gas)
|
||||
|
|
@ -182,7 +189,11 @@ func (env *Environment) CallCode(caller ContractRef, addr common.Address, input
|
|||
return ret, err
|
||||
}
|
||||
|
||||
// Same as CallCode except sender and value is propagated from parent to child scope
|
||||
// DelegateCall executes the contract associated with the addr with the given input as paramaters.
|
||||
// It reverses the state in case of an execution error.
|
||||
//
|
||||
// DelegateCall differs from CallCode in the sense that it executes the given address' code with the caller as context
|
||||
// and the caller is set to the caller of the caller.
|
||||
func (env *Environment) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas *big.Int) ([]byte, error) {
|
||||
if env.vmConfig.NoRecursion && env.Depth > 0 {
|
||||
caller.ReturnGas(gas)
|
||||
|
|
@ -217,7 +228,7 @@ func (env *Environment) DelegateCall(caller ContractRef, addr common.Address, in
|
|||
return ret, err
|
||||
}
|
||||
|
||||
// Create a new contract
|
||||
// Create creates a new contract using code as deployment code.
|
||||
func (env *Environment) Create(caller ContractRef, code []byte, gas, value *big.Int) ([]byte, common.Address, error) {
|
||||
if env.vmConfig.NoRecursion && env.Depth > 0 {
|
||||
caller.ReturnGas(gas)
|
||||
|
|
|
|||
|
|
@ -515,7 +515,7 @@ func (api *PrivateDebugAPI) TraceTransaction(ctx context.Context, txHash common.
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("sender retrieval failed: %v", err)
|
||||
}
|
||||
context := core.ToEVMContext(msg, block.Header(), api.eth.BlockChain())
|
||||
context := core.NewEVMContext(msg, block.Header(), api.eth.BlockChain())
|
||||
|
||||
// Mutate the state if we haven't reached the tracing transaction yet
|
||||
if uint64(idx) < txIndex {
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ func (b *EthApiBackend) GetVMEnv(ctx context.Context, msg core.Message, state et
|
|||
from.SetBalance(common.MaxBig)
|
||||
vmError := func() error { return nil }
|
||||
|
||||
context := core.ToEVMContext(msg, header, b.eth.BlockChain())
|
||||
context := core.NewEVMContext(msg, header, b.eth.BlockChain())
|
||||
return vm.NewEnvironment(context, statedb, b.eth.chainConfig, vm.Config{}), vmError, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ func (b *LesApiBackend) GetVMEnv(ctx context.Context, msg core.Message, state et
|
|||
from.SetBalance(common.MaxBig)
|
||||
|
||||
vmstate := light.NewVMState(ctx, stateDb)
|
||||
context := core.ToEVMContext(msg, header, b.eth.blockchain)
|
||||
context := core.NewEVMContext(msg, header, b.eth.blockchain)
|
||||
return vm.NewEnvironment(context, vmstate, b.eth.chainConfig, vm.Config{}), vmstate.Error, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
|
|||
|
||||
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(100000), new(big.Int), data, false)}
|
||||
|
||||
context := core.ToEVMContext(msg, header, bc)
|
||||
context := core.NewEVMContext(msg, header, bc)
|
||||
vmenv := vm.NewEnvironment(context, statedb, config, vm.Config{})
|
||||
|
||||
//vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{})
|
||||
|
|
@ -140,7 +140,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
|
|||
|
||||
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(100000), new(big.Int), data, false)}
|
||||
|
||||
context := core.ToEVMContext(msg, header, lc)
|
||||
context := core.NewEVMContext(msg, header, lc)
|
||||
vmenv := vm.NewEnvironment(context, vmstate, config, vm.Config{})
|
||||
|
||||
//vmenv := light.NewEnv(ctx, state, config, lc, msg, header, vm.Config{})
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain
|
|||
|
||||
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(1000000), new(big.Int), data, false)}
|
||||
|
||||
context := core.ToEVMContext(msg, header, bc)
|
||||
context := core.NewEVMContext(msg, header, bc)
|
||||
vmenv := vm.NewEnvironment(context, statedb, config, vm.Config{})
|
||||
|
||||
gp := new(core.GasPool).AddGas(common.MaxBig)
|
||||
|
|
@ -187,7 +187,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain
|
|||
from.SetBalance(common.MaxBig)
|
||||
|
||||
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(1000000), new(big.Int), data, false)}
|
||||
context := core.ToEVMContext(msg, header, lc)
|
||||
context := core.NewEVMContext(msg, header, lc)
|
||||
vmenv := vm.NewEnvironment(context, vmstate, config, vm.Config{})
|
||||
gp := new(core.GasPool).AddGas(common.MaxBig)
|
||||
ret, _, _ := core.ApplyMessage(vmenv, msg, gp)
|
||||
|
|
|
|||
|
|
@ -221,43 +221,4 @@ func RunState(chainConfig *params.ChainConfig, statedb *state.StateDB, env, tx m
|
|||
statedb.Commit(chainConfig.IsEIP158(environment.Context.BlockNumber))
|
||||
|
||||
return ret, statedb.Logs(), gasUsed, err
|
||||
/*
|
||||
|
||||
var (
|
||||
data = common.FromHex(tx["data"])
|
||||
gas = common.Big(tx["gasLimit"])
|
||||
price = common.Big(tx["gasPrice"])
|
||||
value = common.Big(tx["value"])
|
||||
nonce = common.Big(tx["nonce"]).Uint64()
|
||||
)
|
||||
|
||||
var to *common.Address
|
||||
if len(tx["to"]) > 2 {
|
||||
t := common.HexToAddress(tx["to"])
|
||||
to = &t
|
||||
}
|
||||
// Set pre compiled contracts
|
||||
vm.Precompiled = vm.PrecompiledContracts()
|
||||
gaspool := new(core.GasPool).AddGas(common.Big(env["currentGasLimit"]))
|
||||
|
||||
key, _ := hex.DecodeString(tx["secretKey"])
|
||||
addr := crypto.PubkeyToAddress(crypto.ToECDSA(key).PublicKey)
|
||||
|
||||
message := types.NewMessage(addr, to, nonce, value, gas, price, data, true)
|
||||
vmenv := NewEnvFromMap(chainConfig, statedb, env, tx)
|
||||
vmenv.origin = addr
|
||||
|
||||
root, _ := statedb.Commit(false)
|
||||
statedb.Reset(root)
|
||||
|
||||
snapshot := statedb.Snapshot()
|
||||
|
||||
ret, _, err := core.ApplyMessage(vmenv, message, gaspool)
|
||||
if core.IsNonceErr(err) || core.IsInvalidTxErr(err) || core.IsGasLimitErr(err) {
|
||||
statedb.RevertToSnapshot(snapshot)
|
||||
}
|
||||
statedb.Commit(chainConfig.IsEIP158(vmenv.BlockNumber()))
|
||||
|
||||
return ret, vmenv.state.Logs(), vmenv.Gas, err
|
||||
*/
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue