mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 02:12:23 +00:00
core,vm,eth,les: add precompiles to block context, re-enable tx tracing
This commit is contained in:
parent
56819e1de5
commit
58e01e4058
14 changed files with 118 additions and 95 deletions
|
|
@ -283,9 +283,12 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
|
||||||
msg := callmsg{call}
|
msg := callmsg{call}
|
||||||
|
|
||||||
evmContext := core.NewEVMContext(msg, block.Header(), b.blockchain, nil)
|
evmContext := core.NewEVMContext(msg, block.Header(), b.blockchain, nil)
|
||||||
|
// Ignore error, we're past header validation
|
||||||
|
beneficiary, _ := b.blockchain.Engine().Author(block.Header())
|
||||||
|
blockContext := core.NewBlockContext(block.Header(), beneficiary, b.config)
|
||||||
// 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.NewEVM(evmContext, statedb, b.config, vm.Config{})
|
vmenv := vm.NewEVM(evmContext, statedb, b.config, &vm.Config{}, blockContext)
|
||||||
gaspool := new(core.GasPool).AddGas(math.MaxUint64)
|
gaspool := new(core.GasPool).AddGas(math.MaxUint64)
|
||||||
|
|
||||||
return core.NewStateTransition(vmenv, msg, gaspool).TransitionDb()
|
return core.NewStateTransition(vmenv, msg, gaspool).TransitionDb()
|
||||||
|
|
|
||||||
|
|
@ -53,8 +53,7 @@ type BlockGen struct {
|
||||||
|
|
||||||
config *params.ChainConfig
|
config *params.ChainConfig
|
||||||
engine consensus.Engine
|
engine consensus.Engine
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// SetCoinbase sets the coinbase of the generated block.
|
// SetCoinbase sets the coinbase of the generated block.
|
||||||
// It can be called at most once.
|
// It can be called at most once.
|
||||||
|
|
@ -100,18 +99,8 @@ func (b *BlockGen) AddTxWithChain(bc *BlockChain, tx *types.Transaction) {
|
||||||
}
|
}
|
||||||
b.statedb.Prepare(tx.Hash(), common.Hash{}, len(b.txs))
|
b.statedb.Prepare(tx.Hash(), common.Hash{}, len(b.txs))
|
||||||
|
|
||||||
blockContext := &vm.BlockContext{
|
blockContext := NewBlockContext(b.header, b.header.Coinbase, b.config)
|
||||||
BlockNumber: b.header.Number,
|
receipt, _, err := ApplyTransaction(b.config, bc, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, &vm.Config{}, blockContext)
|
||||||
Coinbase: b.header.Coinbase,
|
|
||||||
GasLimit: b.header.GasLimit,
|
|
||||||
Signer: types.MakeSigner(b.config, b.header.Number),
|
|
||||||
Precompiles: vm.PrecompiledContractsByzantium, // TODO fix
|
|
||||||
Intpool: vm.NewIntpool(),
|
|
||||||
Time: b.header.Time,
|
|
||||||
Difficulty: b.header.Difficulty,
|
|
||||||
}
|
|
||||||
|
|
||||||
receipt, _, err := ApplyTransaction(b.config, bc, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, &vm.Config{}, blockContext)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
17
core/evm.go
17
core/evm.go
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/consensus"
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ChainContext supports retrieving headers and consensus parameters from the
|
// ChainContext supports retrieving headers and consensus parameters from the
|
||||||
|
|
@ -36,7 +37,7 @@ type ChainContext interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEVMContext creates a new context for use in the EVM.
|
// NewEVMContext creates a new context for use in the EVM.
|
||||||
func NewEVMContext(msg Message, header *types.Header, chain ChainContext, author *common.Address) *vm.Context {
|
func NewEVMContext(msg Message, header *types.Header, chain ChainContext) *vm.Context {
|
||||||
return &vm.Context{
|
return &vm.Context{
|
||||||
CanTransfer: CanTransfer,
|
CanTransfer: CanTransfer,
|
||||||
Transfer: Transfer,
|
Transfer: Transfer,
|
||||||
|
|
@ -46,6 +47,20 @@ func NewEVMContext(msg Message, header *types.Header, chain ChainContext, author
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewBlockContext creates a block-specific context for use in the EVM
|
||||||
|
func NewBlockContext(header *types.Header, beneficiary common.Address, chainConfig *params.ChainConfig) *vm.BlockContext {
|
||||||
|
return &vm.BlockContext{
|
||||||
|
Intpool: vm.NewIntpool(),
|
||||||
|
Coinbase: beneficiary,
|
||||||
|
BlockNumber: new(big.Int).Set(header.Number),
|
||||||
|
Time: new(big.Int).Set(header.Time),
|
||||||
|
Difficulty: new(big.Int).Set(header.Difficulty),
|
||||||
|
GasLimit: header.GasLimit,
|
||||||
|
Signer: types.MakeSigner(chainConfig, header.Number),
|
||||||
|
Precompiles: vm.PrecompilesAt(chainConfig, header.Number),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// GetHashFn returns a GetHashFunc which retrieves header hashes by number
|
// GetHashFn returns a GetHashFunc which retrieves header hashes by number
|
||||||
func GetHashFn(ref *types.Header, chain ChainContext) func(n uint64) common.Hash {
|
func GetHashFn(ref *types.Header, chain ChainContext) func(n uint64) common.Hash {
|
||||||
var cache map[uint64]common.Hash
|
var cache map[uint64]common.Hash
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/ethereum/go-ethereum/consensus"
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
"github.com/ethereum/go-ethereum/consensus/misc"
|
"github.com/ethereum/go-ethereum/consensus/misc"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
|
|
@ -25,7 +24,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"math/big"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// StateProcessor is a basic Processor, which takes care of transitioning
|
// StateProcessor is a basic Processor, which takes care of transitioning
|
||||||
|
|
@ -66,29 +64,15 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
||||||
if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
|
if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
|
||||||
misc.ApplyDAOHardFork(statedb)
|
misc.ApplyDAOHardFork(statedb)
|
||||||
}
|
}
|
||||||
|
// Ignore error, we're past header validation
|
||||||
precompiles := vm.PrecompiledContractsHomestead
|
|
||||||
if p.config.ByzantiumBlock.Cmp(block.Number()) <= 0 {
|
|
||||||
precompiles = vm.PrecompiledContractsByzantium
|
|
||||||
}
|
|
||||||
beneficiary, _ := p.engine.Author(block.Header())
|
beneficiary, _ := p.engine.Author(block.Header())
|
||||||
|
blockContext := NewBlockContext(block.Header(), beneficiary, p.config)
|
||||||
|
|
||||||
blockContext := &vm.BlockContext{
|
|
||||||
Intpool: vm.NewIntpool(),
|
|
||||||
Precompiles: precompiles,
|
|
||||||
|
|
||||||
BlockNumber: new(big.Int).Set(block.Header().Number),
|
|
||||||
Time: new(big.Int).Set(block.Header().Time),
|
|
||||||
Difficulty: new(big.Int).Set(block.Header().Difficulty),
|
|
||||||
GasLimit: block.Header().GasLimit,
|
|
||||||
Coinbase: beneficiary,
|
|
||||||
Signer: types.MakeSigner(p.config, block.Header().Number),
|
|
||||||
}
|
|
||||||
// Iterate over and process the individual transactions
|
// Iterate over and process the individual transactions
|
||||||
receipts = make([]*types.Receipt, len(block.Transactions()))
|
receipts = make([]*types.Receipt, len(block.Transactions()))
|
||||||
for i, tx := range block.Transactions() {
|
for i, tx := range block.Transactions() {
|
||||||
statedb.Prepare(tx.Hash(), block.Hash(), i)
|
statedb.Prepare(tx.Hash(), block.Hash(), i)
|
||||||
receipt, _, err := ApplyTransaction(p.config, p.bc, nil, gp, statedb, header, tx, usedGas, &cfg, blockContext)
|
receipt, _, err := ApplyTransaction(p.config, p.bc, gp, statedb, header, tx, usedGas, &cfg, blockContext)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, 0, err
|
return nil, nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
@ -105,13 +89,13 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
||||||
// and uses the input parameters for its environment. It returns the receipt
|
// and uses the input parameters for its environment. It returns the receipt
|
||||||
// for the transaction, gas used and an error if the transaction failed,
|
// for the transaction, gas used and an error if the transaction failed,
|
||||||
// indicating the block was invalid.
|
// indicating the block was invalid.
|
||||||
func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg *vm.Config, blockContext *vm.BlockContext) (*types.Receipt, uint64, error) {
|
func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg *vm.Config, blockContext *vm.BlockContext) (*types.Receipt, uint64, error) {
|
||||||
msg, err := tx.AsMessage(blockContext.Signer)
|
msg, err := tx.AsMessage(blockContext.Signer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
// Create a new context to be used in the EVM environment
|
// Create a new context to be used in the EVM environment
|
||||||
context := NewEVMContext(msg, header, bc, author)
|
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.NewEVM(context, statedb, config, cfg, blockContext)
|
vmenv := vm.NewEVM(context, statedb, config, cfg, blockContext)
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ type Contract struct {
|
||||||
DelegateCall bool
|
DelegateCall bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewPrecompiledContract returns a new contract environment for the execution of a precompiled contract
|
||||||
func NewPrecompiledContract( caller ContractRef, object ContractRef,value *big.Int, gas uint64) *Contract{
|
func NewPrecompiledContract( caller ContractRef, object ContractRef,value *big.Int, gas uint64) *Contract{
|
||||||
|
|
||||||
c := &Contract{CallerAddress: caller.Address(), caller: caller, self: object, Args: nil}
|
c := &Contract{CallerAddress: caller.Address(), caller: caller, self: object, Args: nil}
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,14 @@ var PrecompiledContractsByzantium = map[common.Address]PrecompiledContract{
|
||||||
common.BytesToAddress([]byte{8}): &bn256Pairing{},
|
common.BytesToAddress([]byte{8}): &bn256Pairing{},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PrecompilesAt returns the map of active precompiled contracts at the given blocknumber and config
|
||||||
|
func PrecompilesAt(c *params.ChainConfig, blockNumber *big.Int) map[common.Address]PrecompiledContract {
|
||||||
|
if c.ByzantiumBlock.Cmp(blockNumber) <= 0 {
|
||||||
|
return PrecompiledContractsByzantium
|
||||||
|
}
|
||||||
|
return PrecompiledContractsHomestead
|
||||||
|
}
|
||||||
|
|
||||||
// RunPrecompiledContract runs and evaluates the output of a precompiled contract.
|
// RunPrecompiledContract runs and evaluates the output of a precompiled contract.
|
||||||
func RunPrecompiledContract(p PrecompiledContract, input []byte, contract *Contract) (ret []byte, err error) {
|
func RunPrecompiledContract(p PrecompiledContract, input []byte, contract *Contract) (ret []byte, err error) {
|
||||||
gas := p.RequiredGas(input)
|
gas := p.RequiredGas(input)
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,9 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// emptyCodeHash is used by create to ensure deployment is disallowed to already
|
// emptyCodeHash is used by create to ensure deployment is disallowed to already
|
||||||
|
|
@ -63,18 +63,11 @@ type Context struct {
|
||||||
// Message information
|
// Message information
|
||||||
Origin common.Address // Provides information for ORIGIN
|
Origin common.Address // Provides information for ORIGIN
|
||||||
GasPrice *big.Int // Provides information for GASPRICE
|
GasPrice *big.Int // Provides information for GASPRICE
|
||||||
|
|
||||||
//// Block information
|
|
||||||
//Coinbase common.Address // Provides information for COINBASE
|
|
||||||
//GasLimit uint64 // Provides information for GASLIMIT
|
|
||||||
//BlockNumber *big.Int // Provides information for NUMBER
|
|
||||||
//Time *big.Int // Provides information for TIME
|
|
||||||
//Difficulty *big.Int // Provides information for DIFFICULTY
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blockcontext provides block-constant auxiliary information. Should never be modified after
|
// Blockcontext provides block-constant auxiliary information. Should never be modified after
|
||||||
// creation
|
// creation
|
||||||
type BlockContext struct{
|
type BlockContext struct {
|
||||||
Precompiles map[common.Address]PrecompiledContract
|
Precompiles map[common.Address]PrecompiledContract
|
||||||
Signer types.Signer
|
Signer types.Signer
|
||||||
Intpool *IntPool
|
Intpool *IntPool
|
||||||
|
|
@ -125,7 +118,7 @@ type EVM struct {
|
||||||
|
|
||||||
// NewEVM returns a new EVM. The returned EVM is not thread safe and should
|
// NewEVM returns a new EVM. The returned EVM is not thread safe and should
|
||||||
// only ever be used *once*.
|
// only ever be used *once*.
|
||||||
func NewEVM(ctx *Context, statedb StateDB, chainConfig *params.ChainConfig, vmConfig *Config,blockContext *BlockContext) *EVM {
|
func NewEVM(ctx *Context, statedb StateDB, chainConfig *params.ChainConfig, vmConfig *Config, blockContext *BlockContext) *EVM {
|
||||||
evm := &EVM{
|
evm := &EVM{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
StateDB: statedb,
|
StateDB: statedb,
|
||||||
|
|
@ -170,7 +163,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
||||||
exists := evm.StateDB.Exist(addr)
|
exists := evm.StateDB.Exist(addr)
|
||||||
precompile, isPrecompile := evm.BlockContext.Precompiles[addr]
|
precompile, isPrecompile := evm.BlockContext.Precompiles[addr]
|
||||||
|
|
||||||
if !exists{
|
if !exists {
|
||||||
if !isPrecompile && evm.ChainConfig().IsEIP158(evm.BlockContext.BlockNumber) && value.Sign() == 0 {
|
if !isPrecompile && evm.ChainConfig().IsEIP158(evm.BlockContext.BlockNumber) && value.Sign() == 0 {
|
||||||
// Calling a non existing account, don't do anything, but ping the tracer
|
// Calling a non existing account, don't do anything, but ping the tracer
|
||||||
if evm.vmConfig.Debug && evm.depth == 0 {
|
if evm.vmConfig.Debug && evm.depth == 0 {
|
||||||
|
|
@ -184,7 +177,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
||||||
evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value)
|
evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value)
|
||||||
|
|
||||||
var contract *Contract
|
var contract *Contract
|
||||||
if isPrecompile{
|
if isPrecompile {
|
||||||
// A 'contract' is needed for gas accounting
|
// A 'contract' is needed for gas accounting
|
||||||
contract = NewPrecompiledContract(caller, to, value, gas)
|
contract = NewPrecompiledContract(caller, to, value, gas)
|
||||||
ret, err = RunPrecompiledContract(precompile, input, contract)
|
ret, err = RunPrecompiledContract(precompile, input, contract)
|
||||||
|
|
@ -196,8 +189,8 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
||||||
evm.vmConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err)
|
evm.vmConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
if !exists{
|
if !exists {
|
||||||
// Shortcut execution -- account didn't exist,
|
// Shortcut execution -- account didn't exist,
|
||||||
// so no need to lookup the code
|
// so no need to lookup the code
|
||||||
// but make sure to set returndata to nil
|
// but make sure to set returndata to nil
|
||||||
|
|
|
||||||
|
|
@ -369,10 +369,10 @@ type storageEntry struct {
|
||||||
Key *common.Hash `json:"key"`
|
Key *common.Hash `json:"key"`
|
||||||
Value common.Hash `json:"value"`
|
Value common.Hash `json:"value"`
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
// StorageRangeAt returns the storage at the given block height and transaction index.
|
// StorageRangeAt returns the storage at the given block height and transaction index.
|
||||||
func (api *PrivateDebugAPI) StorageRangeAt(ctx context.Context, blockHash common.Hash, txIndex int, contractAddress common.Address, keyStart hexutil.Bytes, maxResult int) (StorageRangeResult, error) {
|
func (api *PrivateDebugAPI) StorageRangeAt(ctx context.Context, blockHash common.Hash, txIndex int, contractAddress common.Address, keyStart hexutil.Bytes, maxResult int) (StorageRangeResult, error) {
|
||||||
_, _, statedb, err := api.computeTxEnv(blockHash, txIndex, 0)
|
_, _, _, statedb, err := api.computeTxEnv(blockHash, txIndex, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return StorageRangeResult{}, err
|
return StorageRangeResult{}, err
|
||||||
}
|
}
|
||||||
|
|
@ -405,7 +405,7 @@ func storageRangeAt(st state.Trie, start []byte, maxResult int) (StorageRangeRes
|
||||||
}
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
// GetModifiedAccountsByumber returns all accounts that have changed between the
|
// GetModifiedAccountsByumber returns all accounts that have changed between the
|
||||||
// two blocks specified. A change is defined as a difference in nonce, balance,
|
// two blocks specified. A change is defined as a difference in nonce, balance,
|
||||||
// code hash, or storage hash.
|
// code hash, or storage hash.
|
||||||
|
|
|
||||||
|
|
@ -22,19 +22,19 @@ import (
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/common/math"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/bloombits"
|
"github.com/ethereum/go-ethereum/core/bloombits"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/eth/downloader"
|
"github.com/ethereum/go-ethereum/eth/downloader"
|
||||||
"github.com/ethereum/go-ethereum/eth/gasprice"
|
"github.com/ethereum/go-ethereum/eth/gasprice"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
|
||||||
"github.com/ethereum/go-ethereum/common/math"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// EthAPIBackend implements ethapi.Backend for full nodes
|
// EthAPIBackend implements ethapi.Backend for full nodes
|
||||||
|
|
@ -132,8 +132,11 @@ func (b *EthAPIBackend) GetEVM(ctx context.Context, msg core.Message, state *sta
|
||||||
state.SetBalance(msg.From(), math.MaxBig256)
|
state.SetBalance(msg.From(), math.MaxBig256)
|
||||||
vmError := func() error { return nil }
|
vmError := func() error { return nil }
|
||||||
|
|
||||||
context := core.NewEVMContext(msg, header, b.eth.BlockChain(), nil)
|
context := core.NewEVMContext(msg, header, b.eth.BlockChain())
|
||||||
return vm.NewEVM(context, state, b.eth.chainConfig, &vmCfg, &vm.BlockContext{} ), vmError, nil
|
beneficiary, _ := b.eth.BlockChain().Engine().Author(header)
|
||||||
|
blockContext := core.NewBlockContext(header, beneficiary, b.ChainConfig())
|
||||||
|
|
||||||
|
return vm.NewEVM(context, state, b.eth.chainConfig, &vmCfg, blockContext), vmError, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthAPIBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription {
|
func (b *EthAPIBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription {
|
||||||
|
|
|
||||||
|
|
@ -24,12 +24,22 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"github.com/ethereum/go-ethereum/core"
|
||||||
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
|
"github.com/ethereum/go-ethereum/eth/tracers"
|
||||||
|
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
|
"io/ioutil"
|
||||||
|
"runtime"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -80,7 +90,7 @@ type txTraceTask struct {
|
||||||
statedb *state.StateDB // Intermediate state prepped for tracing
|
statedb *state.StateDB // Intermediate state prepped for tracing
|
||||||
index int // Transaction offset in the block
|
index int // Transaction offset in the block
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
// TraceChain returns the structured logs created during the execution of EVM
|
// TraceChain returns the structured logs created during the execution of EVM
|
||||||
// between two blocks (excluding start) and returns them as a JSON object.
|
// between two blocks (excluding start) and returns them as a JSON object.
|
||||||
func (api *PrivateDebugAPI) TraceChain(ctx context.Context, start, end rpc.BlockNumber, config *TraceConfig) (*rpc.Subscription, error) {
|
func (api *PrivateDebugAPI) TraceChain(ctx context.Context, start, end rpc.BlockNumber, config *TraceConfig) (*rpc.Subscription, error) {
|
||||||
|
|
@ -186,9 +196,10 @@ func (api *PrivateDebugAPI) traceChain(ctx context.Context, start, end *types.Bl
|
||||||
// Trace all the transactions contained within
|
// Trace all the transactions contained within
|
||||||
for i, tx := range task.block.Transactions() {
|
for i, tx := range task.block.Transactions() {
|
||||||
msg, _ := tx.AsMessage(signer)
|
msg, _ := tx.AsMessage(signer)
|
||||||
vmctx := core.NewEVMContext(msg, task.block.Header(), api.eth.blockchain, nil)
|
vmctx := core.NewEVMContext(msg, task.block.Header(), api.eth.blockchain)
|
||||||
|
beneficiary, _ := api.eth.blockchain.Engine().Author(task.block.Header())
|
||||||
res, err := api.traceTx(ctx, msg, vmctx, task.statedb, config)
|
blockCtx := core.NewBlockContext(task.block.Header(), beneficiary, api.eth.chainConfig)
|
||||||
|
res, err := api.traceTx(ctx, msg, vmctx, blockCtx, task.statedb, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
task.results[i] = &txTraceResult{Error: err.Error()}
|
task.results[i] = &txTraceResult{Error: err.Error()}
|
||||||
log.Warn("Tracing failed", "hash", tx.Hash(), "block", task.block.NumberU64(), "err", err)
|
log.Warn("Tracing failed", "hash", tx.Hash(), "block", task.block.NumberU64(), "err", err)
|
||||||
|
|
@ -378,7 +389,7 @@ func (api *PrivateDebugAPI) TraceBlockFromFile(ctx context.Context, file string,
|
||||||
// traceBlock configures a new tracer according to the provided configuration, and
|
// traceBlock configures a new tracer according to the provided configuration, and
|
||||||
// executes all the transactions contained within. The return value will be one item
|
// executes all the transactions contained within. The return value will be one item
|
||||||
// per transaction, dependent on the requestd tracer.
|
// per transaction, dependent on the requestd tracer.
|
||||||
/*
|
|
||||||
func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block, config *TraceConfig) ([]*txTraceResult, error) {
|
func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block, config *TraceConfig) ([]*txTraceResult, error) {
|
||||||
// Create the parent state database
|
// Create the parent state database
|
||||||
if err := api.eth.engine.VerifyHeader(api.eth.blockchain, block.Header(), true); err != nil {
|
if err := api.eth.engine.VerifyHeader(api.eth.blockchain, block.Header(), true); err != nil {
|
||||||
|
|
@ -418,9 +429,10 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block,
|
||||||
// Fetch and execute the next transaction trace tasks
|
// Fetch and execute the next transaction trace tasks
|
||||||
for task := range jobs {
|
for task := range jobs {
|
||||||
msg, _ := txs[task.index].AsMessage(signer)
|
msg, _ := txs[task.index].AsMessage(signer)
|
||||||
vmctx := core.NewEVMContext(msg, block.Header(), api.eth.blockchain, nil)
|
vmctx := core.NewEVMContext(msg, block.Header(), api.eth.blockchain)
|
||||||
|
beneficiary, _ := api.eth.blockchain.Engine().Author(block.Header())
|
||||||
res, err := api.traceTx(ctx, msg, vmctx, task.statedb, config)
|
blockCtx := core.NewBlockContext(block.Header(), beneficiary, api.eth.chainConfig)
|
||||||
|
res, err := api.traceTx(ctx, msg, vmctx, blockCtx, task.statedb, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
results[task.index] = &txTraceResult{Error: err.Error()}
|
results[task.index] = &txTraceResult{Error: err.Error()}
|
||||||
continue
|
continue
|
||||||
|
|
@ -437,9 +449,11 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block,
|
||||||
|
|
||||||
// Generate the next state snapshot fast without tracing
|
// Generate the next state snapshot fast without tracing
|
||||||
msg, _ := tx.AsMessage(signer)
|
msg, _ := tx.AsMessage(signer)
|
||||||
vmctx := core.NewEVMContext(msg, block.Header(), api.eth.blockchain, nil)
|
vmctx := core.NewEVMContext(msg, block.Header(), api.eth.blockchain)
|
||||||
|
beneficiary, _ := api.eth.blockchain.Engine().Author(block.Header())
|
||||||
|
blockCtx := core.NewBlockContext(block.Header(), beneficiary, api.eth.chainConfig)
|
||||||
|
|
||||||
vmenv := vm.NewEVM(vmctx, statedb, api.config, vm.Config{})
|
vmenv := vm.NewEVM(vmctx, statedb, api.config, &vm.Config{}, blockCtx)
|
||||||
if _, _, _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas())); err != nil {
|
if _, _, _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas())); err != nil {
|
||||||
failed = err
|
failed = err
|
||||||
break
|
break
|
||||||
|
|
@ -456,7 +470,7 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block,
|
||||||
}
|
}
|
||||||
return results, nil
|
return results, nil
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
// computeStateDB retrieves the state database associated with a certain block.
|
// computeStateDB retrieves the state database associated with a certain block.
|
||||||
// If no state is locally available for the given block, a number of blocks are
|
// If no state is locally available for the given block, a number of blocks are
|
||||||
// attempted to be reexecuted to generate the desired state.
|
// attempted to be reexecuted to generate the desired state.
|
||||||
|
|
@ -522,7 +536,7 @@ func (api *PrivateDebugAPI) computeStateDB(block *types.Block, reexec uint64) (*
|
||||||
log.Info("Historical state regenerated", "block", block.NumberU64(), "elapsed", time.Since(start), "size", database.TrieDB().Size())
|
log.Info("Historical state regenerated", "block", block.NumberU64(), "elapsed", time.Since(start), "size", database.TrieDB().Size())
|
||||||
return statedb, nil
|
return statedb, nil
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
// TraceTransaction returns the structured logs created during the execution of EVM
|
// TraceTransaction returns the structured logs created during the execution of EVM
|
||||||
// and returns them as a JSON object.
|
// and returns them as a JSON object.
|
||||||
func (api *PrivateDebugAPI) TraceTransaction(ctx context.Context, hash common.Hash, config *TraceConfig) (interface{}, error) {
|
func (api *PrivateDebugAPI) TraceTransaction(ctx context.Context, hash common.Hash, config *TraceConfig) (interface{}, error) {
|
||||||
|
|
@ -535,18 +549,18 @@ func (api *PrivateDebugAPI) TraceTransaction(ctx context.Context, hash common.Ha
|
||||||
if config != nil && config.Reexec != nil {
|
if config != nil && config.Reexec != nil {
|
||||||
reexec = *config.Reexec
|
reexec = *config.Reexec
|
||||||
}
|
}
|
||||||
msg, vmctx, statedb, err := api.computeTxEnv(blockHash, int(index), reexec)
|
msg, vmctx, blockCtx, statedb, err := api.computeTxEnv(blockHash, int(index), reexec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Trace the transaction and return
|
// Trace the transaction and return
|
||||||
return api.traceTx(ctx, msg, vmctx, statedb, config)
|
return api.traceTx(ctx, msg, vmctx, blockCtx, statedb, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
// traceTx configures a new tracer according to the provided configuration, and
|
// traceTx configures a new tracer according to the provided configuration, and
|
||||||
// executes the given message in the provided environment. The return value will
|
// executes the given message in the provided environment. The return value will
|
||||||
// be tracer dependent.
|
// be tracer dependent.
|
||||||
func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, vmctx vm.Context, statedb *state.StateDB, config *TraceConfig) (interface{}, error) {
|
func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, vmctx *vm.Context, blockCtx *vm.BlockContext, statedb *state.StateDB, config *TraceConfig) (interface{}, error) {
|
||||||
// Assemble the structured logger or the JavaScript tracer
|
// Assemble the structured logger or the JavaScript tracer
|
||||||
var (
|
var (
|
||||||
tracer vm.Tracer
|
tracer vm.Tracer
|
||||||
|
|
@ -580,7 +594,7 @@ func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, v
|
||||||
tracer = vm.NewStructLogger(config.LogConfig)
|
tracer = vm.NewStructLogger(config.LogConfig)
|
||||||
}
|
}
|
||||||
// Run the transaction with tracing enabled.
|
// Run the transaction with tracing enabled.
|
||||||
vmenv := vm.NewEVM(vmctx, statedb, api.config, vm.Config{Debug: true, Tracer: tracer})
|
vmenv := vm.NewEVM(vmctx, statedb, api.config, &vm.Config{Debug: true, Tracer: tracer}, blockCtx)
|
||||||
|
|
||||||
ret, gas, failed, err := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.Gas()))
|
ret, gas, failed, err := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.Gas()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -605,19 +619,19 @@ func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, v
|
||||||
}
|
}
|
||||||
|
|
||||||
// computeTxEnv returns the execution environment of a certain transaction.
|
// computeTxEnv returns the execution environment of a certain transaction.
|
||||||
func (api *PrivateDebugAPI) computeTxEnv(blockHash common.Hash, txIndex int, reexec uint64) (core.Message, vm.Context, *state.StateDB, error) {
|
func (api *PrivateDebugAPI) computeTxEnv(blockHash common.Hash, txIndex int, reexec uint64) (core.Message, *vm.Context, *vm.BlockContext, *state.StateDB, error) {
|
||||||
// Create the parent state database
|
// Create the parent state database
|
||||||
block := api.eth.blockchain.GetBlockByHash(blockHash)
|
block := api.eth.blockchain.GetBlockByHash(blockHash)
|
||||||
if block == nil {
|
if block == nil {
|
||||||
return nil, vm.Context{}, nil, fmt.Errorf("block %x not found", blockHash)
|
return nil, nil, nil, nil, fmt.Errorf("block %x not found", blockHash)
|
||||||
}
|
}
|
||||||
parent := api.eth.blockchain.GetBlock(block.ParentHash(), block.NumberU64()-1)
|
parent := api.eth.blockchain.GetBlock(block.ParentHash(), block.NumberU64()-1)
|
||||||
if parent == nil {
|
if parent == nil {
|
||||||
return nil, vm.Context{}, nil, fmt.Errorf("parent %x not found", block.ParentHash())
|
return nil, nil, nil, nil, fmt.Errorf("parent %x not found", block.ParentHash())
|
||||||
}
|
}
|
||||||
statedb, err := api.computeStateDB(parent, reexec)
|
statedb, err := api.computeStateDB(parent, reexec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, vm.Context{}, nil, err
|
return nil, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
// Recompute transactions up to the target index.
|
// Recompute transactions up to the target index.
|
||||||
signer := types.MakeSigner(api.config, block.Number())
|
signer := types.MakeSigner(api.config, block.Number())
|
||||||
|
|
@ -625,18 +639,19 @@ func (api *PrivateDebugAPI) computeTxEnv(blockHash common.Hash, txIndex int, ree
|
||||||
for idx, tx := range block.Transactions() {
|
for idx, tx := range block.Transactions() {
|
||||||
// Assemble the transaction call message and return if the requested offset
|
// Assemble the transaction call message and return if the requested offset
|
||||||
msg, _ := tx.AsMessage(signer)
|
msg, _ := tx.AsMessage(signer)
|
||||||
context := core.NewEVMContext(msg, block.Header(), api.eth.blockchain, nil)
|
context := core.NewEVMContext(msg, block.Header(), api.eth.blockchain)
|
||||||
|
beneficiary, _ := api.eth.blockchain.Engine().Author(block.Header())
|
||||||
|
blockCtx := core.NewBlockContext(block.Header(), beneficiary, api.eth.chainConfig)
|
||||||
if idx == txIndex {
|
if idx == txIndex {
|
||||||
return msg, context, statedb, nil
|
return msg, context, blockCtx, statedb, nil
|
||||||
}
|
}
|
||||||
// Not yet the searched for transaction, execute on top of the current state
|
// Not yet the searched for transaction, execute on top of the current state
|
||||||
vmenv := vm.NewEVM(context, statedb, api.config, vm.Config{})
|
vmenv := vm.NewEVM(context, statedb, api.config, &vm.Config{}, blockCtx)
|
||||||
if _, _, _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil {
|
if _, _, _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil {
|
||||||
return nil, vm.Context{}, nil, fmt.Errorf("tx %x failed: %v", tx.Hash(), err)
|
return nil, nil, nil, nil, fmt.Errorf("tx %x failed: %v", tx.Hash(), err)
|
||||||
}
|
}
|
||||||
// Ensure any modifications are committed to the state
|
// Ensure any modifications are committed to the state
|
||||||
statedb.Finalise(true)
|
statedb.Finalise(true)
|
||||||
}
|
}
|
||||||
return nil, vm.Context{}, nil, fmt.Errorf("tx index %d out of range for block %x", txIndex, blockHash)
|
return nil, nil, nil, nil, fmt.Errorf("tx index %d out of range for block %x", txIndex, blockHash)
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
|
||||||
|
|
@ -104,8 +104,10 @@ func (b *LesApiBackend) GetTd(hash common.Hash) *big.Int {
|
||||||
|
|
||||||
func (b *LesApiBackend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header, vmCfg vm.Config) (*vm.EVM, func() error, error) {
|
func (b *LesApiBackend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header, vmCfg vm.Config) (*vm.EVM, func() error, error) {
|
||||||
state.SetBalance(msg.From(), math.MaxBig256)
|
state.SetBalance(msg.From(), math.MaxBig256)
|
||||||
context := core.NewEVMContext(msg, header, b.eth.blockchain, nil)
|
context := core.NewEVMContext(msg, header, b.eth.blockchain)
|
||||||
return vm.NewEVM(context, state, b.eth.chainConfig, &vmCfg, &vm.BlockContext{}), state.Error, nil
|
beneficiary, _ := b.eth.BlockChain().Engine().Author(header)
|
||||||
|
blockContext := core.NewBlockContext(header, beneficiary, b.ChainConfig())
|
||||||
|
return vm.NewEVM(context, state, b.eth.chainConfig, &vmCfg, blockContext), state.Error, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *LesApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
|
func (b *LesApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
|
||||||
|
|
|
||||||
|
|
@ -135,8 +135,11 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
|
||||||
|
|
||||||
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), 100000, new(big.Int), data, false)}
|
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), 100000, new(big.Int), data, false)}
|
||||||
|
|
||||||
context := core.NewEVMContext(msg, header, bc, nil)
|
context := core.NewEVMContext(msg, header, bc)
|
||||||
vmenv := vm.NewEVM(context, statedb, config, vm.Config{})
|
beneficiary, _ := bc.Engine().Author(header)
|
||||||
|
blockContext := core.NewBlockContext(header, beneficiary, bc.Config())
|
||||||
|
|
||||||
|
vmenv := vm.NewEVM(context, statedb, config, &vm.Config{}, blockContext)
|
||||||
|
|
||||||
//vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{})
|
//vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{})
|
||||||
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
||||||
|
|
@ -148,8 +151,10 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
|
||||||
state := light.NewState(ctx, header, lc.Odr())
|
state := light.NewState(ctx, header, lc.Odr())
|
||||||
state.SetBalance(testBankAddress, math.MaxBig256)
|
state.SetBalance(testBankAddress, math.MaxBig256)
|
||||||
msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 100000, new(big.Int), data, false)}
|
msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 100000, new(big.Int), data, false)}
|
||||||
context := core.NewEVMContext(msg, header, lc, nil)
|
context := core.NewEVMContext(msg, header, lc)
|
||||||
vmenv := vm.NewEVM(context, state, config, vm.Config{})
|
beneficiary, _ := bc.Engine().Author(header)
|
||||||
|
blockContext := core.NewBlockContext(header, beneficiary, bc.Config())
|
||||||
|
vmenv := vm.NewEVM(context, state, config, &vm.Config{}, blockContext)
|
||||||
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
||||||
ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp)
|
ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp)
|
||||||
if state.Error() == nil {
|
if state.Error() == nil {
|
||||||
|
|
|
||||||
|
|
@ -190,8 +190,10 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain
|
||||||
// Perform read-only call.
|
// Perform read-only call.
|
||||||
st.SetBalance(testBankAddress, math.MaxBig256)
|
st.SetBalance(testBankAddress, math.MaxBig256)
|
||||||
msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 1000000, new(big.Int), data, false)}
|
msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 1000000, new(big.Int), data, false)}
|
||||||
context := core.NewEVMContext(msg, header, chain, nil)
|
context := core.NewEVMContext(msg, header, chain)
|
||||||
vmenv := vm.NewEVM(context, st, config, vm.Config{})
|
beneficiary, _ := bc.Engine().Author(header)
|
||||||
|
blockContext := core.NewBlockContext(header, beneficiary, bc.Config())
|
||||||
|
vmenv := vm.NewEVM(context, st, config, &vm.Config{}, blockContext)
|
||||||
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
||||||
ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp)
|
ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp)
|
||||||
res = append(res, ret...)
|
res = append(res, ret...)
|
||||||
|
|
|
||||||
|
|
@ -133,9 +133,12 @@ func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config) (*state.StateD
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
context := core.NewEVMContext(msg, block.Header(), nil, &t.json.Env.Coinbase)
|
context := core.NewEVMContext(msg, block.Header(), nil)
|
||||||
|
beneficiary := t.json.Env.Coinbase
|
||||||
|
blockContext := core.NewBlockContext(block.Header(), beneficiary, config)
|
||||||
|
|
||||||
context.GetHash = vmTestBlockHash
|
context.GetHash = vmTestBlockHash
|
||||||
evm := vm.NewEVM(context, statedb, config, vmconfig)
|
evm := vm.NewEVM(context, statedb, config, &vmconfig, blockContext)
|
||||||
|
|
||||||
gaspool := new(core.GasPool)
|
gaspool := new(core.GasPool)
|
||||||
gaspool.AddGas(block.GasLimit())
|
gaspool.AddGas(block.GasLimit())
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue