diff --git a/core/vm/contract.go b/core/vm/contract.go index 0b87a6543f..ab654fd7ba 100644 --- a/core/vm/contract.go +++ b/core/vm/contract.go @@ -58,15 +58,11 @@ type Contract struct { Gas uint64 value *big.Int - - Args []byte - - DelegateCall bool } // NewContract returns a new contract environment for the execution of EVM. func NewContract(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} if parent, ok := caller.(*Contract); ok { // Reuse JUMPDEST analysis from parent context if available. @@ -118,7 +114,6 @@ func (c *Contract) validJumpdest(dest *big.Int) bool { // AsDelegate sets the contract to be a delegate call and returns the current // contract (for chaining calls) func (c *Contract) AsDelegate() *Contract { - c.DelegateCall = true // NOTE: caller must, at all times be a contract. It should never happen // that caller is something other than a Contract. parent := c.caller.(*Contract) @@ -177,6 +172,8 @@ func (c *Contract) SetCallCode(addr *common.Address, hash common.Hash, code []by c.CodeAddr = addr } +// SetCodeOptionalHash can be used to provide code, but it's optional to provide hash. +// In case hash is not provided, the jumpdest analysis will not be saved to the parent context func (c *Contract) SetCodeOptionalHash(addr *common.Address, codeAndHash codeAndHash) { c.Code = codeAndHash.code c.CodeHash = codeAndHash.hash diff --git a/core/vm/evm.go b/core/vm/evm.go index 132bc4318b..6e474a4294 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -212,12 +212,12 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas evm.StateDB.CreateAccount(addr) } evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value) - // Initialise a new contract and set the code that is to be used by the EVM. // The contract is a scoped environment for this execution context only. contract := NewContract(caller, to, value, gas) contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr)) + // Even if the account has no code, we need to continue because it might be a precompile start := time.Now() // Capture the tracer start/end events in debug mode diff --git a/eth/api_tracer.go b/eth/api_tracer.go index 5b7f168ec2..69d9215106 100644 --- a/eth/api_tracer.go +++ b/eth/api_tracer.go @@ -390,6 +390,13 @@ func (api *PrivateDebugAPI) TraceBlockFromFile(ctx context.Context, file string, } return api.TraceBlock(ctx, blob, config) } +func (api *PrivateDebugAPI) TraceBadBlock(ctx context.Context, index int, config *TraceConfig) ([]*txTraceResult, error) { + if len := len(api.eth.blockchain.BadBlocks()); index < len { + block := api.eth.blockchain.BadBlocks()[index] + return api.traceBlock(ctx, block, config) + } + return nil, fmt.Errorf("index out of range") +} // traceBlock configures a new tracer according to the provided configuration, and // executes all the transactions contained within. The return value will be one item diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index bf4b7808f7..addf3c7660 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -378,6 +378,12 @@ web3._extend({ params: 2, inputFormatter: [null, null] }), + new web3._extend.Method({ + name: 'traceBadBlock', + call: 'debug_traceBadBlock', + params: 1, + inputFormatter: [null] + }), new web3._extend.Method({ name: 'traceBlockByNumber', call: 'debug_traceBlockByNumber',