mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 15:16:43 +00:00
Merge branch 'extended-tracer-backport-1.13.5' into feature/sei-extended-tracer-more-backport
# Conflicts: # core/state_processor.go # eth/tracers/api.go # lib/ethapi/api.go # lib/ethapi/transaction_args.go
This commit is contained in:
commit
caf980e5ee
30 changed files with 230 additions and 275 deletions
|
|
@ -34,7 +34,7 @@ import (
|
||||||
"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/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/eth/tracers/directory"
|
"github.com/ethereum/go-ethereum/eth/tracers"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
|
@ -121,7 +121,7 @@ type rejectedTx struct {
|
||||||
// Apply applies a set of transactions to a pre-state
|
// Apply applies a set of transactions to a pre-state
|
||||||
func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
txIt txIterator, miningReward int64,
|
txIt txIterator, miningReward int64,
|
||||||
getTracerFn func(txIndex int, txHash common.Hash) (*directory.Tracer, io.WriteCloser, error)) (*state.StateDB, *ExecutionResult, []byte, error) {
|
getTracerFn func(txIndex int, txHash common.Hash) (*tracers.Tracer, io.WriteCloser, error)) (*state.StateDB, *ExecutionResult, []byte, error) {
|
||||||
// Capture errors for BLOCKHASH operation, if we haven't been supplied the
|
// Capture errors for BLOCKHASH operation, if we haven't been supplied the
|
||||||
// required blockhashes
|
// required blockhashes
|
||||||
var hashError error
|
var hashError error
|
||||||
|
|
@ -419,7 +419,7 @@ func calcDifficulty(config *params.ChainConfig, number, currentTime, parentTime
|
||||||
return ethash.CalcDifficulty(config, currentTime, parent)
|
return ethash.CalcDifficulty(config, currentTime, parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeTraceResult(tracer *directory.Tracer, f io.WriteCloser) error {
|
func writeTraceResult(tracer *tracers.Tracer, f io.WriteCloser) error {
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
result, err := tracer.GetResult()
|
result, err := tracer.GetResult()
|
||||||
if err != nil || result == nil {
|
if err != nil || result == nil {
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"golang.org/x/exp/slog"
|
"golang.org/x/exp/slog"
|
||||||
|
|
||||||
|
|
@ -34,7 +35,7 @@ import (
|
||||||
"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/directory"
|
"github.com/ethereum/go-ethereum/eth/tracers"
|
||||||
"github.com/ethereum/go-ethereum/eth/tracers/logger"
|
"github.com/ethereum/go-ethereum/eth/tracers/logger"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
|
@ -89,7 +90,7 @@ func Transition(ctx *cli.Context) error {
|
||||||
glogger.Verbosity(slog.Level(ctx.Int(VerbosityFlag.Name)))
|
glogger.Verbosity(slog.Level(ctx.Int(VerbosityFlag.Name)))
|
||||||
log.SetDefault(log.NewLogger(glogger))
|
log.SetDefault(log.NewLogger(glogger))
|
||||||
|
|
||||||
var getTracer = func(txIndex int, txHash common.Hash) (*directory.Tracer, io.WriteCloser, error) { return nil, nil, nil }
|
var getTracer = func(txIndex int, txHash common.Hash) (*tracers.Tracer, io.WriteCloser, error) { return nil, nil, nil }
|
||||||
baseDir, err := createBasedir(ctx)
|
baseDir, err := createBasedir(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return NewError(ErrorIO, fmt.Errorf("failed creating output basedir: %v", err))
|
return NewError(ErrorIO, fmt.Errorf("failed creating output basedir: %v", err))
|
||||||
|
|
@ -121,13 +122,13 @@ func Transition(ctx *cli.Context) error {
|
||||||
prevFile.Close()
|
prevFile.Close()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
getTracer = func(txIndex int, txHash common.Hash) (*directory.Tracer, io.WriteCloser, error) {
|
getTracer = func(txIndex int, txHash common.Hash) (*tracers.Tracer, io.WriteCloser, error) {
|
||||||
traceFile, err := os.Create(path.Join(baseDir, fmt.Sprintf("trace-%d-%v.jsonl", txIndex, txHash.String())))
|
traceFile, err := os.Create(filepath.Join(baseDir, fmt.Sprintf("trace-%d-%v.jsonl", txIndex, txHash.String())))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, NewError(ErrorIO, fmt.Errorf("failed creating trace-file: %v", err))
|
return nil, nil, NewError(ErrorIO, fmt.Errorf("failed creating trace-file: %v", err))
|
||||||
}
|
}
|
||||||
logger := logger.NewJSONLogger(logConfig, traceFile)
|
logger := logger.NewJSONLogger(logConfig, traceFile)
|
||||||
tracer := &directory.Tracer{
|
tracer := &tracers.Tracer{
|
||||||
Hooks: logger,
|
Hooks: logger,
|
||||||
// jsonLogger streams out result to file.
|
// jsonLogger streams out result to file.
|
||||||
GetResult: func() (json.RawMessage, error) { return nil, nil },
|
GetResult: func() (json.RawMessage, error) { return nil, nil },
|
||||||
|
|
@ -140,12 +141,12 @@ func Transition(ctx *cli.Context) error {
|
||||||
if ctx.IsSet(TraceTracerConfigFlag.Name) {
|
if ctx.IsSet(TraceTracerConfigFlag.Name) {
|
||||||
config = []byte(ctx.String(TraceTracerConfigFlag.Name))
|
config = []byte(ctx.String(TraceTracerConfigFlag.Name))
|
||||||
}
|
}
|
||||||
getTracer = func(txIndex int, txHash common.Hash) (*directory.Tracer, io.WriteCloser, error) {
|
getTracer = func(txIndex int, txHash common.Hash) (*tracers.Tracer, io.WriteCloser, error) {
|
||||||
traceFile, err := os.Create(path.Join(baseDir, fmt.Sprintf("trace-%d-%v.json", txIndex, txHash.String())))
|
traceFile, err := os.Create(filepath.Join(baseDir, fmt.Sprintf("trace-%d-%v.json", txIndex, txHash.String())))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, NewError(ErrorIO, fmt.Errorf("failed creating trace-file: %v", err))
|
return nil, nil, NewError(ErrorIO, fmt.Errorf("failed creating trace-file: %v", err))
|
||||||
}
|
}
|
||||||
tracer, err := directory.DefaultDirectory.New(ctx.String(TraceTracerFlag.Name), nil, config)
|
tracer, err := tracers.DefaultDirectory.New(ctx.String(TraceTracerFlag.Name), nil, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, NewError(ErrorConfig, fmt.Errorf("failed instantiating tracer: %w", err))
|
return nil, nil, NewError(ErrorConfig, fmt.Errorf("failed instantiating tracer: %w", err))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,10 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/lib/debug"
|
"github.com/ethereum/go-ethereum/lib/debug"
|
||||||
"github.com/ethereum/go-ethereum/lib/flags"
|
"github.com/ethereum/go-ethereum/lib/flags"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
|
|
||||||
|
// Force-load the tracer engines to trigger registration
|
||||||
|
_ "github.com/ethereum/go-ethereum/eth/tracers/js"
|
||||||
|
_ "github.com/ethereum/go-ethereum/eth/tracers/native"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -143,6 +147,8 @@ var stateTransitionCommand = &cli.Command{
|
||||||
Action: t8ntool.Transition,
|
Action: t8ntool.Transition,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
t8ntool.TraceFlag,
|
t8ntool.TraceFlag,
|
||||||
|
t8ntool.TraceTracerFlag,
|
||||||
|
t8ntool.TraceTracerConfigFlag,
|
||||||
t8ntool.TraceDisableMemoryFlag,
|
t8ntool.TraceDisableMemoryFlag,
|
||||||
t8ntool.TraceEnableMemoryFlag,
|
t8ntool.TraceEnableMemoryFlag,
|
||||||
t8ntool.TraceDisableStackFlag,
|
t8ntool.TraceDisableStackFlag,
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/eth/filters"
|
"github.com/ethereum/go-ethereum/eth/filters"
|
||||||
"github.com/ethereum/go-ethereum/eth/gasprice"
|
"github.com/ethereum/go-ethereum/eth/gasprice"
|
||||||
"github.com/ethereum/go-ethereum/eth/tracers"
|
"github.com/ethereum/go-ethereum/eth/tracers"
|
||||||
"github.com/ethereum/go-ethereum/eth/tracers/directory/live"
|
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/ethdb/remotedb"
|
"github.com/ethereum/go-ethereum/ethdb/remotedb"
|
||||||
"github.com/ethereum/go-ethereum/ethstats"
|
"github.com/ethereum/go-ethereum/ethstats"
|
||||||
|
|
@ -2145,7 +2144,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh
|
||||||
if ctx.IsSet(VMTraceConfigFlag.Name) {
|
if ctx.IsSet(VMTraceConfigFlag.Name) {
|
||||||
config = json.RawMessage(ctx.String(VMTraceConfigFlag.Name))
|
config = json.RawMessage(ctx.String(VMTraceConfigFlag.Name))
|
||||||
}
|
}
|
||||||
t, err := live.Directory.New(name, config)
|
t, err := tracers.LiveDirectory.New(name, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatalf("Failed to create tracer %q: %v", name, err)
|
Fatalf("Failed to create tracer %q: %v", name, err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1834,6 +1834,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
|
||||||
throwaway, _ := state.New(parent.Root, bc.stateCache, bc.snaps)
|
throwaway, _ := state.New(parent.Root, bc.stateCache, bc.snaps)
|
||||||
|
|
||||||
go func(start time.Time, followup *types.Block, throwaway *state.StateDB) {
|
go func(start time.Time, followup *types.Block, throwaway *state.StateDB) {
|
||||||
|
// Disable tracing for prefetcher executions.
|
||||||
vmCfg := bc.vmConfig
|
vmCfg := bc.vmConfig
|
||||||
vmCfg.Tracer = nil
|
vmCfg.Tracer = nil
|
||||||
bc.prefetcher.Prefetch(followup, throwaway, vmCfg, &followupInterrupt)
|
bc.prefetcher.Prefetch(followup, throwaway, vmCfg, &followupInterrupt)
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"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/tracing"
|
|
||||||
"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/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
|
@ -111,14 +110,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb vm.StateDB, cfg vm.
|
||||||
// this method takes an already created EVM instance as input.
|
// this method takes an already created EVM instance as input.
|
||||||
func ApplyTransactionWithEVM(msg *Message, config *params.ChainConfig, gp *GasPool, statedb vm.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (receipt *types.Receipt, err error) {
|
func ApplyTransactionWithEVM(msg *Message, config *params.ChainConfig, gp *GasPool, statedb vm.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (receipt *types.Receipt, err error) {
|
||||||
if evm.Config.Tracer != nil && evm.Config.Tracer.OnTxStart != nil {
|
if evm.Config.Tracer != nil && evm.Config.Tracer.OnTxStart != nil {
|
||||||
evm.Config.Tracer.OnTxStart(&tracing.VMContext{
|
evm.Config.Tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
|
||||||
ChainConfig: evm.ChainConfig(),
|
|
||||||
StateDB: statedb,
|
|
||||||
BlockNumber: evm.Context.BlockNumber,
|
|
||||||
Time: evm.Context.Time,
|
|
||||||
Coinbase: evm.Context.Coinbase,
|
|
||||||
Random: evm.Context.Random,
|
|
||||||
}, tx, msg.From)
|
|
||||||
if evm.Config.Tracer.OnTxEnd != nil {
|
if evm.Config.Tracer.OnTxEnd != nil {
|
||||||
defer func() {
|
defer func() {
|
||||||
evm.Config.Tracer.OnTxEnd(receipt, err)
|
evm.Config.Tracer.OnTxEnd(receipt, err)
|
||||||
|
|
|
||||||
|
|
@ -140,8 +140,6 @@ type Message struct {
|
||||||
AccessList types.AccessList
|
AccessList types.AccessList
|
||||||
BlobGasFeeCap *big.Int
|
BlobGasFeeCap *big.Int
|
||||||
BlobHashes []common.Hash
|
BlobHashes []common.Hash
|
||||||
// Distinguishes type-2 txes
|
|
||||||
DynamicFee bool
|
|
||||||
|
|
||||||
// When SkipAccountChecks is true, the message nonce is not checked against the
|
// When SkipAccountChecks is true, the message nonce is not checked against the
|
||||||
// account nonce in state. It also disables checking that the sender is an EOA.
|
// account nonce in state. It also disables checking that the sender is an EOA.
|
||||||
|
|
@ -164,7 +162,6 @@ func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.In
|
||||||
SkipAccountChecks: false,
|
SkipAccountChecks: false,
|
||||||
BlobHashes: tx.BlobHashes(),
|
BlobHashes: tx.BlobHashes(),
|
||||||
BlobGasFeeCap: tx.BlobGasFeeCap(),
|
BlobGasFeeCap: tx.BlobGasFeeCap(),
|
||||||
DynamicFee: tx.Type() == 2 || tx.Type() == 3,
|
|
||||||
}
|
}
|
||||||
// If baseFee provided, set gasPrice to effectiveGasPrice.
|
// If baseFee provided, set gasPrice to effectiveGasPrice.
|
||||||
if baseFee != nil {
|
if baseFee != nil {
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
|
||||||
sender = vm.AccountRef(cfg.Origin)
|
sender = vm.AccountRef(cfg.Origin)
|
||||||
rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, vmenv.Context.Random != nil, vmenv.Context.Time)
|
rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, vmenv.Context.Random != nil, vmenv.Context.Time)
|
||||||
)
|
)
|
||||||
if cfg.EVMConfig.Tracer != nil {
|
if cfg.EVMConfig.Tracer != nil && cfg.EVMConfig.Tracer.OnTxStart != nil {
|
||||||
cfg.EVMConfig.Tracer.OnTxStart(vmenv.GetVMContext(), types.NewTx(&types.LegacyTx{To: &address, Data: input, Value: cfg.Value, Gas: cfg.GasLimit}), cfg.Origin)
|
cfg.EVMConfig.Tracer.OnTxStart(vmenv.GetVMContext(), types.NewTx(&types.LegacyTx{To: &address, Data: input, Value: cfg.Value, Gas: cfg.GasLimit}), cfg.Origin)
|
||||||
}
|
}
|
||||||
// Execute the preparatory steps for state transition which includes:
|
// Execute the preparatory steps for state transition which includes:
|
||||||
|
|
@ -158,7 +158,7 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
|
||||||
sender = vm.AccountRef(cfg.Origin)
|
sender = vm.AccountRef(cfg.Origin)
|
||||||
rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, vmenv.Context.Random != nil, vmenv.Context.Time)
|
rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, vmenv.Context.Random != nil, vmenv.Context.Time)
|
||||||
)
|
)
|
||||||
if cfg.EVMConfig.Tracer != nil {
|
if cfg.EVMConfig.Tracer != nil && cfg.EVMConfig.Tracer.OnTxStart != nil {
|
||||||
cfg.EVMConfig.Tracer.OnTxStart(vmenv.GetVMContext(), types.NewTx(&types.LegacyTx{Data: input, Value: cfg.Value, Gas: cfg.GasLimit}), cfg.Origin)
|
cfg.EVMConfig.Tracer.OnTxStart(vmenv.GetVMContext(), types.NewTx(&types.LegacyTx{Data: input, Value: cfg.Value, Gas: cfg.GasLimit}), cfg.Origin)
|
||||||
}
|
}
|
||||||
// Execute the preparatory steps for state transition which includes:
|
// Execute the preparatory steps for state transition which includes:
|
||||||
|
|
@ -189,7 +189,7 @@ func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, er
|
||||||
statedb = cfg.State
|
statedb = cfg.State
|
||||||
rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, vmenv.Context.Random != nil, vmenv.Context.Time)
|
rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, vmenv.Context.Random != nil, vmenv.Context.Time)
|
||||||
)
|
)
|
||||||
if cfg.EVMConfig.Tracer != nil {
|
if cfg.EVMConfig.Tracer != nil && cfg.EVMConfig.Tracer.OnTxStart != nil {
|
||||||
cfg.EVMConfig.Tracer.OnTxStart(vmenv.GetVMContext(), types.NewTx(&types.LegacyTx{To: &address, Data: input, Value: cfg.Value, Gas: cfg.GasLimit}), cfg.Origin)
|
cfg.EVMConfig.Tracer.OnTxStart(vmenv.GetVMContext(), types.NewTx(&types.LegacyTx{To: &address, Data: input, Value: cfg.Value, Gas: cfg.GasLimit}), cfg.Origin)
|
||||||
}
|
}
|
||||||
// Execute the preparatory steps for state transition which includes:
|
// Execute the preparatory steps for state transition which includes:
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ import (
|
||||||
"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/directory"
|
"github.com/ethereum/go-ethereum/eth/tracers"
|
||||||
"github.com/ethereum/go-ethereum/eth/tracers/logger"
|
"github.com/ethereum/go-ethereum/eth/tracers/logger"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
|
||||||
|
|
@ -330,7 +330,7 @@ func benchmarkNonModifyingCode(gas uint64, code []byte, name string, tracerCode
|
||||||
cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
||||||
cfg.GasLimit = gas
|
cfg.GasLimit = gas
|
||||||
if len(tracerCode) > 0 {
|
if len(tracerCode) > 0 {
|
||||||
tracer, err := directory.DefaultDirectory.New(tracerCode, new(directory.Context), nil)
|
tracer, err := tracers.DefaultDirectory.New(tracerCode, new(tracers.Context), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
@ -826,7 +826,7 @@ func TestRuntimeJSTracer(t *testing.T) {
|
||||||
statedb.SetCode(common.HexToAddress("0xee"), calleeCode)
|
statedb.SetCode(common.HexToAddress("0xee"), calleeCode)
|
||||||
statedb.SetCode(common.HexToAddress("0xff"), suicideCode)
|
statedb.SetCode(common.HexToAddress("0xff"), suicideCode)
|
||||||
|
|
||||||
tracer, err := directory.DefaultDirectory.New(jsTracer, new(directory.Context), nil)
|
tracer, err := tracers.DefaultDirectory.New(jsTracer, new(tracers.Context), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
@ -861,7 +861,7 @@ func TestJSTracerCreateTx(t *testing.T) {
|
||||||
code := []byte{byte(vm.PUSH1), 0, byte(vm.PUSH1), 0, byte(vm.RETURN)}
|
code := []byte{byte(vm.PUSH1), 0, byte(vm.PUSH1), 0, byte(vm.RETURN)}
|
||||||
|
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
||||||
tracer, err := directory.DefaultDirectory.New(jsTracer, new(directory.Context), nil)
|
tracer, err := tracers.DefaultDirectory.New(jsTracer, new(tracers.Context), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/eth/gasprice"
|
"github.com/ethereum/go-ethereum/eth/gasprice"
|
||||||
"github.com/ethereum/go-ethereum/eth/protocols/eth"
|
"github.com/ethereum/go-ethereum/eth/protocols/eth"
|
||||||
"github.com/ethereum/go-ethereum/eth/protocols/snap"
|
"github.com/ethereum/go-ethereum/eth/protocols/snap"
|
||||||
"github.com/ethereum/go-ethereum/eth/tracers/directory/live"
|
"github.com/ethereum/go-ethereum/eth/tracers"
|
||||||
"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/lib/ethapi"
|
"github.com/ethereum/go-ethereum/lib/ethapi"
|
||||||
|
|
@ -212,7 +212,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
||||||
if config.VMTraceConfig != "" {
|
if config.VMTraceConfig != "" {
|
||||||
traceConfig = json.RawMessage(config.VMTraceConfig)
|
traceConfig = json.RawMessage(config.VMTraceConfig)
|
||||||
}
|
}
|
||||||
t, err := live.Directory.New(config.VMTrace, traceConfig)
|
t, err := tracers.LiveDirectory.New(config.VMTrace, traceConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Failed to create tracer %s: %v", config.VMTrace, err)
|
return nil, fmt.Errorf("Failed to create tracer %s: %v", config.VMTrace, err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,6 @@ import (
|
||||||
"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/directory"
|
|
||||||
"github.com/ethereum/go-ethereum/eth/tracers/logger"
|
"github.com/ethereum/go-ethereum/eth/tracers/logger"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/lib/ethapi"
|
"github.com/ethereum/go-ethereum/lib/ethapi"
|
||||||
|
|
@ -273,7 +272,7 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
|
||||||
// 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, _ := core.TransactionToMessage(tx, signer, task.block.BaseFee())
|
msg, _ := core.TransactionToMessage(tx, signer, task.block.BaseFee())
|
||||||
txctx := &directory.Context{
|
txctx := &Context{
|
||||||
BlockHash: task.block.Hash(),
|
BlockHash: task.block.Hash(),
|
||||||
BlockNumber: task.block.Number(),
|
BlockNumber: task.block.Number(),
|
||||||
TxIndex: i,
|
TxIndex: i,
|
||||||
|
|
@ -590,7 +589,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
|
||||||
// process that generates states in one thread and traces txes
|
// process that generates states in one thread and traces txes
|
||||||
// in separate worker threads.
|
// in separate worker threads.
|
||||||
if config != nil && config.Tracer != nil && *config.Tracer != "" {
|
if config != nil && config.Tracer != nil && *config.Tracer != "" {
|
||||||
if isJS := directory.DefaultDirectory.IsJS(*config.Tracer); isJS {
|
if isJS := DefaultDirectory.IsJS(*config.Tracer); isJS {
|
||||||
return api.traceBlockParallel(ctx, block, statedb, config)
|
return api.traceBlockParallel(ctx, block, statedb, config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -605,7 +604,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
|
||||||
for i, tx := range txs {
|
for i, tx := range txs {
|
||||||
// Generate the next state snapshot fast without tracing
|
// Generate the next state snapshot fast without tracing
|
||||||
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
|
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
|
||||||
txctx := &directory.Context{
|
txctx := &Context{
|
||||||
BlockHash: blockHash,
|
BlockHash: blockHash,
|
||||||
BlockNumber: block.Number(),
|
BlockNumber: block.Number(),
|
||||||
TxIndex: i,
|
TxIndex: i,
|
||||||
|
|
@ -644,7 +643,7 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat
|
||||||
// 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, _ := core.TransactionToMessage(txs[task.index], signer, block.BaseFee())
|
msg, _ := core.TransactionToMessage(txs[task.index], signer, block.BaseFee())
|
||||||
txctx := &directory.Context{
|
txctx := &Context{
|
||||||
BlockHash: blockHash,
|
BlockHash: blockHash,
|
||||||
BlockNumber: block.Number(),
|
BlockNumber: block.Number(),
|
||||||
TxIndex: task.index,
|
TxIndex: task.index,
|
||||||
|
|
@ -859,7 +858,7 @@ func (api *API) TraceTransaction(ctx context.Context, hash common.Hash, config *
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
txctx := &directory.Context{
|
txctx := &Context{
|
||||||
BlockHash: blockHash,
|
BlockHash: blockHash,
|
||||||
BlockNumber: block.Number(),
|
BlockNumber: block.Number(),
|
||||||
TxIndex: int(index),
|
TxIndex: int(index),
|
||||||
|
|
@ -926,27 +925,26 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc
|
||||||
config.BlockOverrides.Apply(&vmctx)
|
config.BlockOverrides.Apply(&vmctx)
|
||||||
}
|
}
|
||||||
// Execute the trace
|
// Execute the trace
|
||||||
msg, err := args.ToMessage(api.backend.RPCGasCap(), vmctx.BaseFee)
|
if err := args.CallDefaults(api.backend.RPCGasCap(), vmctx.BaseFee, api.backend.ChainConfig().ChainID); err != nil {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
tx, err := argsToTransaction(api.backend, &args, msg)
|
var (
|
||||||
if err != nil {
|
msg = args.ToMessage(vmctx.BaseFee)
|
||||||
return nil, err
|
tx = args.ToTransaction()
|
||||||
}
|
traceConfig *TraceConfig
|
||||||
var traceConfig *TraceConfig
|
)
|
||||||
if config != nil {
|
if config != nil {
|
||||||
traceConfig = &config.TraceConfig
|
traceConfig = &config.TraceConfig
|
||||||
}
|
}
|
||||||
return api.traceTx(ctx, tx, msg, new(directory.Context), vmctx, statedb, traceConfig)
|
return api.traceTx(ctx, tx, msg, new(Context), vmctx, statedb, traceConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 *API) traceTx(ctx context.Context, tx *types.Transaction, message *core.Message, txctx *directory.Context, vmctx vm.BlockContext, statedb vm.StateDB, config *TraceConfig) (interface{}, error) {
|
func (api *API) traceTx(ctx context.Context, tx *types.Transaction, message *core.Message, txctx *Context, vmctx vm.BlockContext, statedb vm.StateDB, config *TraceConfig) (interface{}, error) {
|
||||||
var (
|
var (
|
||||||
tracer *directory.Tracer
|
tracer *Tracer
|
||||||
err error
|
err error
|
||||||
timeout = defaultTraceTimeout
|
timeout = defaultTraceTimeout
|
||||||
usedGas uint64
|
usedGas uint64
|
||||||
|
|
@ -955,9 +953,15 @@ func (api *API) traceTx(ctx context.Context, tx *types.Transaction, message *cor
|
||||||
config = &TraceConfig{}
|
config = &TraceConfig{}
|
||||||
}
|
}
|
||||||
// Default tracer is the struct logger
|
// Default tracer is the struct logger
|
||||||
tracer = logger.NewStructLogger(config.Config).Tracer()
|
if config.Tracer == nil {
|
||||||
if config.Tracer != nil {
|
logger := logger.NewStructLogger(config.Config)
|
||||||
tracer, err = directory.DefaultDirectory.New(*config.Tracer, txctx, config.TracerConfig)
|
tracer = &Tracer{
|
||||||
|
Hooks: logger.Hooks(),
|
||||||
|
GetResult: logger.GetResult,
|
||||||
|
Stop: logger.Stop,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tracer, err = DefaultDirectory.New(*config.Tracer, txctx, config.TracerConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -1050,54 +1054,3 @@ func overrideConfig(original *params.ChainConfig, override *params.ChainConfig)
|
||||||
|
|
||||||
return copy, canon
|
return copy, canon
|
||||||
}
|
}
|
||||||
|
|
||||||
// argsToTransaction produces a Transaction object given call arguments.
|
|
||||||
// The `msg` field must be converted from the same arguments.
|
|
||||||
func argsToTransaction(b Backend, args *ethapi.TransactionArgs, msg *core.Message) (*types.Transaction, error) {
|
|
||||||
chainID := b.ChainConfig().ChainID
|
|
||||||
if args.ChainID != nil {
|
|
||||||
if have := (*big.Int)(args.ChainID); have.Cmp(chainID) != 0 {
|
|
||||||
return nil, fmt.Errorf("chainId does not match node's (have=%v, want=%v)", have, chainID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var data types.TxData
|
|
||||||
switch {
|
|
||||||
case args.MaxFeePerGas != nil:
|
|
||||||
al := types.AccessList{}
|
|
||||||
if args.AccessList != nil {
|
|
||||||
al = *args.AccessList
|
|
||||||
}
|
|
||||||
data = &types.DynamicFeeTx{
|
|
||||||
To: args.To,
|
|
||||||
ChainID: chainID,
|
|
||||||
Nonce: msg.Nonce,
|
|
||||||
Gas: msg.GasLimit,
|
|
||||||
GasFeeCap: msg.GasFeeCap,
|
|
||||||
GasTipCap: msg.GasTipCap,
|
|
||||||
Value: msg.Value,
|
|
||||||
Data: msg.Data,
|
|
||||||
AccessList: al,
|
|
||||||
}
|
|
||||||
case args.AccessList != nil:
|
|
||||||
data = &types.AccessListTx{
|
|
||||||
To: args.To,
|
|
||||||
ChainID: chainID,
|
|
||||||
Nonce: msg.Nonce,
|
|
||||||
Gas: msg.GasLimit,
|
|
||||||
GasPrice: msg.GasPrice,
|
|
||||||
Value: msg.Value,
|
|
||||||
Data: msg.Data,
|
|
||||||
AccessList: *args.AccessList,
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
data = &types.LegacyTx{
|
|
||||||
To: args.To,
|
|
||||||
Nonce: msg.Nonce,
|
|
||||||
Gas: msg.GasLimit,
|
|
||||||
GasPrice: msg.GasPrice,
|
|
||||||
Value: msg.Value,
|
|
||||||
Data: msg.Data,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return types.NewTx(data), nil
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,7 @@
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
// Package directory provides functionality to lookup tracers by name.
|
package tracers
|
||||||
// It also includes utility functions that are imported by the other
|
|
||||||
// tracing packages.
|
|
||||||
package directory
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
@ -33,7 +33,7 @@ import (
|
||||||
"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/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/eth/tracers/directory"
|
"github.com/ethereum/go-ethereum/eth/tracers"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/tests"
|
"github.com/ethereum/go-ethereum/tests"
|
||||||
|
|
@ -139,7 +139,7 @@ func testCallTracer(tracerName string, dirPath string, t *testing.T) {
|
||||||
)
|
)
|
||||||
triedb.Close()
|
triedb.Close()
|
||||||
|
|
||||||
tracer, err := directory.DefaultDirectory.New(tracerName, new(directory.Context), test.TracerConfig)
|
tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), test.TracerConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create call tracer: %v", err)
|
t.Fatalf("failed to create call tracer: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -247,7 +247,7 @@ func benchTracer(tracerName string, test *callTracerTest, b *testing.B) {
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
tracer, err := directory.DefaultDirectory.New(tracerName, new(directory.Context), nil)
|
tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("failed to create call tracer: %v", err)
|
b.Fatalf("failed to create call tracer: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -283,8 +283,8 @@ func TestInternals(t *testing.T) {
|
||||||
BaseFee: new(big.Int),
|
BaseFee: new(big.Int),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
mkTracer := func(name string, cfg json.RawMessage) *directory.Tracer {
|
mkTracer := func(name string, cfg json.RawMessage) *tracers.Tracer {
|
||||||
tr, err := directory.DefaultDirectory.New(name, nil, cfg)
|
tr, err := tracers.DefaultDirectory.New(name, nil, cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create call tracer: %v", err)
|
t.Fatalf("failed to create call tracer: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -294,7 +294,7 @@ func TestInternals(t *testing.T) {
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
name string
|
name string
|
||||||
code []byte
|
code []byte
|
||||||
tracer *directory.Tracer
|
tracer *tracers.Tracer
|
||||||
want string
|
want string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
"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/directory"
|
"github.com/ethereum/go-ethereum/eth/tracers"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/tests"
|
"github.com/ethereum/go-ethereum/tests"
|
||||||
)
|
)
|
||||||
|
|
@ -97,7 +97,7 @@ func flatCallTracerTestRunner(tracerName string, filename string, dirPath string
|
||||||
defer triedb.Close()
|
defer triedb.Close()
|
||||||
|
|
||||||
// Create the tracer, the EVM environment and run it
|
// Create the tracer, the EVM environment and run it
|
||||||
tracer, err := directory.DefaultDirectory.New(tracerName, new(directory.Context), test.TracerConfig)
|
tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), test.TracerConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create call tracer: %v", err)
|
return fmt.Errorf("failed to create call tracer: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
"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/directory"
|
"github.com/ethereum/go-ethereum/eth/tracers"
|
||||||
"github.com/ethereum/go-ethereum/tests"
|
"github.com/ethereum/go-ethereum/tests"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -113,7 +113,7 @@ func testPrestateDiffTracer(tracerName string, dirPath string, t *testing.T) {
|
||||||
context.BlobBaseFee = eip4844.CalcBlobFee(excessBlobGas)
|
context.BlobBaseFee = eip4844.CalcBlobFee(excessBlobGas)
|
||||||
}
|
}
|
||||||
|
|
||||||
tracer, err := directory.DefaultDirectory.New(tracerName, new(directory.Context), test.TracerConfig)
|
tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), test.TracerConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create call tracer: %v", err)
|
t.Fatalf("failed to create call tracer: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
package directory
|
package internal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
@ -62,6 +62,7 @@ func memoryCopy(m []byte, offset, size int64) (cpy []byte) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MemoryPtr returns a pointer to a slice of memory.
|
||||||
func MemoryPtr(m []byte, offset, size int64) []byte {
|
func MemoryPtr(m []byte, offset, size int64) []byte {
|
||||||
if size == 0 {
|
if size == 0 {
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
package directory
|
package internal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
@ -25,7 +25,8 @@ import (
|
||||||
"github.com/dop251/goja"
|
"github.com/dop251/goja"
|
||||||
"github.com/ethereum/go-ethereum/core/tracing"
|
"github.com/ethereum/go-ethereum/core/tracing"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/eth/tracers/directory"
|
"github.com/ethereum/go-ethereum/eth/tracers"
|
||||||
|
"github.com/ethereum/go-ethereum/eth/tracers/internal"
|
||||||
"github.com/holiman/uint256"
|
"github.com/holiman/uint256"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
|
@ -44,16 +45,16 @@ func init() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
type ctorFn = func(*directory.Context, json.RawMessage) (*directory.Tracer, error)
|
type ctorFn = func(*tracers.Context, json.RawMessage) (*tracers.Tracer, error)
|
||||||
lookup := func(code string) ctorFn {
|
lookup := func(code string) ctorFn {
|
||||||
return func(ctx *directory.Context, cfg json.RawMessage) (*directory.Tracer, error) {
|
return func(ctx *tracers.Context, cfg json.RawMessage) (*tracers.Tracer, error) {
|
||||||
return newJsTracer(code, ctx, cfg)
|
return newJsTracer(code, ctx, cfg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for name, code := range assetTracers {
|
for name, code := range assetTracers {
|
||||||
directory.DefaultDirectory.Register(name, lookup(code), true)
|
tracers.DefaultDirectory.Register(name, lookup(code), true)
|
||||||
}
|
}
|
||||||
directory.DefaultDirectory.RegisterJSEval(newJsTracer)
|
tracers.DefaultDirectory.RegisterJSEval(newJsTracer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// bigIntProgram is compiled once and the exported function mostly invoked to convert
|
// bigIntProgram is compiled once and the exported function mostly invoked to convert
|
||||||
|
|
@ -136,7 +137,7 @@ type jsTracer struct {
|
||||||
// The methods `result` and `fault` are required to be present.
|
// The methods `result` and `fault` are required to be present.
|
||||||
// The methods `step`, `enter`, and `exit` are optional, but note that
|
// The methods `step`, `enter`, and `exit` are optional, but note that
|
||||||
// `enter` and `exit` always go together.
|
// `enter` and `exit` always go together.
|
||||||
func newJsTracer(code string, ctx *directory.Context, cfg json.RawMessage) (*directory.Tracer, error) {
|
func newJsTracer(code string, ctx *tracers.Context, cfg json.RawMessage) (*tracers.Tracer, error) {
|
||||||
vm := goja.New()
|
vm := goja.New()
|
||||||
// By default field names are exported to JS as is, i.e. capitalized.
|
// By default field names are exported to JS as is, i.e. capitalized.
|
||||||
vm.SetFieldNameMapper(goja.UncapFieldNameMapper())
|
vm.SetFieldNameMapper(goja.UncapFieldNameMapper())
|
||||||
|
|
@ -149,7 +150,7 @@ func newJsTracer(code string, ctx *directory.Context, cfg json.RawMessage) (*dir
|
||||||
t.setBuiltinFunctions()
|
t.setBuiltinFunctions()
|
||||||
|
|
||||||
if ctx == nil {
|
if ctx == nil {
|
||||||
ctx = new(directory.Context)
|
ctx = new(tracers.Context)
|
||||||
}
|
}
|
||||||
if ctx.BlockHash != (common.Hash{}) {
|
if ctx.BlockHash != (common.Hash{}) {
|
||||||
blockHash, err := t.toBuf(vm, ctx.BlockHash.Bytes())
|
blockHash, err := t.toBuf(vm, ctx.BlockHash.Bytes())
|
||||||
|
|
@ -220,7 +221,7 @@ func newJsTracer(code string, ctx *directory.Context, cfg json.RawMessage) (*dir
|
||||||
t.frameResultValue = t.frameResult.setupObject()
|
t.frameResultValue = t.frameResult.setupObject()
|
||||||
t.logValue = t.log.setupObject()
|
t.logValue = t.log.setupObject()
|
||||||
|
|
||||||
return &directory.Tracer{
|
return &tracers.Tracer{
|
||||||
Hooks: &tracing.Hooks{
|
Hooks: &tracing.Hooks{
|
||||||
OnTxStart: t.OnTxStart,
|
OnTxStart: t.OnTxStart,
|
||||||
OnTxEnd: t.OnTxEnd,
|
OnTxEnd: t.OnTxEnd,
|
||||||
|
|
@ -643,7 +644,7 @@ func (mo *memoryObj) slice(begin, end int64) ([]byte, error) {
|
||||||
if end < begin || begin < 0 {
|
if end < begin || begin < 0 {
|
||||||
return nil, fmt.Errorf("tracer accessed out of bound memory: offset %d, end %d", begin, end)
|
return nil, fmt.Errorf("tracer accessed out of bound memory: offset %d, end %d", begin, end)
|
||||||
}
|
}
|
||||||
slice, err := directory.GetMemoryCopyPadded(mo.memory, begin, end-begin)
|
slice, err := internal.GetMemoryCopyPadded(mo.memory, begin, end-begin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -669,7 +670,7 @@ func (mo *memoryObj) getUint(addr int64) (*big.Int, error) {
|
||||||
if len(mo.memory) < int(addr)+32 || addr < 0 {
|
if len(mo.memory) < int(addr)+32 || addr < 0 {
|
||||||
return nil, fmt.Errorf("tracer accessed out of bound memory: available %d, offset %d, size %d", len(mo.memory), addr, 32)
|
return nil, fmt.Errorf("tracer accessed out of bound memory: available %d, offset %d, size %d", len(mo.memory), addr, 32)
|
||||||
}
|
}
|
||||||
return new(big.Int).SetBytes(directory.MemoryPtr(mo.memory, addr, 32)), nil
|
return new(big.Int).SetBytes(internal.MemoryPtr(mo.memory, addr, 32)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mo *memoryObj) Length() int {
|
func (mo *memoryObj) Length() int {
|
||||||
|
|
@ -709,7 +710,7 @@ func (s *stackObj) peek(idx int) (*big.Int, error) {
|
||||||
if len(s.stack) <= idx || idx < 0 {
|
if len(s.stack) <= idx || idx < 0 {
|
||||||
return nil, fmt.Errorf("tracer accessed out of bound stack: size %d, index %d", len(s.stack), idx)
|
return nil, fmt.Errorf("tracer accessed out of bound stack: size %d, index %d", len(s.stack), idx)
|
||||||
}
|
}
|
||||||
return directory.StackBack(s.stack, idx).ToBig(), nil
|
return internal.StackBack(s.stack, idx).ToBig(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *stackObj) Length() int {
|
func (s *stackObj) Length() int {
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ import (
|
||||||
"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/directory"
|
"github.com/ethereum/go-ethereum/eth/tracers"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -61,7 +61,7 @@ func testCtx() *vmContext {
|
||||||
return &vmContext{blockCtx: vm.BlockContext{BlockNumber: big.NewInt(1)}, txCtx: vm.TxContext{GasPrice: big.NewInt(100000)}}
|
return &vmContext{blockCtx: vm.BlockContext{BlockNumber: big.NewInt(1)}, txCtx: vm.TxContext{GasPrice: big.NewInt(100000)}}
|
||||||
}
|
}
|
||||||
|
|
||||||
func runTrace(tracer *directory.Tracer, vmctx *vmContext, chaincfg *params.ChainConfig, contractCode []byte) (json.RawMessage, error) {
|
func runTrace(tracer *tracers.Tracer, vmctx *vmContext, chaincfg *params.ChainConfig, contractCode []byte) (json.RawMessage, error) {
|
||||||
var (
|
var (
|
||||||
env = vm.NewEVM(vmctx.blockCtx, vmctx.txCtx, &dummyStatedb{}, chaincfg, vm.Config{Tracer: tracer.Hooks})
|
env = vm.NewEVM(vmctx.blockCtx, vmctx.txCtx, &dummyStatedb{}, chaincfg, vm.Config{Tracer: tracer.Hooks})
|
||||||
gasLimit uint64 = 31000
|
gasLimit uint64 = 31000
|
||||||
|
|
@ -264,14 +264,14 @@ func TestIsPrecompile(t *testing.T) {
|
||||||
|
|
||||||
func TestEnterExit(t *testing.T) {
|
func TestEnterExit(t *testing.T) {
|
||||||
// test that either both or none of enter() and exit() are defined
|
// test that either both or none of enter() and exit() are defined
|
||||||
if _, err := newJsTracer("{step: function() {}, fault: function() {}, result: function() { return null; }, enter: function() {}}", new(directory.Context), nil); err == nil {
|
if _, err := newJsTracer("{step: function() {}, fault: function() {}, result: function() { return null; }, enter: function() {}}", new(tracers.Context), nil); err == nil {
|
||||||
t.Fatal("tracer creation should've failed without exit() definition")
|
t.Fatal("tracer creation should've failed without exit() definition")
|
||||||
}
|
}
|
||||||
if _, err := newJsTracer("{step: function() {}, fault: function() {}, result: function() { return null; }, enter: function() {}, exit: function() {}}", new(directory.Context), nil); err != nil {
|
if _, err := newJsTracer("{step: function() {}, fault: function() {}, result: function() { return null; }, enter: function() {}, exit: function() {}}", new(tracers.Context), nil); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
// test that the enter and exit method are correctly invoked and the values passed
|
// test that the enter and exit method are correctly invoked and the values passed
|
||||||
tracer, err := newJsTracer("{enters: 0, exits: 0, enterGas: 0, gasUsed: 0, step: function() {}, fault: function() {}, result: function() { return {enters: this.enters, exits: this.exits, enterGas: this.enterGas, gasUsed: this.gasUsed} }, enter: function(frame) { this.enters++; this.enterGas = frame.getGas(); }, exit: function(res) { this.exits++; this.gasUsed = res.getGasUsed(); }}", new(directory.Context), nil)
|
tracer, err := newJsTracer("{enters: 0, exits: 0, enterGas: 0, gasUsed: 0, step: function() {}, fault: function() {}, result: function() { return {enters: this.enters, exits: this.exits, enterGas: this.enterGas, gasUsed: this.gasUsed} }, enter: function(frame) { this.enters++; this.enterGas = frame.getGas(); }, exit: function(res) { this.exits++; this.gasUsed = res.getGasUsed(); }}", new(tracers.Context), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
@ -293,7 +293,7 @@ func TestEnterExit(t *testing.T) {
|
||||||
|
|
||||||
func TestSetup(t *testing.T) {
|
func TestSetup(t *testing.T) {
|
||||||
// Test empty config
|
// Test empty config
|
||||||
_, err := newJsTracer(`{setup: function(cfg) { if (cfg !== "{}") { throw("invalid empty config") } }, fault: function() {}, result: function() {}}`, new(directory.Context), nil)
|
_, err := newJsTracer(`{setup: function(cfg) { if (cfg !== "{}") { throw("invalid empty config") } }, fault: function() {}, result: function() {}}`, new(tracers.Context), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|
@ -303,12 +303,12 @@ func TestSetup(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
// Test no setup func
|
// Test no setup func
|
||||||
_, err = newJsTracer(`{fault: function() {}, result: function() {}}`, new(directory.Context), cfg)
|
_, err = newJsTracer(`{fault: function() {}, result: function() {}}`, new(tracers.Context), cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
// Test config value
|
// Test config value
|
||||||
tracer, err := newJsTracer("{config: null, setup: function(cfg) { this.config = JSON.parse(cfg) }, step: function() {}, fault: function() {}, result: function() { return this.config.foo }}", new(directory.Context), cfg)
|
tracer, err := newJsTracer("{config: null, setup: function(cfg) { this.config = JSON.parse(cfg) }, step: function() {}, fault: function() {}, result: function() { return this.config.foo }}", new(tracers.Context), cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package live
|
package tracers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
@ -9,21 +9,21 @@ import (
|
||||||
|
|
||||||
type ctorFunc func(config json.RawMessage) (*tracing.Hooks, error)
|
type ctorFunc func(config json.RawMessage) (*tracing.Hooks, error)
|
||||||
|
|
||||||
// Directory is the collection of tracers which can be used
|
// LiveDirectory is the collection of tracers which can be used
|
||||||
// during normal block import operations.
|
// during normal block import operations.
|
||||||
var Directory = directory{elems: make(map[string]ctorFunc)}
|
var LiveDirectory = liveDirectory{elems: make(map[string]ctorFunc)}
|
||||||
|
|
||||||
type directory struct {
|
type liveDirectory struct {
|
||||||
elems map[string]ctorFunc
|
elems map[string]ctorFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register registers a tracer constructor by name.
|
// Register registers a tracer constructor by name.
|
||||||
func (d *directory) Register(name string, f ctorFunc) {
|
func (d *liveDirectory) Register(name string, f ctorFunc) {
|
||||||
d.elems[name] = f
|
d.elems[name] = f
|
||||||
}
|
}
|
||||||
|
|
||||||
// New instantiates a tracer by name.
|
// New instantiates a tracer by name.
|
||||||
func (d *directory) New(name string, config json.RawMessage) (*tracing.Hooks, error) {
|
func (d *liveDirectory) New(name string, config json.RawMessage) (*tracing.Hooks, error) {
|
||||||
if f, ok := d.elems[name]; ok {
|
if f, ok := d.elems[name]; ok {
|
||||||
return f(config)
|
return f(config)
|
||||||
}
|
}
|
||||||
|
|
@ -7,12 +7,12 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/tracing"
|
"github.com/ethereum/go-ethereum/core/tracing"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/eth/tracers/directory/live"
|
"github.com/ethereum/go-ethereum/eth/tracers"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
live.Directory.Register("noop", newNoopTracer)
|
tracers.LiveDirectory.Register("noop", newNoopTracer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// noop is a no-op live tracer. It's there to
|
// noop is a no-op live tracer. It's there to
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/tracing"
|
"github.com/ethereum/go-ethereum/core/tracing"
|
||||||
"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/directory"
|
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/holiman/uint256"
|
"github.com/holiman/uint256"
|
||||||
)
|
)
|
||||||
|
|
@ -142,14 +141,6 @@ func (l *StructLogger) Hooks() *tracing.Hooks {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *StructLogger) Tracer() *directory.Tracer {
|
|
||||||
return &directory.Tracer{
|
|
||||||
Hooks: l.Hooks(),
|
|
||||||
GetResult: l.GetResult,
|
|
||||||
Stop: l.Stop,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset clears the data held by the logger.
|
// Reset clears the data held by the logger.
|
||||||
func (l *StructLogger) Reset() {
|
func (l *StructLogger) Reset() {
|
||||||
l.storage = make(map[common.Address]Storage)
|
l.storage = make(map[common.Address]Storage)
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,11 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/tracing"
|
"github.com/ethereum/go-ethereum/core/tracing"
|
||||||
"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/directory"
|
"github.com/ethereum/go-ethereum/eth/tracers"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
directory.DefaultDirectory.Register("4byteTracer", newFourByteTracer, false)
|
tracers.DefaultDirectory.Register("4byteTracer", newFourByteTracer, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// fourByteTracer searches for 4byte-identifiers, and collects them for post-processing.
|
// fourByteTracer searches for 4byte-identifiers, and collects them for post-processing.
|
||||||
|
|
@ -56,11 +56,11 @@ type fourByteTracer struct {
|
||||||
|
|
||||||
// newFourByteTracer returns a native go tracer which collects
|
// newFourByteTracer returns a native go tracer which collects
|
||||||
// 4 byte-identifiers of a tx, and implements vm.EVMLogger.
|
// 4 byte-identifiers of a tx, and implements vm.EVMLogger.
|
||||||
func newFourByteTracer(ctx *directory.Context, _ json.RawMessage) (*directory.Tracer, error) {
|
func newFourByteTracer(ctx *tracers.Context, _ json.RawMessage) (*tracers.Tracer, error) {
|
||||||
t := &fourByteTracer{
|
t := &fourByteTracer{
|
||||||
ids: make(map[string]int),
|
ids: make(map[string]int),
|
||||||
}
|
}
|
||||||
return &directory.Tracer{
|
return &tracers.Tracer{
|
||||||
Hooks: &tracing.Hooks{
|
Hooks: &tracing.Hooks{
|
||||||
OnTxStart: t.OnTxStart,
|
OnTxStart: t.OnTxStart,
|
||||||
OnEnter: t.OnEnter,
|
OnEnter: t.OnEnter,
|
||||||
|
|
|
||||||
|
|
@ -28,13 +28,13 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/tracing"
|
"github.com/ethereum/go-ethereum/core/tracing"
|
||||||
"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/directory"
|
"github.com/ethereum/go-ethereum/eth/tracers"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate go run github.com/fjl/gencodec -type callFrame -field-override callFrameMarshaling -out gen_callframe_json.go
|
//go:generate go run github.com/fjl/gencodec -type callFrame -field-override callFrameMarshaling -out gen_callframe_json.go
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
directory.DefaultDirectory.Register("callTracer", newCallTracer, false)
|
tracers.DefaultDirectory.Register("callTracer", newCallTracer, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
type callLog struct {
|
type callLog struct {
|
||||||
|
|
@ -120,12 +120,12 @@ type callTracerConfig struct {
|
||||||
|
|
||||||
// newCallTracer returns a native go tracer which tracks
|
// newCallTracer returns a native go tracer which tracks
|
||||||
// call frames of a tx, and implements vm.EVMLogger.
|
// call frames of a tx, and implements vm.EVMLogger.
|
||||||
func newCallTracer(ctx *directory.Context, cfg json.RawMessage) (*directory.Tracer, error) {
|
func newCallTracer(ctx *tracers.Context, cfg json.RawMessage) (*tracers.Tracer, error) {
|
||||||
t, err := newCallTracerObject(ctx, cfg)
|
t, err := newCallTracerObject(ctx, cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &directory.Tracer{
|
return &tracers.Tracer{
|
||||||
Hooks: &tracing.Hooks{
|
Hooks: &tracing.Hooks{
|
||||||
OnTxStart: t.OnTxStart,
|
OnTxStart: t.OnTxStart,
|
||||||
OnTxEnd: t.OnTxEnd,
|
OnTxEnd: t.OnTxEnd,
|
||||||
|
|
@ -138,7 +138,7 @@ func newCallTracer(ctx *directory.Context, cfg json.RawMessage) (*directory.Trac
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newCallTracerObject(ctx *directory.Context, cfg json.RawMessage) (*callTracer, error) {
|
func newCallTracerObject(ctx *tracers.Context, cfg json.RawMessage) (*callTracer, error) {
|
||||||
var config callTracerConfig
|
var config callTracerConfig
|
||||||
if cfg != nil {
|
if cfg != nil {
|
||||||
if err := json.Unmarshal(cfg, &config); err != nil {
|
if err := json.Unmarshal(cfg, &config); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -28,14 +28,14 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/tracing"
|
"github.com/ethereum/go-ethereum/core/tracing"
|
||||||
"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/directory"
|
"github.com/ethereum/go-ethereum/eth/tracers"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate go run github.com/fjl/gencodec -type flatCallAction -field-override flatCallActionMarshaling -out gen_flatcallaction_json.go
|
//go:generate go run github.com/fjl/gencodec -type flatCallAction -field-override flatCallActionMarshaling -out gen_flatcallaction_json.go
|
||||||
//go:generate go run github.com/fjl/gencodec -type flatCallResult -field-override flatCallResultMarshaling -out gen_flatcallresult_json.go
|
//go:generate go run github.com/fjl/gencodec -type flatCallResult -field-override flatCallResultMarshaling -out gen_flatcallresult_json.go
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
directory.DefaultDirectory.Register("flatCallTracer", newFlatCallTracer, false)
|
tracers.DefaultDirectory.Register("flatCallTracer", newFlatCallTracer, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
var parityErrorMapping = map[string]string{
|
var parityErrorMapping = map[string]string{
|
||||||
|
|
@ -112,9 +112,9 @@ type flatCallResultMarshaling struct {
|
||||||
type flatCallTracer struct {
|
type flatCallTracer struct {
|
||||||
tracer *callTracer
|
tracer *callTracer
|
||||||
config flatCallTracerConfig
|
config flatCallTracerConfig
|
||||||
ctx *directory.Context // Holds tracer context data
|
ctx *tracers.Context // Holds tracer context data
|
||||||
reason error // Textual reason for the interruption
|
reason error // Textual reason for the interruption
|
||||||
activePrecompiles []common.Address // Updated on tx start based on given rules
|
activePrecompiles []common.Address // Updated on tx start based on given rules
|
||||||
}
|
}
|
||||||
|
|
||||||
type flatCallTracerConfig struct {
|
type flatCallTracerConfig struct {
|
||||||
|
|
@ -123,7 +123,7 @@ type flatCallTracerConfig struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// newFlatCallTracer returns a new flatCallTracer.
|
// newFlatCallTracer returns a new flatCallTracer.
|
||||||
func newFlatCallTracer(ctx *directory.Context, cfg json.RawMessage) (*directory.Tracer, error) {
|
func newFlatCallTracer(ctx *tracers.Context, cfg json.RawMessage) (*tracers.Tracer, error) {
|
||||||
var config flatCallTracerConfig
|
var config flatCallTracerConfig
|
||||||
if cfg != nil {
|
if cfg != nil {
|
||||||
if err := json.Unmarshal(cfg, &config); err != nil {
|
if err := json.Unmarshal(cfg, &config); err != nil {
|
||||||
|
|
@ -139,7 +139,7 @@ func newFlatCallTracer(ctx *directory.Context, cfg json.RawMessage) (*directory.
|
||||||
}
|
}
|
||||||
|
|
||||||
ft := &flatCallTracer{tracer: t, ctx: ctx, config: config}
|
ft := &flatCallTracer{tracer: t, ctx: ctx, config: config}
|
||||||
return &directory.Tracer{
|
return &tracers.Tracer{
|
||||||
Hooks: &tracing.Hooks{
|
Hooks: &tracing.Hooks{
|
||||||
OnTxStart: ft.OnTxStart,
|
OnTxStart: ft.OnTxStart,
|
||||||
OnTxEnd: ft.OnTxEnd,
|
OnTxEnd: ft.OnTxEnd,
|
||||||
|
|
@ -236,7 +236,7 @@ func (t *flatCallTracer) isPrecompiled(addr common.Address) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func flatFromNested(input *callFrame, traceAddress []int, convertErrs bool, ctx *directory.Context) (output []flatCallFrame, err error) {
|
func flatFromNested(input *callFrame, traceAddress []int, convertErrs bool, ctx *tracers.Context) (output []flatCallFrame, err error) {
|
||||||
var frame *flatCallFrame
|
var frame *flatCallFrame
|
||||||
switch input.Type {
|
switch input.Type {
|
||||||
case vm.CREATE, vm.CREATE2:
|
case vm.CREATE, vm.CREATE2:
|
||||||
|
|
@ -335,7 +335,7 @@ func newFlatSelfdestruct(input *callFrame) *flatCallFrame {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func fillCallFrameFromContext(callFrame *flatCallFrame, ctx *directory.Context) {
|
func fillCallFrameFromContext(callFrame *flatCallFrame, ctx *tracers.Context) {
|
||||||
if ctx == nil {
|
if ctx == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,32 +23,32 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/tracing"
|
"github.com/ethereum/go-ethereum/core/tracing"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/eth/tracers/directory"
|
"github.com/ethereum/go-ethereum/eth/tracers"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
directory.DefaultDirectory.Register("muxTracer", newMuxTracer, false)
|
tracers.DefaultDirectory.Register("muxTracer", newMuxTracer, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// muxTracer is a go implementation of the Tracer interface which
|
// muxTracer is a go implementation of the Tracer interface which
|
||||||
// runs multiple tracers in one go.
|
// runs multiple tracers in one go.
|
||||||
type muxTracer struct {
|
type muxTracer struct {
|
||||||
names []string
|
names []string
|
||||||
tracers []*directory.Tracer
|
tracers []*tracers.Tracer
|
||||||
}
|
}
|
||||||
|
|
||||||
// newMuxTracer returns a new mux tracer.
|
// newMuxTracer returns a new mux tracer.
|
||||||
func newMuxTracer(ctx *directory.Context, cfg json.RawMessage) (*directory.Tracer, error) {
|
func newMuxTracer(ctx *tracers.Context, cfg json.RawMessage) (*tracers.Tracer, error) {
|
||||||
var config map[string]json.RawMessage
|
var config map[string]json.RawMessage
|
||||||
if cfg != nil {
|
if cfg != nil {
|
||||||
if err := json.Unmarshal(cfg, &config); err != nil {
|
if err := json.Unmarshal(cfg, &config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
objects := make([]*directory.Tracer, 0, len(config))
|
objects := make([]*tracers.Tracer, 0, len(config))
|
||||||
names := make([]string, 0, len(config))
|
names := make([]string, 0, len(config))
|
||||||
for k, v := range config {
|
for k, v := range config {
|
||||||
t, err := directory.DefaultDirectory.New(k, ctx, v)
|
t, err := tracers.DefaultDirectory.New(k, ctx, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -57,7 +57,7 @@ func newMuxTracer(ctx *directory.Context, cfg json.RawMessage) (*directory.Trace
|
||||||
}
|
}
|
||||||
|
|
||||||
t := &muxTracer{names: names, tracers: objects}
|
t := &muxTracer{names: names, tracers: objects}
|
||||||
return &directory.Tracer{
|
return &tracers.Tracer{
|
||||||
Hooks: &tracing.Hooks{
|
Hooks: &tracing.Hooks{
|
||||||
OnTxStart: t.OnTxStart,
|
OnTxStart: t.OnTxStart,
|
||||||
OnTxEnd: t.OnTxEnd,
|
OnTxEnd: t.OnTxEnd,
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
package directory
|
package native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
@ -23,20 +23,21 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/tracing"
|
"github.com/ethereum/go-ethereum/core/tracing"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/eth/tracers"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
DefaultDirectory.Register("noopTracer", newNoopTracer, false)
|
tracers.DefaultDirectory.Register("noopTracer", newNoopTracer, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NoopTracer is a go implementation of the Tracer interface which
|
// noopTracer is a go implementation of the Tracer interface which
|
||||||
// performs no action. It's mostly useful for testing purposes.
|
// performs no action. It's mostly useful for testing purposes.
|
||||||
type NoopTracer struct{}
|
type noopTracer struct{}
|
||||||
|
|
||||||
// newNoopTracer returns a new noop tracer.
|
// newNoopTracer returns a new noop tracer.
|
||||||
func newNoopTracer(ctx *Context, _ json.RawMessage) (*Tracer, error) {
|
func newNoopTracer(ctx *tracers.Context, _ json.RawMessage) (*tracers.Tracer, error) {
|
||||||
t := &NoopTracer{}
|
t := &noopTracer{}
|
||||||
return &Tracer{
|
return &tracers.Tracer{
|
||||||
Hooks: &tracing.Hooks{
|
Hooks: &tracing.Hooks{
|
||||||
OnTxStart: t.OnTxStart,
|
OnTxStart: t.OnTxStart,
|
||||||
OnTxEnd: t.OnTxEnd,
|
OnTxEnd: t.OnTxEnd,
|
||||||
|
|
@ -56,42 +57,42 @@ func newNoopTracer(ctx *Context, _ json.RawMessage) (*Tracer, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *NoopTracer) OnOpcode(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error) {
|
func (t *noopTracer) OnOpcode(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *NoopTracer) OnFault(pc uint64, op byte, gas, cost uint64, _ tracing.OpContext, depth int, err error) {
|
func (t *noopTracer) OnFault(pc uint64, op byte, gas, cost uint64, _ tracing.OpContext, depth int, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *NoopTracer) OnGasChange(old, new uint64, reason tracing.GasChangeReason) {}
|
func (t *noopTracer) OnGasChange(old, new uint64, reason tracing.GasChangeReason) {}
|
||||||
|
|
||||||
func (t *NoopTracer) OnEnter(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
|
func (t *noopTracer) OnEnter(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *NoopTracer) OnExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) {
|
func (t *noopTracer) OnExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*NoopTracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction, from common.Address) {
|
func (*noopTracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction, from common.Address) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*NoopTracer) OnTxEnd(receipt *types.Receipt, err error) {}
|
func (*noopTracer) OnTxEnd(receipt *types.Receipt, err error) {}
|
||||||
|
|
||||||
func (*NoopTracer) OnBalanceChange(a common.Address, prev, new *big.Int, reason tracing.BalanceChangeReason) {
|
func (*noopTracer) OnBalanceChange(a common.Address, prev, new *big.Int, reason tracing.BalanceChangeReason) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*NoopTracer) OnNonceChange(a common.Address, prev, new uint64) {}
|
func (*noopTracer) OnNonceChange(a common.Address, prev, new uint64) {}
|
||||||
|
|
||||||
func (*NoopTracer) OnCodeChange(a common.Address, prevCodeHash common.Hash, prev []byte, codeHash common.Hash, code []byte) {
|
func (*noopTracer) OnCodeChange(a common.Address, prevCodeHash common.Hash, prev []byte, codeHash common.Hash, code []byte) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*NoopTracer) OnStorageChange(a common.Address, k, prev, new common.Hash) {}
|
func (*noopTracer) OnStorageChange(a common.Address, k, prev, new common.Hash) {}
|
||||||
|
|
||||||
func (*NoopTracer) OnLog(log *types.Log) {}
|
func (*noopTracer) OnLog(log *types.Log) {}
|
||||||
|
|
||||||
// GetResult returns an empty json object.
|
// GetResult returns an empty json object.
|
||||||
func (t *NoopTracer) GetResult() (json.RawMessage, error) {
|
func (t *noopTracer) GetResult() (json.RawMessage, error) {
|
||||||
return json.RawMessage(`{}`), nil
|
return json.RawMessage(`{}`), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop terminates execution of the tracer at the first opportune moment.
|
// Stop terminates execution of the tracer at the first opportune moment.
|
||||||
func (t *NoopTracer) Stop(err error) {
|
func (t *noopTracer) Stop(err error) {
|
||||||
}
|
}
|
||||||
|
|
@ -28,14 +28,15 @@ import (
|
||||||
"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/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/eth/tracers/directory"
|
"github.com/ethereum/go-ethereum/eth/tracers"
|
||||||
|
"github.com/ethereum/go-ethereum/eth/tracers/internal"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate go run github.com/fjl/gencodec -type account -field-override accountMarshaling -out gen_account_json.go
|
//go:generate go run github.com/fjl/gencodec -type account -field-override accountMarshaling -out gen_account_json.go
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
directory.DefaultDirectory.Register("prestateTracer", newPrestateTracer, false)
|
tracers.DefaultDirectory.Register("prestateTracer", newPrestateTracer, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
type stateMap = map[common.Address]*account
|
type stateMap = map[common.Address]*account
|
||||||
|
|
@ -73,7 +74,7 @@ type prestateTracerConfig struct {
|
||||||
DiffMode bool `json:"diffMode"` // If true, this tracer will return state modifications
|
DiffMode bool `json:"diffMode"` // If true, this tracer will return state modifications
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPrestateTracer(ctx *directory.Context, cfg json.RawMessage) (*directory.Tracer, error) {
|
func newPrestateTracer(ctx *tracers.Context, cfg json.RawMessage) (*tracers.Tracer, error) {
|
||||||
var config prestateTracerConfig
|
var config prestateTracerConfig
|
||||||
if cfg != nil {
|
if cfg != nil {
|
||||||
if err := json.Unmarshal(cfg, &config); err != nil {
|
if err := json.Unmarshal(cfg, &config); err != nil {
|
||||||
|
|
@ -87,7 +88,7 @@ func newPrestateTracer(ctx *directory.Context, cfg json.RawMessage) (*directory.
|
||||||
created: make(map[common.Address]bool),
|
created: make(map[common.Address]bool),
|
||||||
deleted: make(map[common.Address]bool),
|
deleted: make(map[common.Address]bool),
|
||||||
}
|
}
|
||||||
return &directory.Tracer{
|
return &tracers.Tracer{
|
||||||
Hooks: &tracing.Hooks{
|
Hooks: &tracing.Hooks{
|
||||||
OnTxStart: t.OnTxStart,
|
OnTxStart: t.OnTxStart,
|
||||||
OnTxEnd: t.OnTxEnd,
|
OnTxEnd: t.OnTxEnd,
|
||||||
|
|
@ -132,7 +133,7 @@ func (t *prestateTracer) OnOpcode(pc uint64, opcode byte, gas, cost uint64, scop
|
||||||
case stackLen >= 4 && op == vm.CREATE2:
|
case stackLen >= 4 && op == vm.CREATE2:
|
||||||
offset := stackData[stackLen-2]
|
offset := stackData[stackLen-2]
|
||||||
size := stackData[stackLen-3]
|
size := stackData[stackLen-3]
|
||||||
init, err := directory.GetMemoryCopyPadded(scope.MemoryData(), int64(offset.Uint64()), int64(size.Uint64()))
|
init, err := internal.GetMemoryCopyPadded(scope.MemoryData(), int64(offset.Uint64()), int64(size.Uint64()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("failed to copy CREATE2 input", "err", err, "tracer", "prestateTracer", "offset", offset, "size", size)
|
log.Warn("failed to copy CREATE2 input", "err", err, "tracer", "prestateTracer", "offset", offset, "size", size)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -454,7 +454,7 @@ func (s *PersonalAccountAPI) signTransaction(ctx context.Context, args *Transact
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Assemble the transaction and sign with the wallet
|
// Assemble the transaction and sign with the wallet
|
||||||
tx := args.toTransaction()
|
tx := args.ToTransaction()
|
||||||
|
|
||||||
return wallet.SignTxWithPassphrase(account, passwd, tx, s.b.ChainConfig().ChainID)
|
return wallet.SignTxWithPassphrase(account, passwd, tx, s.b.ChainConfig().ChainID)
|
||||||
}
|
}
|
||||||
|
|
@ -497,7 +497,7 @@ func (s *PersonalAccountAPI) SignTransaction(ctx context.Context, args Transacti
|
||||||
return nil, errors.New("nonce not specified")
|
return nil, errors.New("nonce not specified")
|
||||||
}
|
}
|
||||||
// Before actually signing the transaction, ensure the transaction fee is reasonable.
|
// Before actually signing the transaction, ensure the transaction fee is reasonable.
|
||||||
tx := args.toTransaction()
|
tx := args.ToTransaction()
|
||||||
if err := checkTxFee(tx.GasPrice(), tx.Gas(), s.b.RPCTxFeeCap()); err != nil {
|
if err := checkTxFee(tx.GasPrice(), tx.Gas(), s.b.RPCTxFeeCap()); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -1081,14 +1081,14 @@ func doCall(ctx context.Context, b Backend, args TransactionArgs, state vm.State
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
// Get a new instance of the EVM.
|
// Get a new instance of the EVM.
|
||||||
msg, err := args.ToMessage(globalGasCap, header.BaseFee)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil)
|
blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil)
|
||||||
if blockOverrides != nil {
|
if blockOverrides != nil {
|
||||||
blockOverrides.Apply(&blockCtx)
|
blockOverrides.Apply(&blockCtx)
|
||||||
}
|
}
|
||||||
|
if err := args.CallDefaults(globalGasCap, blockCtx.BaseFee, b.ChainConfig().ChainID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
msg := args.ToMessage(blockCtx.BaseFee)
|
||||||
evm := b.GetEVM(ctx, msg, state, header, &vm.Config{NoBaseFee: true}, &blockCtx)
|
evm := b.GetEVM(ctx, msg, state, header, &vm.Config{NoBaseFee: true}, &blockCtx)
|
||||||
|
|
||||||
// Wait for the context to be done and cancel the evm. Even if the
|
// Wait for the context to be done and cancel the evm. Even if the
|
||||||
|
|
@ -1200,11 +1200,15 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr
|
||||||
State: state,
|
State: state,
|
||||||
ErrorRatio: estimateGasErrorRatio,
|
ErrorRatio: estimateGasErrorRatio,
|
||||||
}
|
}
|
||||||
// Run the gas estimation andwrap any revertals into a custom return
|
|
||||||
call, err := args.ToMessage(gasCap, header.BaseFee)
|
if err := args.CallDefaults(gasCap, header.BaseFee, b.ChainConfig().ChainID); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
call := args.ToMessage(header.BaseFee)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
// Run the gas estimation andwrap any revertals into a custom return
|
||||||
estimate, revert, err := gasestimator.Estimate(ctx, call, opts, gasCap)
|
estimate, revert, err := gasestimator.Estimate(ctx, call, opts, gasCap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if len(revert) > 0 {
|
if len(revert) > 0 {
|
||||||
|
|
@ -1537,7 +1541,7 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH
|
||||||
statedb := db.Copy().(vm.StateDB)
|
statedb := db.Copy().(vm.StateDB)
|
||||||
// Set the accesslist to the last al
|
// Set the accesslist to the last al
|
||||||
args.AccessList = &accessList
|
args.AccessList = &accessList
|
||||||
msg, err := args.ToMessage(b.RPCGasCap(), header.BaseFee)
|
msg := args.ToMessage(header.BaseFee)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, nil, err
|
return nil, 0, nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -1548,7 +1552,7 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH
|
||||||
vmenv := b.GetEVM(ctx, msg, statedb, header, &config, nil)
|
vmenv := b.GetEVM(ctx, msg, statedb, header, &config, nil)
|
||||||
res, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit))
|
res, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, nil, fmt.Errorf("failed to apply transaction: %v err: %v", args.toTransaction().Hash(), err)
|
return nil, 0, nil, fmt.Errorf("failed to apply transaction: %v err: %v", args.ToTransaction().Hash(), err)
|
||||||
}
|
}
|
||||||
if tracer.Equal(prevTracer) {
|
if tracer.Equal(prevTracer) {
|
||||||
return accessList, res.UsedGas, res.Err, nil
|
return accessList, res.UsedGas, res.Err, nil
|
||||||
|
|
@ -1816,7 +1820,7 @@ func (s *TransactionAPI) SendTransaction(ctx context.Context, args TransactionAr
|
||||||
return common.Hash{}, err
|
return common.Hash{}, err
|
||||||
}
|
}
|
||||||
// Assemble the transaction and sign with the wallet
|
// Assemble the transaction and sign with the wallet
|
||||||
tx := args.toTransaction()
|
tx := args.ToTransaction()
|
||||||
|
|
||||||
signed, err := wallet.SignTx(account, tx, s.b.ChainConfig().ChainID)
|
signed, err := wallet.SignTx(account, tx, s.b.ChainConfig().ChainID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -1834,7 +1838,7 @@ func (s *TransactionAPI) FillTransaction(ctx context.Context, args TransactionAr
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Assemble the transaction and obtain rlp
|
// Assemble the transaction and obtain rlp
|
||||||
tx := args.toTransaction()
|
tx := args.ToTransaction()
|
||||||
data, err := tx.MarshalBinary()
|
data, err := tx.MarshalBinary()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -1900,7 +1904,7 @@ func (s *TransactionAPI) SignTransaction(ctx context.Context, args TransactionAr
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Before actually sign the transaction, ensure the transaction fee is reasonable.
|
// Before actually sign the transaction, ensure the transaction fee is reasonable.
|
||||||
tx := args.toTransaction()
|
tx := args.ToTransaction()
|
||||||
if err := checkTxFee(tx.GasPrice(), tx.Gas(), s.b.RPCTxFeeCap()); err != nil {
|
if err := checkTxFee(tx.GasPrice(), tx.Gas(), s.b.RPCTxFeeCap()); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -1948,7 +1952,7 @@ func (s *TransactionAPI) Resend(ctx context.Context, sendArgs TransactionArgs, g
|
||||||
if err := sendArgs.SetDefaults(ctx, s.b); err != nil {
|
if err := sendArgs.SetDefaults(ctx, s.b); err != nil {
|
||||||
return common.Hash{}, err
|
return common.Hash{}, err
|
||||||
}
|
}
|
||||||
matchTx := sendArgs.toTransaction()
|
matchTx := sendArgs.ToTransaction()
|
||||||
|
|
||||||
// Before replacing the old transaction, ensure the _new_ transaction fee is reasonable.
|
// Before replacing the old transaction, ensure the _new_ transaction fee is reasonable.
|
||||||
var price = matchTx.GasPrice()
|
var price = matchTx.GasPrice()
|
||||||
|
|
@ -1978,7 +1982,7 @@ func (s *TransactionAPI) Resend(ctx context.Context, sendArgs TransactionArgs, g
|
||||||
if gasLimit != nil && *gasLimit != 0 {
|
if gasLimit != nil && *gasLimit != 0 {
|
||||||
sendArgs.Gas = gasLimit
|
sendArgs.Gas = gasLimit
|
||||||
}
|
}
|
||||||
signedTx, err := s.sign(sendArgs.from(), sendArgs.toTransaction())
|
signedTx, err := s.sign(sendArgs.from(), sendArgs.ToTransaction())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Hash{}, err
|
return common.Hash{}, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -197,40 +197,68 @@ func (args *TransactionArgs) setLondonFeeDefaults(ctx context.Context, head *typ
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CallDefaults sanitizes the transaction arguments, often filling in zero values,
|
||||||
|
// for the purpose of eth_call class of RPC methods.
|
||||||
|
func (args *TransactionArgs) CallDefaults(globalGasCap uint64, baseFee *big.Int, chainID *big.Int) error {
|
||||||
|
// Reject invalid combinations of pre- and post-1559 fee styles
|
||||||
|
if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) {
|
||||||
|
return errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
|
||||||
|
}
|
||||||
|
if args.ChainID == nil {
|
||||||
|
args.ChainID = (*hexutil.Big)(chainID)
|
||||||
|
} else {
|
||||||
|
if have := (*big.Int)(args.ChainID); have.Cmp(chainID) != 0 {
|
||||||
|
return fmt.Errorf("chainId does not match node's (have=%v, want=%v)", have, chainID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if args.Gas == nil {
|
||||||
|
gas := globalGasCap
|
||||||
|
if gas == 0 {
|
||||||
|
gas = uint64(math.MaxUint64 / 2)
|
||||||
|
}
|
||||||
|
args.Gas = (*hexutil.Uint64)(&gas)
|
||||||
|
} else {
|
||||||
|
if globalGasCap > 0 && globalGasCap < uint64(*args.Gas) {
|
||||||
|
log.Warn("Caller gas above allowance, capping", "requested", args.Gas, "cap", globalGasCap)
|
||||||
|
args.Gas = (*hexutil.Uint64)(&globalGasCap)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if args.Nonce == nil {
|
||||||
|
args.Nonce = new(hexutil.Uint64)
|
||||||
|
}
|
||||||
|
if args.Value == nil {
|
||||||
|
args.Value = new(hexutil.Big)
|
||||||
|
}
|
||||||
|
if baseFee == nil {
|
||||||
|
// If there's no basefee, then it must be a non-1559 execution
|
||||||
|
if args.GasPrice == nil {
|
||||||
|
args.GasPrice = new(hexutil.Big)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// A basefee is provided, necessitating 1559-type execution
|
||||||
|
if args.MaxFeePerGas == nil {
|
||||||
|
args.MaxFeePerGas = new(hexutil.Big)
|
||||||
|
}
|
||||||
|
if args.MaxPriorityFeePerGas == nil {
|
||||||
|
args.MaxPriorityFeePerGas = new(hexutil.Big)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// ToMessage converts the transaction arguments to the Message type used by the
|
// ToMessage converts the transaction arguments to the Message type used by the
|
||||||
// core evm. This method is used in calls and traces that do not require a real
|
// core evm. This method is used in calls and traces that do not require a real
|
||||||
// live transaction.
|
// live transaction.
|
||||||
func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (*core.Message, error) {
|
// Assumes that fields are not nil, i.e. setDefaults or CallDefaults has been called.
|
||||||
// Reject invalid combinations of pre- and post-1559 fee styles
|
func (args *TransactionArgs) ToMessage(baseFee *big.Int) *core.Message {
|
||||||
if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) {
|
|
||||||
return nil, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
|
|
||||||
}
|
|
||||||
// Set sender address or use zero address if none specified.
|
|
||||||
addr := args.from()
|
|
||||||
|
|
||||||
// Set default gas & gas price if none were set
|
|
||||||
gas := globalGasCap
|
|
||||||
if gas == 0 {
|
|
||||||
gas = uint64(math.MaxUint64 / 2)
|
|
||||||
}
|
|
||||||
if args.Gas != nil {
|
|
||||||
gas = uint64(*args.Gas)
|
|
||||||
}
|
|
||||||
if globalGasCap != 0 && globalGasCap < gas {
|
|
||||||
log.Warn("Caller gas above allowance, capping", "requested", gas, "cap", globalGasCap)
|
|
||||||
gas = globalGasCap
|
|
||||||
}
|
|
||||||
var (
|
var (
|
||||||
gasPrice *big.Int
|
gasPrice *big.Int
|
||||||
gasFeeCap *big.Int
|
gasFeeCap *big.Int
|
||||||
gasTipCap *big.Int
|
gasTipCap *big.Int
|
||||||
)
|
)
|
||||||
if baseFee == nil {
|
if baseFee == nil {
|
||||||
// If there's no basefee, then it must be a non-1559 execution
|
gasPrice = args.GasPrice.ToInt()
|
||||||
gasPrice = new(big.Int)
|
|
||||||
if args.GasPrice != nil {
|
|
||||||
gasPrice = args.GasPrice.ToInt()
|
|
||||||
}
|
|
||||||
gasFeeCap, gasTipCap = gasPrice, gasPrice
|
gasFeeCap, gasTipCap = gasPrice, gasPrice
|
||||||
} else {
|
} else {
|
||||||
// A basefee is provided, necessitating 1559-type execution
|
// A basefee is provided, necessitating 1559-type execution
|
||||||
|
|
@ -240,14 +268,8 @@ func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (*
|
||||||
gasFeeCap, gasTipCap = gasPrice, gasPrice
|
gasFeeCap, gasTipCap = gasPrice, gasPrice
|
||||||
} else {
|
} else {
|
||||||
// User specified 1559 gas fields (or none), use those
|
// User specified 1559 gas fields (or none), use those
|
||||||
gasFeeCap = new(big.Int)
|
gasFeeCap = args.MaxFeePerGas.ToInt()
|
||||||
if args.MaxFeePerGas != nil {
|
gasTipCap = args.MaxPriorityFeePerGas.ToInt()
|
||||||
gasFeeCap = args.MaxFeePerGas.ToInt()
|
|
||||||
}
|
|
||||||
gasTipCap = new(big.Int)
|
|
||||||
if args.MaxPriorityFeePerGas != nil {
|
|
||||||
gasTipCap = args.MaxPriorityFeePerGas.ToInt()
|
|
||||||
}
|
|
||||||
// Backfill the legacy gasPrice for EVM execution, unless we're all zeroes
|
// Backfill the legacy gasPrice for EVM execution, unless we're all zeroes
|
||||||
gasPrice = new(big.Int)
|
gasPrice = new(big.Int)
|
||||||
if gasFeeCap.BitLen() > 0 || gasTipCap.BitLen() > 0 {
|
if gasFeeCap.BitLen() > 0 || gasTipCap.BitLen() > 0 {
|
||||||
|
|
@ -255,33 +277,27 @@ func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
value := new(big.Int)
|
|
||||||
if args.Value != nil {
|
|
||||||
value = args.Value.ToInt()
|
|
||||||
}
|
|
||||||
data := args.data()
|
|
||||||
var accessList types.AccessList
|
var accessList types.AccessList
|
||||||
if args.AccessList != nil {
|
if args.AccessList != nil {
|
||||||
accessList = *args.AccessList
|
accessList = *args.AccessList
|
||||||
}
|
}
|
||||||
msg := &core.Message{
|
return &core.Message{
|
||||||
From: addr,
|
From: args.from(),
|
||||||
To: args.To,
|
To: args.To,
|
||||||
Value: value,
|
Value: (*big.Int)(args.Value),
|
||||||
GasLimit: gas,
|
GasLimit: uint64(*args.Gas),
|
||||||
GasPrice: gasPrice,
|
GasPrice: gasPrice,
|
||||||
GasFeeCap: gasFeeCap,
|
GasFeeCap: gasFeeCap,
|
||||||
GasTipCap: gasTipCap,
|
GasTipCap: gasTipCap,
|
||||||
Data: data,
|
Data: args.data(),
|
||||||
AccessList: accessList,
|
AccessList: accessList,
|
||||||
SkipAccountChecks: true,
|
SkipAccountChecks: true,
|
||||||
}
|
}
|
||||||
return msg, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// toTransaction converts the arguments to a transaction.
|
// ToTransaction converts the arguments to a transaction.
|
||||||
// This assumes that SetDefaults has been called.
|
// This assumes that setDefaults has been called.
|
||||||
func (args *TransactionArgs) toTransaction() *types.Transaction {
|
func (args *TransactionArgs) ToTransaction() *types.Transaction {
|
||||||
var data types.TxData
|
var data types.TxData
|
||||||
switch {
|
switch {
|
||||||
case args.MaxFeePerGas != nil:
|
case args.MaxFeePerGas != nil:
|
||||||
|
|
@ -323,9 +339,3 @@ func (args *TransactionArgs) toTransaction() *types.Transaction {
|
||||||
}
|
}
|
||||||
return types.NewTx(data)
|
return types.NewTx(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToTransaction converts the arguments to a transaction.
|
|
||||||
// This assumes that SetDefaults has been called.
|
|
||||||
func (args *TransactionArgs) ToTransaction() *types.Transaction {
|
|
||||||
return args.toTransaction()
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue