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.
This commit is contained in:
parent
248dc50ee8
commit
bbc5db8405
|
@ -142,19 +142,29 @@ func newJsTracer(code string, ctx *tracers.Context, cfg json.RawMessage) (tracer
|
|||
vm: vm,
|
||||
ctx: make(map[string]goja.Value),
|
||||
}
|
||||
|
||||
t.setTypeConverters()
|
||||
t.setBuiltinFunctions()
|
||||
|
||||
if ctx == nil {
|
||||
ctx = new(tracers.Context)
|
||||
}
|
||||
if ctx.BlockHash != (common.Hash{}) {
|
||||
t.ctx["blockHash"] = vm.ToValue(ctx.BlockHash.Bytes())
|
||||
blockHash, err := t.toBuf(vm, ctx.BlockHash.Bytes())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t.ctx["blockHash"] = blockHash
|
||||
if ctx.TxHash != (common.Hash{}) {
|
||||
t.ctx["txIndex"] = vm.ToValue(ctx.TxIndex)
|
||||
t.ctx["txHash"] = vm.ToValue(ctx.TxHash.Bytes())
|
||||
txHash, err := t.toBuf(vm, ctx.TxHash.Bytes())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t.ctx["txHash"] = txHash
|
||||
}
|
||||
}
|
||||
|
||||
t.setTypeConverters()
|
||||
t.setBuiltinFunctions()
|
||||
ret, err := vm.RunString("(" + code + ")")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -224,6 +234,10 @@ func (t *jsTracer) CaptureTxEnd(restGas uint64) {
|
|||
|
||||
// CaptureStart implements the Tracer interface to initialize the tracing operation.
|
||||
func (t *jsTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
|
||||
cancel := func(err error) {
|
||||
t.err = err
|
||||
t.env.Cancel()
|
||||
}
|
||||
t.env = env
|
||||
db := &dbObj{db: env.StateDB, vm: t.vm, toBig: t.toBig, toBuf: t.toBuf, fromBuf: t.fromBuf}
|
||||
t.dbValue = db.setupObject()
|
||||
|
@ -232,19 +246,34 @@ func (t *jsTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Addr
|
|||
} else {
|
||||
t.ctx["type"] = t.vm.ToValue("CALL")
|
||||
}
|
||||
t.ctx["from"] = t.vm.ToValue(from.Bytes())
|
||||
t.ctx["to"] = t.vm.ToValue(to.Bytes())
|
||||
t.ctx["input"] = t.vm.ToValue(input)
|
||||
fromVal, err := t.toBuf(t.vm, from.Bytes())
|
||||
if err != nil {
|
||||
cancel(err)
|
||||
return
|
||||
}
|
||||
t.ctx["from"] = fromVal
|
||||
toVal, err := t.toBuf(t.vm, to.Bytes())
|
||||
if err != nil {
|
||||
cancel(err)
|
||||
return
|
||||
}
|
||||
t.ctx["to"] = toVal
|
||||
inputVal, err := t.toBuf(t.vm, input)
|
||||
if err != nil {
|
||||
cancel(err)
|
||||
return
|
||||
}
|
||||
t.ctx["input"] = inputVal
|
||||
t.ctx["gas"] = t.vm.ToValue(t.gasLimit)
|
||||
gasPriceBig, err := t.toBig(t.vm, env.TxContext.GasPrice.String())
|
||||
if err != nil {
|
||||
t.err = err
|
||||
cancel(err)
|
||||
return
|
||||
}
|
||||
t.ctx["gasPrice"] = gasPriceBig
|
||||
valueBig, err := t.toBig(t.vm, value.String())
|
||||
if err != nil {
|
||||
t.err = err
|
||||
cancel(err)
|
||||
return
|
||||
}
|
||||
t.ctx["value"] = valueBig
|
||||
|
@ -293,10 +322,15 @@ func (t *jsTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope
|
|||
|
||||
// CaptureEnd is called after the call finishes to finalize the tracing.
|
||||
func (t *jsTracer) CaptureEnd(output []byte, gasUsed uint64, err error) {
|
||||
t.ctx["output"] = t.vm.ToValue(output)
|
||||
if err != nil {
|
||||
t.ctx["error"] = t.vm.ToValue(err.Error())
|
||||
}
|
||||
outputVal, err := t.toBuf(t.vm, output)
|
||||
if err != nil {
|
||||
t.err = err
|
||||
return
|
||||
}
|
||||
t.ctx["output"] = outputVal
|
||||
}
|
||||
|
||||
// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct).
|
||||
|
@ -465,13 +499,13 @@ func (t *jsTracer) setBuiltinFunctions() {
|
|||
}
|
||||
return false
|
||||
})
|
||||
vm.Set("slice", func(slice goja.Value, start, end int) goja.Value {
|
||||
vm.Set("slice", func(slice goja.Value, start, end int64) goja.Value {
|
||||
b, err := t.fromBuf(vm, slice, false)
|
||||
if err != nil {
|
||||
vm.Interrupt(err)
|
||||
return nil
|
||||
}
|
||||
if start < 0 || start > end || end > len(b) {
|
||||
if start < 0 || start > end || end > int64(len(b)) {
|
||||
vm.Interrupt(fmt.Sprintf("Tracer accessed out of bound memory: available %d, offset %d, size %d", len(b), start, end-start))
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue