forked from cerc-io/plugeth
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,
|
vm: vm,
|
||||||
ctx: make(map[string]goja.Value),
|
ctx: make(map[string]goja.Value),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t.setTypeConverters()
|
||||||
|
t.setBuiltinFunctions()
|
||||||
|
|
||||||
if ctx == nil {
|
if ctx == nil {
|
||||||
ctx = new(tracers.Context)
|
ctx = new(tracers.Context)
|
||||||
}
|
}
|
||||||
if ctx.BlockHash != (common.Hash{}) {
|
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{}) {
|
if ctx.TxHash != (common.Hash{}) {
|
||||||
t.ctx["txIndex"] = vm.ToValue(ctx.TxIndex)
|
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 + ")")
|
ret, err := vm.RunString("(" + code + ")")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -224,6 +234,10 @@ func (t *jsTracer) CaptureTxEnd(restGas uint64) {
|
|||||||
|
|
||||||
// CaptureStart implements the Tracer interface to initialize the tracing operation.
|
// 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) {
|
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
|
t.env = env
|
||||||
db := &dbObj{db: env.StateDB, vm: t.vm, toBig: t.toBig, toBuf: t.toBuf, fromBuf: t.fromBuf}
|
db := &dbObj{db: env.StateDB, vm: t.vm, toBig: t.toBig, toBuf: t.toBuf, fromBuf: t.fromBuf}
|
||||||
t.dbValue = db.setupObject()
|
t.dbValue = db.setupObject()
|
||||||
@ -232,19 +246,34 @@ func (t *jsTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Addr
|
|||||||
} else {
|
} else {
|
||||||
t.ctx["type"] = t.vm.ToValue("CALL")
|
t.ctx["type"] = t.vm.ToValue("CALL")
|
||||||
}
|
}
|
||||||
t.ctx["from"] = t.vm.ToValue(from.Bytes())
|
fromVal, err := t.toBuf(t.vm, from.Bytes())
|
||||||
t.ctx["to"] = t.vm.ToValue(to.Bytes())
|
if err != nil {
|
||||||
t.ctx["input"] = t.vm.ToValue(input)
|
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)
|
t.ctx["gas"] = t.vm.ToValue(t.gasLimit)
|
||||||
gasPriceBig, err := t.toBig(t.vm, env.TxContext.GasPrice.String())
|
gasPriceBig, err := t.toBig(t.vm, env.TxContext.GasPrice.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.err = err
|
cancel(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
t.ctx["gasPrice"] = gasPriceBig
|
t.ctx["gasPrice"] = gasPriceBig
|
||||||
valueBig, err := t.toBig(t.vm, value.String())
|
valueBig, err := t.toBig(t.vm, value.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.err = err
|
cancel(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
t.ctx["value"] = valueBig
|
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.
|
// CaptureEnd is called after the call finishes to finalize the tracing.
|
||||||
func (t *jsTracer) CaptureEnd(output []byte, gasUsed uint64, err error) {
|
func (t *jsTracer) CaptureEnd(output []byte, gasUsed uint64, err error) {
|
||||||
t.ctx["output"] = t.vm.ToValue(output)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.ctx["error"] = t.vm.ToValue(err.Error())
|
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).
|
// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct).
|
||||||
@ -465,13 +499,13 @@ func (t *jsTracer) setBuiltinFunctions() {
|
|||||||
}
|
}
|
||||||
return false
|
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)
|
b, err := t.fromBuf(vm, slice, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
vm.Interrupt(err)
|
vm.Interrupt(err)
|
||||||
return nil
|
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))
|
vm.Interrupt(fmt.Sprintf("Tracer accessed out of bound memory: available %d, offset %d, size %d", len(b), start, end-start))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user