mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 18:02:24 +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}
|
||||
|
||||
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
|
||||
// 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)
|
||||
|
||||
return core.NewStateTransition(vmenv, msg, gaspool).TransitionDb()
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ type BlockGen struct {
|
|||
|
||||
config *params.ChainConfig
|
||||
engine consensus.Engine
|
||||
|
||||
}
|
||||
|
||||
// SetCoinbase sets the coinbase of the generated block.
|
||||
|
|
@ -100,18 +99,8 @@ func (b *BlockGen) AddTxWithChain(bc *BlockChain, tx *types.Transaction) {
|
|||
}
|
||||
b.statedb.Prepare(tx.Hash(), common.Hash{}, len(b.txs))
|
||||
|
||||
blockContext := &vm.BlockContext{
|
||||
BlockNumber: b.header.Number,
|
||||
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)
|
||||
blockContext := NewBlockContext(b.header, b.header.Coinbase, b.config)
|
||||
receipt, _, err := ApplyTransaction(b.config, bc, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, &vm.Config{}, blockContext)
|
||||
if err != nil {
|
||||
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/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
)
|
||||
|
||||
// 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.
|
||||
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{
|
||||
CanTransfer: CanTransfer,
|
||||
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
|
||||
func GetHashFn(ref *types.Header, chain ChainContext) func(n uint64) common.Hash {
|
||||
var cache map[uint64]common.Hash
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/consensus"
|
||||
"github.com/ethereum/go-ethereum/consensus/misc"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
|
|
@ -25,7 +24,6 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
// 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 {
|
||||
misc.ApplyDAOHardFork(statedb)
|
||||
}
|
||||
|
||||
precompiles := vm.PrecompiledContractsHomestead
|
||||
if p.config.ByzantiumBlock.Cmp(block.Number()) <= 0 {
|
||||
precompiles = vm.PrecompiledContractsByzantium
|
||||
}
|
||||
// Ignore error, we're past header validation
|
||||
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
|
||||
receipts = make([]*types.Receipt, len(block.Transactions()))
|
||||
for i, tx := range block.Transactions() {
|
||||
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 {
|
||||
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
|
||||
// for the transaction, gas used and an error if the transaction failed,
|
||||
// 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)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
// 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
|
||||
// about the transaction and calling mechanisms.
|
||||
vmenv := vm.NewEVM(context, statedb, config, cfg, blockContext)
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ type Contract struct {
|
|||
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{
|
||||
|
||||
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{},
|
||||
}
|
||||
|
||||
// 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.
|
||||
func RunPrecompiledContract(p PrecompiledContract, input []byte, contract *Contract) (ret []byte, err error) {
|
||||
gas := p.RequiredGas(input)
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"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
|
||||
|
|
@ -63,13 +63,6 @@ type Context struct {
|
|||
// Message information
|
||||
Origin common.Address // Provides information for ORIGIN
|
||||
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
|
||||
|
|
|
|||
|
|
@ -369,10 +369,10 @@ type storageEntry struct {
|
|||
Key *common.Hash `json:"key"`
|
||||
Value common.Hash `json:"value"`
|
||||
}
|
||||
/*
|
||||
|
||||
// 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) {
|
||||
_, _, statedb, err := api.computeTxEnv(blockHash, txIndex, 0)
|
||||
_, _, _, statedb, err := api.computeTxEnv(blockHash, txIndex, 0)
|
||||
if err != nil {
|
||||
return StorageRangeResult{}, err
|
||||
}
|
||||
|
|
@ -405,7 +405,7 @@ func storageRangeAt(st state.Trie, start []byte, maxResult int) (StorageRangeRes
|
|||
}
|
||||
return result, nil
|
||||
}
|
||||
*/
|
||||
|
||||
// GetModifiedAccountsByumber returns all accounts that have changed between the
|
||||
// two blocks specified. A change is defined as a difference in nonce, balance,
|
||||
// code hash, or storage hash.
|
||||
|
|
|
|||
|
|
@ -22,19 +22,19 @@ import (
|
|||
|
||||
"github.com/ethereum/go-ethereum/accounts"
|
||||
"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/bloombits"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"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/gasprice"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"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
|
||||
|
|
@ -132,8 +132,11 @@ func (b *EthAPIBackend) GetEVM(ctx context.Context, msg core.Message, state *sta
|
|||
state.SetBalance(msg.From(), math.MaxBig256)
|
||||
vmError := func() error { return nil }
|
||||
|
||||
context := core.NewEVMContext(msg, header, b.eth.BlockChain(), nil)
|
||||
return vm.NewEVM(context, state, b.eth.chainConfig, &vmCfg, &vm.BlockContext{} ), vmError, nil
|
||||
context := core.NewEVMContext(msg, header, b.eth.BlockChain())
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -24,12 +24,22 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common"
|
||||
"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/types"
|
||||
"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/rlp"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"github.com/ethereum/go-ethereum/trie"
|
||||
"io/ioutil"
|
||||
"runtime"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -80,7 +90,7 @@ type txTraceTask struct {
|
|||
statedb *state.StateDB // Intermediate state prepped for tracing
|
||||
index int // Transaction offset in the block
|
||||
}
|
||||
/*
|
||||
|
||||
// TraceChain returns the structured logs created during the execution of EVM
|
||||
// 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) {
|
||||
|
|
@ -186,9 +196,10 @@ func (api *PrivateDebugAPI) traceChain(ctx context.Context, start, end *types.Bl
|
|||
// Trace all the transactions contained within
|
||||
for i, tx := range task.block.Transactions() {
|
||||
msg, _ := tx.AsMessage(signer)
|
||||
vmctx := core.NewEVMContext(msg, task.block.Header(), api.eth.blockchain, nil)
|
||||
|
||||
res, err := api.traceTx(ctx, msg, vmctx, task.statedb, config)
|
||||
vmctx := core.NewEVMContext(msg, task.block.Header(), api.eth.blockchain)
|
||||
beneficiary, _ := api.eth.blockchain.Engine().Author(task.block.Header())
|
||||
blockCtx := core.NewBlockContext(task.block.Header(), beneficiary, api.eth.chainConfig)
|
||||
res, err := api.traceTx(ctx, msg, vmctx, blockCtx, task.statedb, config)
|
||||
if err != nil {
|
||||
task.results[i] = &txTraceResult{Error: err.Error()}
|
||||
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
|
||||
// executes all the transactions contained within. The return value will be one item
|
||||
// per transaction, dependent on the requestd tracer.
|
||||
/*
|
||||
|
||||
func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block, config *TraceConfig) ([]*txTraceResult, error) {
|
||||
// Create the parent state database
|
||||
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
|
||||
for task := range jobs {
|
||||
msg, _ := txs[task.index].AsMessage(signer)
|
||||
vmctx := core.NewEVMContext(msg, block.Header(), api.eth.blockchain, nil)
|
||||
|
||||
res, err := api.traceTx(ctx, msg, vmctx, task.statedb, config)
|
||||
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)
|
||||
res, err := api.traceTx(ctx, msg, vmctx, blockCtx, task.statedb, config)
|
||||
if err != nil {
|
||||
results[task.index] = &txTraceResult{Error: err.Error()}
|
||||
continue
|
||||
|
|
@ -437,9 +449,11 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block,
|
|||
|
||||
// Generate the next state snapshot fast without tracing
|
||||
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 {
|
||||
failed = err
|
||||
break
|
||||
|
|
@ -456,7 +470,7 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block,
|
|||
}
|
||||
return results, nil
|
||||
}
|
||||
*/
|
||||
|
||||
// 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
|
||||
// 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())
|
||||
return statedb, nil
|
||||
}
|
||||
/*
|
||||
|
||||
// TraceTransaction returns the structured logs created during the execution of EVM
|
||||
// and returns them as a JSON object.
|
||||
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 {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
// 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
|
||||
// executes the given message in the provided environment. The return value will
|
||||
// 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
|
||||
var (
|
||||
tracer vm.Tracer
|
||||
|
|
@ -580,7 +594,7 @@ func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, v
|
|||
tracer = vm.NewStructLogger(config.LogConfig)
|
||||
}
|
||||
// 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()))
|
||||
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.
|
||||
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
|
||||
block := api.eth.blockchain.GetBlockByHash(blockHash)
|
||||
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)
|
||||
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)
|
||||
if err != nil {
|
||||
return nil, vm.Context{}, nil, err
|
||||
return nil, nil, nil, nil, err
|
||||
}
|
||||
// Recompute transactions up to the target index.
|
||||
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() {
|
||||
// Assemble the transaction call message and return if the requested offset
|
||||
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 {
|
||||
return msg, context, statedb, nil
|
||||
return msg, context, blockCtx, statedb, nil
|
||||
}
|
||||
// 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 {
|
||||
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
|
||||
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) {
|
||||
state.SetBalance(msg.From(), math.MaxBig256)
|
||||
context := core.NewEVMContext(msg, header, b.eth.blockchain, nil)
|
||||
return vm.NewEVM(context, state, b.eth.chainConfig, &vmCfg, &vm.BlockContext{}), state.Error, nil
|
||||
context := core.NewEVMContext(msg, header, b.eth.blockchain)
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -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)}
|
||||
|
||||
context := core.NewEVMContext(msg, header, bc, nil)
|
||||
vmenv := vm.NewEVM(context, statedb, config, vm.Config{})
|
||||
context := core.NewEVMContext(msg, header, bc)
|
||||
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{})
|
||||
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.SetBalance(testBankAddress, math.MaxBig256)
|
||||
msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 100000, new(big.Int), data, false)}
|
||||
context := core.NewEVMContext(msg, header, lc, nil)
|
||||
vmenv := vm.NewEVM(context, state, config, vm.Config{})
|
||||
context := core.NewEVMContext(msg, header, lc)
|
||||
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)
|
||||
ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp)
|
||||
if state.Error() == nil {
|
||||
|
|
|
|||
|
|
@ -190,8 +190,10 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain
|
|||
// Perform read-only call.
|
||||
st.SetBalance(testBankAddress, math.MaxBig256)
|
||||
msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 1000000, new(big.Int), data, false)}
|
||||
context := core.NewEVMContext(msg, header, chain, nil)
|
||||
vmenv := vm.NewEVM(context, st, config, vm.Config{})
|
||||
context := core.NewEVMContext(msg, header, chain)
|
||||
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)
|
||||
ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp)
|
||||
res = append(res, ret...)
|
||||
|
|
|
|||
|
|
@ -133,9 +133,12 @@ func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config) (*state.StateD
|
|||
if err != nil {
|
||||
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
|
||||
evm := vm.NewEVM(context, statedb, config, vmconfig)
|
||||
evm := vm.NewEVM(context, statedb, config, &vmconfig, blockContext)
|
||||
|
||||
gaspool := new(core.GasPool)
|
||||
gaspool.AddGas(block.GasLimit())
|
||||
|
|
|
|||
Loading…
Reference in a new issue