Skip to content

Commit 4dcc794

Browse files
authored
Merge 879d1ca into d68583f
2 parents d68583f + 879d1ca commit 4dcc794

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+2105
-1862
lines changed

cmd/evm/internal/t8ntool/execution.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ type rejectedTx struct {
9494
// Apply applies a set of transactions to a pre-state
9595
func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
9696
txs types.Transactions, miningReward int64,
97-
getTracerFn func(txIndex int, txHash common.Hash) (tracer vm.Tracer, err error)) (*state.StateDB, *ExecutionResult, error) {
97+
getTracerFn func(txIndex int, txHash common.Hash) (tracer vm.EVMLogger, err error)) (*state.StateDB, *ExecutionResult, error) {
9898

9999
// Capture errors for BLOCKHASH operation, if we haven't been supplied the
100100
// required blockhashes

cmd/evm/internal/t8ntool/transition.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,10 @@ func Transition(ctx *cli.Context) error {
9292

9393
var (
9494
err error
95-
tracer vm.Tracer
95+
tracer vm.EVMLogger
9696
baseDir = ""
9797
)
98-
var getTracer func(txIndex int, txHash common.Hash) (vm.Tracer, error)
98+
var getTracer func(txIndex int, txHash common.Hash) (vm.EVMLogger, error)
9999

100100
// If user specified a basedir, make sure it exists
101101
if ctx.IsSet(OutputBasedir.Name) {
@@ -122,7 +122,7 @@ func Transition(ctx *cli.Context) error {
122122
prevFile.Close()
123123
}
124124
}()
125-
getTracer = func(txIndex int, txHash common.Hash) (vm.Tracer, error) {
125+
getTracer = func(txIndex int, txHash common.Hash) (vm.EVMLogger, error) {
126126
if prevFile != nil {
127127
prevFile.Close()
128128
}
@@ -134,7 +134,7 @@ func Transition(ctx *cli.Context) error {
134134
return vm.NewJSONLogger(logConfig, traceFile), nil
135135
}
136136
} else {
137-
getTracer = func(txIndex int, txHash common.Hash) (tracer vm.Tracer, err error) {
137+
getTracer = func(txIndex int, txHash common.Hash) (tracer vm.EVMLogger, err error) {
138138
return nil, nil
139139
}
140140
}

cmd/evm/runner.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ func runCmd(ctx *cli.Context) error {
116116
}
117117

118118
var (
119-
tracer vm.Tracer
119+
tracer vm.EVMLogger
120120
debugLogger *vm.StructLogger
121121
statedb *state.StateDB
122122
chainConfig *params.ChainConfig

cmd/evm/staterunner.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func stateTestCmd(ctx *cli.Context) error {
6565
EnableReturnData: !ctx.GlobalBool(DisableReturnDataFlag.Name),
6666
}
6767
var (
68-
tracer vm.Tracer
68+
tracer vm.EVMLogger
6969
debugger *vm.StructLogger
7070
)
7171
switch {

cmd/geth/main.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ import (
4141
"github.com/celo-org/celo-blockchain/log"
4242
"github.com/celo-org/celo-blockchain/metrics"
4343
"github.com/celo-org/celo-blockchain/node"
44+
45+
// Force-load the tracer engines to trigger registration
46+
_ "github.com/celo-org/celo-blockchain/eth/tracers/js"
47+
_ "github.com/celo-org/celo-blockchain/eth/tracers/native"
48+
4449
"gopkg.in/urfave/cli.v1"
4550
)
4651

core/vm/access_list_tracer.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ func (a *AccessListTracer) CaptureStart(env *EVM, from common.Address, to common
141141
}
142142

143143
// CaptureState captures all opcodes that touch storage or addresses and adds them to the accesslist.
144-
func (a *AccessListTracer) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error) {
144+
func (a *AccessListTracer) CaptureState(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error) {
145145
stack := scope.Stack
146146
if (op == SLOAD || op == SSTORE) && stack.len() >= 1 {
147147
slot := common.Hash(stack.data[stack.len()-1].Bytes32())
@@ -161,7 +161,7 @@ func (a *AccessListTracer) CaptureState(env *EVM, pc uint64, op OpCode, gas, cos
161161
}
162162
}
163163

164-
func (*AccessListTracer) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, depth int, err error) {
164+
func (*AccessListTracer) CaptureFault(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, depth int, err error) {
165165
}
166166

167167
func (*AccessListTracer) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) {}

core/vm/evm.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -207,9 +207,14 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
207207
if !evm.StateDB.Exist(addr) {
208208
if !isPrecompile && evm.chainRules.IsEIP158 && value.Sign() == 0 {
209209
// Calling a non existing account, don't do anything, but ping the tracer
210-
if evm.Config.Debug && evm.depth == 0 {
211-
evm.Config.Tracer.CaptureStart(evm, caller.Address(), addr, false, input, gas, value)
212-
evm.Config.Tracer.CaptureEnd(ret, 0, 0, nil)
210+
if evm.Config.Debug {
211+
if evm.depth == 0 {
212+
evm.Config.Tracer.CaptureStart(evm, caller.Address(), addr, false, input, gas, value)
213+
evm.Config.Tracer.CaptureEnd(ret, 0, 0, nil)
214+
} else {
215+
evm.Config.Tracer.CaptureEnter(CALL, caller.Address(), addr, input, gas, value)
216+
evm.Config.Tracer.CaptureExit(ret, 0, nil)
217+
}
213218
}
214219
return nil, gas, nil
215220
}

core/vm/interpreter.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ import (
2727

2828
// Config are the configuration options for the Interpreter
2929
type Config struct {
30-
Debug bool // Enables debugging
31-
Tracer Tracer // Opcode logger
32-
NoRecursion bool // Disables call, callcode, delegate call and create
33-
NoBaseFee bool // Forces the EIP-1559 baseFee to 0 (needed for 0 price calls)
34-
EnablePreimageRecording bool // Enables recording of SHA3/keccak preimages
30+
Debug bool // Enables debugging
31+
Tracer EVMLogger // Opcode logger
32+
NoRecursion bool // Disables call, callcode, delegate call and create
33+
NoBaseFee bool // Forces the EIP-1559 baseFee to 0 (needed for 0 price calls)
34+
EnablePreimageRecording bool // Enables recording of SHA3/keccak preimages
3535

3636
JumpTable [256]*operation // EVM instruction table, automatically populated if unset
3737

@@ -152,9 +152,9 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
152152
pc = uint64(0) // program counter
153153
cost uint64
154154
// copies used by tracer
155-
pcCopy uint64 // needed for the deferred Tracer
156-
gasCopy uint64 // for Tracer to log gas remaining before execution
157-
logged bool // deferred Tracer should ignore already logged steps
155+
pcCopy uint64 // needed for the deferred EVMLogger
156+
gasCopy uint64 // for EVMLogger to log gas remaining before execution
157+
logged bool // deferred EVMLogger should ignore already logged steps
158158
res []byte // result of the opcode execution function
159159
)
160160
// Don't move this deferrred function, it's placed before the capturestate-deferred method,
@@ -169,9 +169,9 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
169169
defer func() {
170170
if err != nil {
171171
if !logged {
172-
in.cfg.Tracer.CaptureState(in.evm, pcCopy, op, gasCopy, cost, callContext, in.returnData, in.evm.depth, err)
172+
in.cfg.Tracer.CaptureState(pcCopy, op, gasCopy, cost, callContext, in.returnData, in.evm.depth, err)
173173
} else {
174-
in.cfg.Tracer.CaptureFault(in.evm, pcCopy, op, gasCopy, cost, callContext, in.evm.depth, err)
174+
in.cfg.Tracer.CaptureFault(pcCopy, op, gasCopy, cost, callContext, in.evm.depth, err)
175175
}
176176
}
177177
}()
@@ -256,7 +256,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
256256
}
257257

258258
if in.cfg.Debug {
259-
in.cfg.Tracer.CaptureState(in.evm, pc, op, gasCopy, cost, callContext, in.returnData, in.evm.depth, err)
259+
in.cfg.Tracer.CaptureState(pc, op, gasCopy, cost, callContext, in.returnData, in.evm.depth, err)
260260
logged = true
261261
}
262262

core/vm/logger.go

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -98,27 +98,28 @@ func (s *StructLog) ErrorString() string {
9898
return ""
9999
}
100100

101-
// Tracer is used to collect execution traces from an EVM transaction
101+
// EVMLogger is used to collect execution traces from an EVM transaction
102102
// execution. CaptureState is called for each step of the VM with the
103103
// current VM state.
104104
// Note that reference types are actual VM data structures; make copies
105105
// if you need to retain them beyond the current call.
106-
type Tracer interface {
106+
type EVMLogger interface {
107107
CaptureStart(env *EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int)
108-
CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error)
108+
CaptureState(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error)
109109
CaptureEnter(typ OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int)
110110
CaptureExit(output []byte, gasUsed uint64, err error)
111-
CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, depth int, err error)
111+
CaptureFault(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, depth int, err error)
112112
CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error)
113113
}
114114

115-
// StructLogger is an EVM state logger and implements Tracer.
115+
// StructLogger is an EVM state logger and implements EVMLogger.
116116
//
117117
// StructLogger can capture state based on the given Log configuration and also keeps
118118
// a track record of modified storage which is used in reporting snapshots of the
119119
// contract their storage.
120120
type StructLogger struct {
121121
cfg LogConfig
122+
env *EVM
122123

123124
storage map[common.Address]Storage
124125
logs []StructLog
@@ -145,14 +146,15 @@ func (l *StructLogger) Reset() {
145146
l.err = nil
146147
}
147148

148-
// CaptureStart implements the Tracer interface to initialize the tracing operation.
149+
// CaptureStart implements the EVMLogger interface to initialize the tracing operation.
149150
func (l *StructLogger) CaptureStart(env *EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
151+
l.env = env
150152
}
151153

152154
// CaptureState logs a new structured log message and pushes it out to the environment
153155
//
154156
// CaptureState also tracks SLOAD/SSTORE ops to track storage change.
155-
func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error) {
157+
func (l *StructLogger) CaptureState(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error) {
156158
memory := scope.Memory
157159
stack := scope.Stack
158160
contract := scope.Contract
@@ -186,7 +188,7 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui
186188
if op == SLOAD && stack.len() >= 1 {
187189
var (
188190
address = common.Hash(stack.data[stack.len()-1].Bytes32())
189-
value = env.StateDB.GetState(contract.Address(), address)
191+
value = l.env.StateDB.GetState(contract.Address(), address)
190192
)
191193
l.storage[contract.Address()][address] = value
192194
storage = l.storage[contract.Address()].Copy()
@@ -206,13 +208,13 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui
206208
copy(rdata, rData)
207209
}
208210
// create a new snapshot of the EVM.
209-
log := StructLog{pc, op, gas, cost, mem, memory.Len(), stck, rdata, storage, depth, env.StateDB.GetRefund(), err}
211+
log := StructLog{pc, op, gas, cost, mem, memory.Len(), stck, rdata, storage, depth, l.env.StateDB.GetRefund(), err}
210212
l.logs = append(l.logs, log)
211213
}
212214

213-
// CaptureFault implements the Tracer interface to trace an execution fault
215+
// CaptureFault implements the EVMLogger interface to trace an execution fault
214216
// while running an opcode.
215-
func (l *StructLogger) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, depth int, err error) {
217+
func (l *StructLogger) CaptureFault(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, depth int, err error) {
216218
}
217219

218220
// CaptureEnd is called after the call finishes to finalize the tracing.
@@ -291,19 +293,21 @@ func WriteLogs(writer io.Writer, logs []*types.Log) {
291293
type mdLogger struct {
292294
out io.Writer
293295
cfg *LogConfig
296+
env *EVM
294297
}
295298

296299
// NewMarkdownLogger creates a logger which outputs information in a format adapted
297300
// for human readability, and is also a valid markdown table
298301
func NewMarkdownLogger(cfg *LogConfig, writer io.Writer) *mdLogger {
299-
l := &mdLogger{writer, cfg}
302+
l := &mdLogger{out: writer, cfg: cfg}
300303
if l.cfg == nil {
301304
l.cfg = &LogConfig{}
302305
}
303306
return l
304307
}
305308

306309
func (t *mdLogger) CaptureStart(env *EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
310+
t.env = env
307311
if !create {
308312
fmt.Fprintf(t.out, "From: `%v`\nTo: `%v`\nData: `0x%x`\nGas: `%d`\nValue `%v` wei\n",
309313
from.String(), to.String(),
@@ -321,7 +325,7 @@ func (t *mdLogger) CaptureStart(env *EVM, from common.Address, to common.Address
321325
}
322326

323327
// CaptureState also tracks SLOAD/SSTORE ops to track storage change.
324-
func (t *mdLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error) {
328+
func (t *mdLogger) CaptureState(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error) {
325329
stack := scope.Stack
326330
fmt.Fprintf(t.out, "| %4d | %10v | %3d |", pc, op, cost)
327331

@@ -334,14 +338,14 @@ func (t *mdLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64
334338
b := fmt.Sprintf("[%v]", strings.Join(a, ","))
335339
fmt.Fprintf(t.out, "%10v |", b)
336340
}
337-
fmt.Fprintf(t.out, "%10v |", env.StateDB.GetRefund())
341+
fmt.Fprintf(t.out, "%10v |", t.env.StateDB.GetRefund())
338342
fmt.Fprintln(t.out, "")
339343
if err != nil {
340344
fmt.Fprintf(t.out, "Error: %v\n", err)
341345
}
342346
}
343347

344-
func (t *mdLogger) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, depth int, err error) {
348+
func (t *mdLogger) CaptureFault(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, depth int, err error) {
345349
fmt.Fprintf(t.out, "\nError: at pc=%d, op=%v: %v\n", pc, op, err)
346350
}
347351

core/vm/logger_json.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,25 +29,27 @@ import (
2929
type JSONLogger struct {
3030
encoder *json.Encoder
3131
cfg *LogConfig
32+
env *EVM
3233
}
3334

3435
// NewJSONLogger creates a new EVM tracer that prints execution steps as JSON objects
3536
// into the provided stream.
3637
func NewJSONLogger(cfg *LogConfig, writer io.Writer) *JSONLogger {
37-
l := &JSONLogger{json.NewEncoder(writer), cfg}
38+
l := &JSONLogger{encoder: json.NewEncoder(writer), cfg: cfg}
3839
if l.cfg == nil {
3940
l.cfg = &LogConfig{}
4041
}
4142
return l
4243
}
4344

4445
func (l *JSONLogger) CaptureStart(env *EVM, from, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
46+
l.env = env
4547
}
4648

47-
func (l *JSONLogger) CaptureFault(*EVM, uint64, OpCode, uint64, uint64, *ScopeContext, int, error) {}
49+
func (l *JSONLogger) CaptureFault(uint64, OpCode, uint64, uint64, *ScopeContext, int, error) {}
4850

4951
// CaptureState outputs state information on the logger.
50-
func (l *JSONLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error) {
52+
func (l *JSONLogger) CaptureState(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error) {
5153
memory := scope.Memory
5254
stack := scope.Stack
5355

@@ -58,7 +60,7 @@ func (l *JSONLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint
5860
GasCost: cost,
5961
MemorySize: memory.Len(),
6062
Depth: depth,
61-
RefundCounter: env.StateDB.GetRefund(),
63+
RefundCounter: l.env.StateDB.GetRefund(),
6264
Err: err,
6365
}
6466
if l.cfg.EnableMemory {

core/vm/logger_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ func TestStoreCapture(t *testing.T) {
6262
scope.Stack.push(uint256.NewInt(1))
6363
scope.Stack.push(new(uint256.Int))
6464
var index common.Hash
65-
logger.CaptureState(env, 0, SSTORE, 0, 0, scope, nil, 0, nil)
65+
logger.CaptureStart(env, common.Address{}, contract.Address(), false, nil, 0, nil)
66+
logger.CaptureState(0, SSTORE, 0, 0, scope, nil, 0, nil)
6667
if len(logger.storage[contract.Address()]) == 0 {
6768
t.Fatalf("expected exactly 1 changed value on address %x, got %d", contract.Address(),
6869
len(logger.storage[contract.Address()]))

0 commit comments

Comments
 (0)