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.
|
// Execute the call.
|
||||||
msg := callmsg{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
|
// Create a new environment which holds all relevant information
|
||||||
// about the transaction and calling mechanisms.
|
// about the transaction and calling mechanisms.
|
||||||
vmenv := vm.NewEnvironment(evmContext, statedb, chainConfig, vm.Config{})
|
vmenv := vm.NewEnvironment(evmContext, statedb, chainConfig, vm.Config{})
|
||||||
|
|
|
||||||
|
|
@ -162,6 +162,7 @@ func run(ctx *cli.Context) error {
|
||||||
Origin: sender.Address(),
|
Origin: sender.Address(),
|
||||||
State: statedb,
|
State: statedb,
|
||||||
GasLimit: common.Big(ctx.GlobalString(GasFlag.Name)),
|
GasLimit: common.Big(ctx.GlobalString(GasFlag.Name)),
|
||||||
|
GasPrice: common.Big(ctx.GlobalString(PriceFlag.Name)),
|
||||||
Value: common.Big(ctx.GlobalString(ValueFlag.Name)),
|
Value: common.Big(ctx.GlobalString(ValueFlag.Name)),
|
||||||
EVMConfig: vm.Config{
|
EVMConfig: vm.Config{
|
||||||
Tracer: logger,
|
Tracer: logger,
|
||||||
|
|
@ -175,6 +176,7 @@ func run(ctx *cli.Context) error {
|
||||||
Origin: sender.Address(),
|
Origin: sender.Address(),
|
||||||
State: statedb,
|
State: statedb,
|
||||||
GasLimit: common.Big(ctx.GlobalString(GasFlag.Name)),
|
GasLimit: common.Big(ctx.GlobalString(GasFlag.Name)),
|
||||||
|
GasPrice: common.Big(ctx.GlobalString(PriceFlag.Name)),
|
||||||
Value: common.Big(ctx.GlobalString(ValueFlag.Name)),
|
Value: common.Big(ctx.GlobalString(ValueFlag.Name)),
|
||||||
EVMConfig: vm.Config{
|
EVMConfig: vm.Config{
|
||||||
Tracer: logger,
|
Tracer: logger,
|
||||||
|
|
|
||||||
14
core/evm.go
14
core/evm.go
|
|
@ -1,5 +1,4 @@
|
||||||
// Copyright 2014 The go-ethereum Authors
|
// Copyright 2014 The go-ethereum Authors
|
||||||
|
|
||||||
// This file is part of the go-ethereum library.
|
// This file is part of the go-ethereum library.
|
||||||
//
|
//
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
// 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
|
// BlockFetcher retrieves headers by their hash
|
||||||
type BlockFetcher interface {
|
type HeaderFetcher interface {
|
||||||
// GetHeader returns the hash corresponding to their hash
|
// GetHeader returns the hash corresponding to their hash
|
||||||
GetHeader(common.Hash, uint64) *types.Header
|
GetHeader(common.Hash, uint64) *types.Header
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToEVMContext creates a new context for use in the EVM.
|
// NewEVMContext creates a new context for use in the EVM.
|
||||||
func ToEVMContext(msg Message, header *types.Header, chain BlockFetcher) vm.Context {
|
func NewEVMContext(msg Message, header *types.Header, chain HeaderFetcher) vm.Context {
|
||||||
return vm.Context{
|
return vm.Context{
|
||||||
CanTransfer: CanTransfer,
|
CanTransfer: CanTransfer,
|
||||||
Transfer: Transfer,
|
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
|
// GetHashFn returns a GetHashFunc which retrieves header hashes by number
|
||||||
// up to the limit defined by the Yellow Paper and uses the given block chain
|
func GetHashFn(ref *types.Header, chain HeaderFetcher) func(n uint64) common.Hash {
|
||||||
// to query for information.
|
|
||||||
func GetHashFn(ref *types.Header, chain BlockFetcher) func(n uint64) common.Hash {
|
|
||||||
return 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) {
|
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 {
|
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.
|
// 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 {
|
func CanTransfer(db vm.StateDB, addr common.Address, amount *big.Int) bool {
|
||||||
return db.GetBalance(addr).Cmp(amount) >= 0
|
return db.GetBalance(addr).Cmp(amount) >= 0
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -293,6 +293,7 @@ func (self *StateDB) HasSuicided(addr common.Address) bool {
|
||||||
* SETTERS
|
* SETTERS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// AddBalance adds amount to the account associated with addr
|
||||||
func (self *StateDB) AddBalance(addr common.Address, amount *big.Int) {
|
func (self *StateDB) AddBalance(addr common.Address, amount *big.Int) {
|
||||||
stateObject := self.GetOrNewStateObject(addr)
|
stateObject := self.GetOrNewStateObject(addr)
|
||||||
if stateObject != nil {
|
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) {
|
func (self *StateDB) SubBalance(addr common.Address, amount *big.Int) {
|
||||||
stateObject := self.GetOrNewStateObject(addr)
|
stateObject := self.GetOrNewStateObject(addr)
|
||||||
if stateObject != nil {
|
if stateObject != nil {
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, gp *GasPool, s
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
// Create a new context to be used in the EVM environment
|
// 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
|
// Create a new environment which holds all relevant information
|
||||||
// about the transaction and calling mechanisms.
|
// about the transaction and calling mechanisms.
|
||||||
vmenv := vm.NewEnvironment(context, statedb, config, vm.Config{})
|
vmenv := vm.NewEnvironment(context, statedb, config, vm.Config{})
|
||||||
|
|
|
||||||
|
|
@ -74,17 +74,20 @@ type Environment struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEnvironment retutrns a new EVM environment.
|
// 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{
|
env := &Environment{
|
||||||
Context: context,
|
Context: context,
|
||||||
StateDB: statedb,
|
StateDB: statedb,
|
||||||
vmConfig: vmCfg,
|
vmConfig: vmConfig,
|
||||||
chainConfig: chainConfig,
|
chainConfig: chainConfig,
|
||||||
}
|
}
|
||||||
env.evm = New(env, vmCfg)
|
env.evm = New(env, vmConfig)
|
||||||
return env
|
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) {
|
func (env *Environment) Call(caller ContractRef, addr common.Address, input []byte, gas, value *big.Int) ([]byte, error) {
|
||||||
if env.vmConfig.NoRecursion && env.Depth > 0 {
|
if env.vmConfig.NoRecursion && env.Depth > 0 {
|
||||||
caller.ReturnGas(gas)
|
caller.ReturnGas(gas)
|
||||||
|
|
@ -140,7 +143,11 @@ func (env *Environment) Call(caller ContractRef, addr common.Address, input []by
|
||||||
return ret, err
|
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) {
|
func (env *Environment) CallCode(caller ContractRef, addr common.Address, input []byte, gas, value *big.Int) ([]byte, error) {
|
||||||
if env.vmConfig.NoRecursion && env.Depth > 0 {
|
if env.vmConfig.NoRecursion && env.Depth > 0 {
|
||||||
caller.ReturnGas(gas)
|
caller.ReturnGas(gas)
|
||||||
|
|
@ -182,7 +189,11 @@ func (env *Environment) CallCode(caller ContractRef, addr common.Address, input
|
||||||
return ret, err
|
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) {
|
func (env *Environment) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas *big.Int) ([]byte, error) {
|
||||||
if env.vmConfig.NoRecursion && env.Depth > 0 {
|
if env.vmConfig.NoRecursion && env.Depth > 0 {
|
||||||
caller.ReturnGas(gas)
|
caller.ReturnGas(gas)
|
||||||
|
|
@ -217,7 +228,7 @@ func (env *Environment) DelegateCall(caller ContractRef, addr common.Address, in
|
||||||
return ret, err
|
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) {
|
func (env *Environment) Create(caller ContractRef, code []byte, gas, value *big.Int) ([]byte, common.Address, error) {
|
||||||
if env.vmConfig.NoRecursion && env.Depth > 0 {
|
if env.vmConfig.NoRecursion && env.Depth > 0 {
|
||||||
caller.ReturnGas(gas)
|
caller.ReturnGas(gas)
|
||||||
|
|
|
||||||
|
|
@ -515,7 +515,7 @@ func (api *PrivateDebugAPI) TraceTransaction(ctx context.Context, txHash common.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("sender retrieval failed: %v", err)
|
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
|
// Mutate the state if we haven't reached the tracing transaction yet
|
||||||
if uint64(idx) < txIndex {
|
if uint64(idx) < txIndex {
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ func (b *EthApiBackend) GetVMEnv(ctx context.Context, msg core.Message, state et
|
||||||
from.SetBalance(common.MaxBig)
|
from.SetBalance(common.MaxBig)
|
||||||
vmError := func() error { return nil }
|
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
|
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)
|
from.SetBalance(common.MaxBig)
|
||||||
|
|
||||||
vmstate := light.NewVMState(ctx, stateDb)
|
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
|
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)}
|
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 := vm.NewEnvironment(context, statedb, config, vm.Config{})
|
||||||
|
|
||||||
//vmenv := core.NewEnv(statedb, config, bc, msg, header, 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)}
|
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 := vm.NewEnvironment(context, vmstate, config, vm.Config{})
|
||||||
|
|
||||||
//vmenv := light.NewEnv(ctx, state, config, lc, msg, header, 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)}
|
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{})
|
vmenv := vm.NewEnvironment(context, statedb, config, vm.Config{})
|
||||||
|
|
||||||
gp := new(core.GasPool).AddGas(common.MaxBig)
|
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)
|
from.SetBalance(common.MaxBig)
|
||||||
|
|
||||||
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(1000000), new(big.Int), data, false)}
|
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{})
|
vmenv := vm.NewEnvironment(context, vmstate, config, vm.Config{})
|
||||||
gp := new(core.GasPool).AddGas(common.MaxBig)
|
gp := new(core.GasPool).AddGas(common.MaxBig)
|
||||||
ret, _, _ := core.ApplyMessage(vmenv, msg, gp)
|
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))
|
statedb.Commit(chainConfig.IsEIP158(environment.Context.BlockNumber))
|
||||||
|
|
||||||
return ret, statedb.Logs(), gasUsed, err
|
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