Skip to content

Commit bbc5db8

Browse files
authored
eth/tracers/js: fix type inconsistencies (#28488)
This change fixes two type-inconsistencies in the JS tracer: - In most places we return byte arrays as a `Uint8Array` to the tracer. However it seems we missed doing the conversion for `ctx` fields which are passed to the tracer during `result`. They are passed as simple arrays. I think Uint8Arrays are more suitable and we should change this inconsistency. Note: this will be a breaking-change. But I believe the effect is small. If we look at our tracers we see that these fields (`ctx.from`, `ctx.to`, etc.) are used in 2 ways. Passed to `toHex` which takes both array or buffer. Or the length was measured which is the same for both types. - The `slice` taking in `int, int` params versus `memory.slice` taking `int64, int64` params. I suggest changing `slice` types to `int64`. This should have no effect almost in any case.
1 parent 248dc50 commit bbc5db8

File tree

1 file changed

+46
-12
lines changed

1 file changed

+46
-12
lines changed

eth/tracers/js/goja.go

+46-12
Original file line numberDiff line numberDiff line change
@@ -142,19 +142,29 @@ func newJsTracer(code string, ctx *tracers.Context, cfg json.RawMessage) (tracer
142142
vm: vm,
143143
ctx: make(map[string]goja.Value),
144144
}
145+
146+
t.setTypeConverters()
147+
t.setBuiltinFunctions()
148+
145149
if ctx == nil {
146150
ctx = new(tracers.Context)
147151
}
148152
if ctx.BlockHash != (common.Hash{}) {
149-
t.ctx["blockHash"] = vm.ToValue(ctx.BlockHash.Bytes())
153+
blockHash, err := t.toBuf(vm, ctx.BlockHash.Bytes())
154+
if err != nil {
155+
return nil, err
156+
}
157+
t.ctx["blockHash"] = blockHash
150158
if ctx.TxHash != (common.Hash{}) {
151159
t.ctx["txIndex"] = vm.ToValue(ctx.TxIndex)
152-
t.ctx["txHash"] = vm.ToValue(ctx.TxHash.Bytes())
160+
txHash, err := t.toBuf(vm, ctx.TxHash.Bytes())
161+
if err != nil {
162+
return nil, err
163+
}
164+
t.ctx["txHash"] = txHash
153165
}
154166
}
155167

156-
t.setTypeConverters()
157-
t.setBuiltinFunctions()
158168
ret, err := vm.RunString("(" + code + ")")
159169
if err != nil {
160170
return nil, err
@@ -224,6 +234,10 @@ func (t *jsTracer) CaptureTxEnd(restGas uint64) {
224234

225235
// CaptureStart implements the Tracer interface to initialize the tracing operation.
226236
func (t *jsTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
237+
cancel := func(err error) {
238+
t.err = err
239+
t.env.Cancel()
240+
}
227241
t.env = env
228242
db := &dbObj{db: env.StateDB, vm: t.vm, toBig: t.toBig, toBuf: t.toBuf, fromBuf: t.fromBuf}
229243
t.dbValue = db.setupObject()
@@ -232,19 +246,34 @@ func (t *jsTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Addr
232246
} else {
233247
t.ctx["type"] = t.vm.ToValue("CALL")
234248
}
235-
t.ctx["from"] = t.vm.ToValue(from.Bytes())
236-
t.ctx["to"] = t.vm.ToValue(to.Bytes())
237-
t.ctx["input"] = t.vm.ToValue(input)
249+
fromVal, err := t.toBuf(t.vm, from.Bytes())
250+
if err != nil {
251+
cancel(err)
252+
return
253+
}
254+
t.ctx["from"] = fromVal
255+
toVal, err := t.toBuf(t.vm, to.Bytes())
256+
if err != nil {
257+
cancel(err)
258+
return
259+
}
260+
t.ctx["to"] = toVal
261+
inputVal, err := t.toBuf(t.vm, input)
262+
if err != nil {
263+
cancel(err)
264+
return
265+
}
266+
t.ctx["input"] = inputVal
238267
t.ctx["gas"] = t.vm.ToValue(t.gasLimit)
239268
gasPriceBig, err := t.toBig(t.vm, env.TxContext.GasPrice.String())
240269
if err != nil {
241-
t.err = err
270+
cancel(err)
242271
return
243272
}
244273
t.ctx["gasPrice"] = gasPriceBig
245274
valueBig, err := t.toBig(t.vm, value.String())
246275
if err != nil {
247-
t.err = err
276+
cancel(err)
248277
return
249278
}
250279
t.ctx["value"] = valueBig
@@ -293,10 +322,15 @@ func (t *jsTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope
293322

294323
// CaptureEnd is called after the call finishes to finalize the tracing.
295324
func (t *jsTracer) CaptureEnd(output []byte, gasUsed uint64, err error) {
296-
t.ctx["output"] = t.vm.ToValue(output)
297325
if err != nil {
298326
t.ctx["error"] = t.vm.ToValue(err.Error())
299327
}
328+
outputVal, err := t.toBuf(t.vm, output)
329+
if err != nil {
330+
t.err = err
331+
return
332+
}
333+
t.ctx["output"] = outputVal
300334
}
301335

302336
// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct).
@@ -465,13 +499,13 @@ func (t *jsTracer) setBuiltinFunctions() {
465499
}
466500
return false
467501
})
468-
vm.Set("slice", func(slice goja.Value, start, end int) goja.Value {
502+
vm.Set("slice", func(slice goja.Value, start, end int64) goja.Value {
469503
b, err := t.fromBuf(vm, slice, false)
470504
if err != nil {
471505
vm.Interrupt(err)
472506
return nil
473507
}
474-
if start < 0 || start > end || end > len(b) {
508+
if start < 0 || start > end || end > int64(len(b)) {
475509
vm.Interrupt(fmt.Sprintf("Tracer accessed out of bound memory: available %d, offset %d, size %d", len(b), start, end-start))
476510
return nil
477511
}

0 commit comments

Comments
 (0)