Skip to content

Commit

Permalink
feat: struct based live chain logging
Browse files Browse the repository at this point in the history
  • Loading branch information
dhyaniarun1993 committed Mar 25, 2024
1 parent 07ee59c commit fe95fa9
Show file tree
Hide file tree
Showing 90 changed files with 1,567 additions and 1,737 deletions.
4 changes: 2 additions & 2 deletions accounts/abi/bind/backends/simulated.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ import (
"github.com/ledgerwatch/erigon/core"
"github.com/ledgerwatch/erigon/core/rawdb"
"github.com/ledgerwatch/erigon/core/state"
"github.com/ledgerwatch/erigon/core/tracing"
"github.com/ledgerwatch/erigon/core/types"
"github.com/ledgerwatch/erigon/core/vm"
"github.com/ledgerwatch/erigon/core/vm/evmtypes"
"github.com/ledgerwatch/erigon/event"
"github.com/ledgerwatch/erigon/params"
"github.com/ledgerwatch/erigon/turbo/services"
Expand Down Expand Up @@ -715,7 +715,7 @@ func (b *SimulatedBackend) callContract(_ context.Context, call ethereum.CallMsg
}
// Set infinite balance to the fake caller account.
from := statedb.GetOrNewStateObject(call.From)
from.SetBalance(uint256.NewInt(0).SetAllOne(), evmtypes.BalanceChangeUnspecified)
from.SetBalance(uint256.NewInt(0).SetAllOne(), tracing.BalanceChangeUnspecified)
// Execute the call.
msg := callMsg{call}

Expand Down
2 changes: 1 addition & 1 deletion cmd/devnet/devnet/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ func (n *devnetNode) EnableMetrics(int) {
// run configures, creates and serves an erigon node
func (n *devnetNode) run(ctx *cli.Context) error {
var logger log.Logger
var tracer tracers.Tracer
var tracer *tracers.Tracer
var err error
var metricsMux *http.ServeMux

Expand Down
2 changes: 1 addition & 1 deletion cmd/erigon/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func main() {

func runErigon(cliCtx *cli.Context) error {
var logger log.Logger
var tracer tracers.Tracer
var tracer *tracers.Tracer
var err error
var metricsMux *http.ServeMux

Expand Down
4 changes: 2 additions & 2 deletions cmd/evm/internal/t8ntool/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ import (
"github.com/ledgerwatch/erigon/common/math"
"github.com/ledgerwatch/erigon/consensus/ethash"
"github.com/ledgerwatch/erigon/core/state"
"github.com/ledgerwatch/erigon/core/tracing"
"github.com/ledgerwatch/erigon/core/types"
"github.com/ledgerwatch/erigon/core/vm/evmtypes"
"github.com/ledgerwatch/erigon/turbo/rpchelper"
)

Expand Down Expand Up @@ -84,7 +84,7 @@ func MakePreState(chainRules *chain.Rules, tx kv.RwTx, accounts types.GenesisAll
statedb.SetCode(addr, a.Code)
statedb.SetNonce(addr, a.Nonce)
balance, _ := uint256.FromBig(a.Balance)
statedb.SetBalance(addr, balance, evmtypes.BalanceIncreaseGenesisBalance)
statedb.SetBalance(addr, balance, tracing.BalanceIncreaseGenesisBalance)
for k, v := range a.Storage {
key := k
val := uint256.NewInt(0).SetBytes(v.Bytes())
Expand Down
9 changes: 5 additions & 4 deletions cmd/evm/internal/t8ntool/transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/holiman/uint256"
"github.com/ledgerwatch/erigon-lib/common/datadir"
"github.com/ledgerwatch/erigon/core/state/temporal"
"github.com/ledgerwatch/erigon/core/tracing"
"github.com/ledgerwatch/log/v3"
"github.com/urfave/cli/v2"

Expand Down Expand Up @@ -100,7 +101,7 @@ func Main(ctx *cli.Context) error {
err error
baseDir = ""
)
var getTracer func(txIndex int, txHash libcommon.Hash) (vm.EVMLogger, error)
var getTracer func(txIndex int, txHash libcommon.Hash) (*tracing.Hooks, error)

// If user specified a basedir, make sure it exists
if ctx.IsSet(OutputBasedir.Name) {
Expand All @@ -127,7 +128,7 @@ func Main(ctx *cli.Context) error {
prevFile.Close()
}
}()
getTracer = func(txIndex int, txHash libcommon.Hash) (vm.EVMLogger, error) {
getTracer = func(txIndex int, txHash libcommon.Hash) (*tracing.Hooks, error) {
if prevFile != nil {
prevFile.Close()
}
Expand All @@ -136,10 +137,10 @@ func Main(ctx *cli.Context) error {
return nil, NewError(ErrorIO, fmt.Errorf("failed creating trace-file: %v", err2))
}
prevFile = traceFile
return trace_logger.NewJSONLogger(logConfig, traceFile), nil
return trace_logger.NewJSONLogger(logConfig, traceFile).Hooks, nil
}
} else {
getTracer = func(txIndex int, txHash libcommon.Hash) (tracer vm.EVMLogger, err error) {
getTracer = func(txIndex int, txHash libcommon.Hash) (tracer *tracing.Hooks, err error) {
return nil, nil
}
}
Expand Down
6 changes: 3 additions & 3 deletions cmd/evm/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ func runCmd(ctx *cli.Context) error {
}

var (
tracer tracers.Tracer
tracer *tracers.Tracer
debugLogger *logger.StructLogger
statedb *state.IntraBlockState
chainConfig *chain.Config
Expand All @@ -147,7 +147,7 @@ func runCmd(ctx *cli.Context) error {
tracer = logger.NewJSONLogger(logconfig, os.Stdout)
} else if ctx.Bool(DebugFlag.Name) {
debugLogger = logger.NewStructLogger(logconfig)
tracer = debugLogger
tracer = debugLogger.Tracer()
} else {
debugLogger = logger.NewStructLogger(logconfig)
}
Expand Down Expand Up @@ -238,7 +238,7 @@ func runCmd(ctx *cli.Context) error {
Coinbase: genesisConfig.Coinbase,
BlockNumber: new(big.Int).SetUint64(genesisConfig.Number),
EVMConfig: vm.Config{
Tracer: tracer,
Tracer: tracer.Hooks,
Debug: ctx.Bool(DebugFlag.Name) || ctx.Bool(MachineFlag.Name),
},
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/evm/staterunner.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ func stateTestCmd(ctx *cli.Context) error {
Debug: ctx.Bool(DebugFlag.Name) || ctx.Bool(MachineFlag.Name),
}
if machineFriendlyOutput {
cfg.Tracer = logger.NewJSONLogger(config, os.Stderr)
cfg.Tracer = logger.NewJSONLogger(config, os.Stderr).Hooks
} else if ctx.Bool(DebugFlag.Name) {
cfg.Tracer = logger.NewStructLogger(config)
cfg.Tracer = logger.NewStructLogger(config).Hooks()
}

if len(ctx.Args().First()) != 0 {
Expand Down
6 changes: 4 additions & 2 deletions cmd/integration/commands/state_stages.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,10 @@ func syncBySmallSteps(db kv.RwDB, miningConfig params.MiningConfig, ctx context.
stopAt = 1
}

var structLogger *logger.StructLogger
traceStart := func() {
vmConfig.Tracer = logger.NewStructLogger(&logger.LogConfig{})
structLogger = logger.NewStructLogger(&logger.LogConfig{})
vmConfig.Tracer = structLogger.Hooks()
vmConfig.Debug = true
}
traceStop := func(id int) {
Expand All @@ -262,7 +264,7 @@ func syncBySmallSteps(db kv.RwDB, miningConfig params.MiningConfig, ctx context.
}
encoder := json.NewEncoder(w)
encoder.SetIndent(" ", " ")
for _, l := range logger.FormatLogs(vmConfig.Tracer.(*logger.StructLogger).StructLogs()) {
for _, l := range logger.FormatLogs(structLogger.StructLogs()) {
if err2 := encoder.Encode(l); err2 != nil {
panic(err2)
}
Expand Down
99 changes: 34 additions & 65 deletions cmd/state/commands/opcode_tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"encoding/gob"
"encoding/json"
"fmt"
"math/big"
"os"
"os/signal"
"strconv"
Expand All @@ -29,10 +28,11 @@ import (
"github.com/ledgerwatch/erigon/core"
"github.com/ledgerwatch/erigon/core/rawdb"
"github.com/ledgerwatch/erigon/core/state"
"github.com/ledgerwatch/erigon/core/tracing"
"github.com/ledgerwatch/erigon/core/types"
"github.com/ledgerwatch/erigon/core/vm"
"github.com/ledgerwatch/erigon/core/vm/evmtypes"
"github.com/ledgerwatch/erigon/eth/ethconfig"
"github.com/ledgerwatch/erigon/eth/tracers"
"github.com/ledgerwatch/erigon/turbo/rpchelper"
"github.com/ledgerwatch/erigon/turbo/snapshotsync/freezeblocks"
)
Expand Down Expand Up @@ -115,7 +115,7 @@ type opcodeTracer struct {
saveBblocks bool
blockNumber uint64
depth int
env *vm.EVM
env *tracing.VMContext
}

func NewOpcodeTracer(blockNum uint64, saveOpcodes bool, saveBblocks bool) *opcodeTracer {
Expand Down Expand Up @@ -164,13 +164,23 @@ type blockTxs struct {
Txs slicePtrTx
}

func (ot *opcodeTracer) CaptureTxStart(env *vm.EVM, tx types.Transaction) {
func (ot *opcodeTracer) Tracer() *tracers.Tracer {
return &tracers.Tracer{
Hooks: &tracing.Hooks{
OnTxStart: ot.OnTxStart,
OnEnter: ot.OnEnter,
OnExit: ot.OnExit,
OnFault: ot.OnFault,
OnOpcode: ot.OnOpcode,
},
}
}

func (ot *opcodeTracer) OnTxStart(env *tracing.VMContext, tx types.Transaction, from libcommon.Address) {
ot.env = env
ot.depth = 0
}

func (ot *opcodeTracer) CaptureTxEnd(receipt *types.Receipt, err error) {}

func (ot *opcodeTracer) captureStartOrEnter(from, to libcommon.Address, create bool, input []byte) {
//fmt.Fprint(ot.summary, ot.lastLine)

Expand Down Expand Up @@ -199,14 +209,9 @@ func (ot *opcodeTracer) captureStartOrEnter(from, to libcommon.Address, create b
ot.stack = append(ot.stack, &newTx)
}

func (ot *opcodeTracer) CaptureStart(from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) {
ot.depth = 0
ot.captureStartOrEnter(from, to, create, input)
}

func (ot *opcodeTracer) CaptureEnter(typ vm.OpCode, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) {
ot.depth++
ot.captureStartOrEnter(from, to, create, input)
func (ot *opcodeTracer) OnEnter(depth int, typ byte, from libcommon.Address, to libcommon.Address, precompile bool, input []byte, gas uint64, value *uint256.Int, code []byte) {
ot.depth = depth
ot.captureStartOrEnter(from, to, vm.OpCode(typ) == vm.CREATE, input)
}

func (ot *opcodeTracer) captureEndOrExit(err error) {
Expand Down Expand Up @@ -241,18 +246,13 @@ func (ot *opcodeTracer) captureEndOrExit(err error) {
}
}

func (ot *opcodeTracer) CaptureEnd(output []byte, usedGas uint64, err error, reverted bool) {
func (ot *opcodeTracer) OnExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) {
ot.captureEndOrExit(err)
ot.depth = depth
}

func (ot *opcodeTracer) CaptureExit(output []byte, usedGas uint64, err error, reverted bool) {
ot.captureEndOrExit(err)
ot.depth--
}

func (ot *opcodeTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, opDepth int, err error) {
func (ot *opcodeTracer) OnOpcode(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, rData []byte, opDepth int, err error) {
//CaptureState sees the system as it is before the opcode is run. It seems to never get an error.
contract := scope.Contract

//sanity check
if pc > uint64(MaxUint16) {
Expand Down Expand Up @@ -284,8 +284,8 @@ func (ot *opcodeTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64,
currentEntry.TxHash = new(libcommon.Hash)
currentEntry.TxHash.SetBytes(currentTxHash.Bytes())
currentEntry.CodeHash = new(libcommon.Hash)
currentEntry.CodeHash.SetBytes(contract.CodeHash.Bytes())
currentEntry.CodeSize = len(contract.Code)
currentEntry.CodeHash.SetBytes(scope.CodeHash().Bytes())
currentEntry.CodeSize = len(scope.Code())
if ot.saveOpcodes {
currentEntry.Opcodes = make([]opcode, 0, 200)
}
Expand Down Expand Up @@ -313,7 +313,7 @@ func (ot *opcodeTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64,
//sanity check
if currentEntry.OpcodeFault != "" {
panic(fmt.Sprintf("Running opcodes but fault is already set. txFault=%s, opFault=%v, op=%s",
currentEntry.OpcodeFault, err, op.String()))
currentEntry.OpcodeFault, err, vm.OpCode(op).String()))
}

// if it is a Fault, check whether we already have a record of the opcode. If so, just add the flag to it
Expand All @@ -325,11 +325,11 @@ func (ot *opcodeTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64,

faultAndRepeated := false

if pc16 == currentEntry.lastPc16 && op == currentEntry.lastOp {
if pc16 == currentEntry.lastPc16 && vm.OpCode(op) == currentEntry.lastOp {
//it's a repeated opcode. We assume this only happens when it's a Fault.
if err == nil {
panic(fmt.Sprintf("Duplicate opcode with no fault. bn=%d txaddr=%s pc=%x op=%s",
ot.blockNumber, currentEntry.TxAddr, pc, op.String()))
ot.blockNumber, currentEntry.TxAddr, pc, vm.OpCode(op).String()))
}
faultAndRepeated = true
//ot.fsumWriter.WriteString("Fault for EXISTING opcode\n")
Expand All @@ -341,7 +341,7 @@ func (ot *opcodeTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64,
} else {
// it's a new opcode
if ot.saveOpcodes {
newOpcode := opcode{pc16, op, errstr}
newOpcode := opcode{pc16, vm.OpCode(op), errstr}
currentEntry.Opcodes = append(currentEntry.Opcodes, newOpcode)
}
}
Expand Down Expand Up @@ -372,56 +372,25 @@ func (ot *opcodeTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64,

//sanity check
// we're starting a bblock, so either we're in PC=0 or we have OP=JUMPDEST
if pc16 != 0 && op.String() != "JUMPDEST" {
if pc16 != 0 && vm.OpCode(op).String() != "JUMPDEST" {
panic(fmt.Sprintf("Bad bblock? lastpc=%x, lastOp=%s; pc=%x, op=%s; bn=%d txaddr=%s tx=%d-%s",
currentEntry.lastPc16, currentEntry.lastOp.String(), pc, op.String(), ot.blockNumber, currentEntry.TxAddr, currentEntry.Depth, currentEntry.TxHash.String()))
currentEntry.lastPc16, currentEntry.lastOp.String(), pc, vm.OpCode(op).String(), ot.blockNumber, currentEntry.TxAddr, currentEntry.Depth, currentEntry.TxHash.String()))
}
}
}
}

currentEntry.lastPc16 = pc16
currentEntry.lastOp = op
currentEntry.lastOp = vm.OpCode(op)
}

func (ot *opcodeTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, opDepth int, err error) {
func (ot *opcodeTracer) OnFault(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, opDepth int, err error) {
// CaptureFault sees the system as it is after the fault happens

// CaptureState might have already recorded the opcode before it failed. Let's centralize the processing there.
ot.CaptureState(pc, op, gas, cost, scope, nil, opDepth, err)

}

func (ot *opcodeTracer) OnBlockStart(b *types.Block, td *big.Int, finalized, safe *types.Header, chainConfig *chain2.Config) {
}

func (ot *opcodeTracer) OnBlockEnd(err error) {
ot.OnOpcode(pc, op, gas, cost, scope, nil, opDepth, err)
}

func (ot *opcodeTracer) OnGenesisBlock(b *types.Block, alloc types.GenesisAlloc) {
}

func (ot *opcodeTracer) OnBeaconBlockRootStart(root libcommon.Hash) {}

func (ot *opcodeTracer) OnBeaconBlockRootEnd() {}

func (ot *opcodeTracer) CaptureKeccakPreimage(hash libcommon.Hash, data []byte) {}

func (ot *opcodeTracer) OnGasChange(old, new uint64, reason vm.GasChangeReason) {}

func (ot *opcodeTracer) OnBalanceChange(a libcommon.Address, prev, new *uint256.Int, reason evmtypes.BalanceChangeReason) {
}

func (ot *opcodeTracer) OnNonceChange(a libcommon.Address, prev, new uint64) {}

func (ot *opcodeTracer) OnCodeChange(a libcommon.Address, prevCodeHash libcommon.Hash, prev []byte, codeHash libcommon.Hash, code []byte) {
}

func (ot *opcodeTracer) OnStorageChange(a libcommon.Address, k *libcommon.Hash, prev, new uint256.Int) {
}

func (ot *opcodeTracer) OnLog(log *types.Log) {}

// GetResult returns an empty json object.
func (ot *opcodeTracer) GetResult() (json.RawMessage, error) {
return json.RawMessage(`{}`), nil
Expand Down Expand Up @@ -474,7 +443,7 @@ func OpcodeTracer(genesis *types.Genesis, blockNum uint64, chaindata string, num
blockReader := freezeblocks.NewBlockReader(freezeblocks.NewRoSnapshots(ethconfig.BlocksFreezing{Enabled: false}, "", 0, log.New()), nil /* BorSnapshots */)

chainConfig := genesis.Config
vmConfig := vm.Config{Tracer: ot, Debug: true}
vmConfig := vm.Config{Tracer: ot.Tracer().Hooks, Debug: true}

noOpWriter := state.NewNoopWriter()

Expand Down
Loading

0 comments on commit fe95fa9

Please sign in to comment.