Parent: #13653. Related method/tracer inventory: #13657.
Custom JavaScript tracers still have observable differences against upstream Geth 23408c2b17c3f4e094921d2ff305bfef018b1ace. These are separate from the indexed-call block-context correction in #13700.
toHex output prefix
With a funded synthetic caller, an overridden target containing 0x00, and this tracer:
{step:function(){},fault:function(){},result:function(ctx){return {output:toHex(ctx.output)};}}
debug_traceCall returns { "output": "" } in Nethermind 7f3fa1ca0848fd80be70006676a6ac4e1ca6584c, versus { "output": "0x" } in Geth. With target code 0x602a60005260206000f3, both return the 32-byte word 42, but Nethermind omits 0x while Geth includes it. No txIndex is required. Source: Engine.ToHex calls ToHexString() without the prefix flag. Audit bundled scripts before changing the helper, including empty/nonempty buffers and helper arguments.
ctx.gasPrice interpretation
For a funded synthetic caller and STOP target, override blockOverrides.baseFeePerGas to 0x7 and return ctx.gasPrice.toString(10) from the tracer:
| Call fees |
Nethermind |
Geth |
gasPrice: "0x64" |
"100" |
"93" |
maxFeePerGas: "0x64", maxPriorityFeePerGas: "0x2" |
"9" |
"2" |
Verified using identical requests at a matching recent mainnet block, with txIndex omitted. Nethermind source GethLikeBlockJavaScriptTracer.SetTransactionCtx uses the effective gas price; Geth eth/tracers/js/goja.go:OnTxStart uses tx.EffectiveGasTip(env.BaseFee).
Geth's custom-tracer documentation describes gasPrice as the configured transaction price; this differs from its current implementation at nonzero base fee. The execution-apis debug schemas do not specify this custom JavaScript context. Establish and document the compatibility decision before changing this field; no exception to Geth parity has yet been accepted.
Acceptance
- Add failing-before/passing-after regressions through RPC serialization and the JavaScript engine, then shared HTTP fixtures against pinned Geth.
- Cover empty/nonempty helper results, legacy/dynamic fees, zero/nonzero base fees, and indexed/non-indexed calls.
- Check bundled tracers for callers that already prepend
0x.
- Record any justified semantic exception explicitly rather than suppressing mismatches in the comparison harness.
No implementation is included in this issue yet; keep it open until the accepted behavior is tested and documented.
Source follow-up: the bundled 4byteTracer_legacy, callTracer_legacy and prestateTracer_legacy scripts use toHex directly, without adding a prefix to its result. Fixing the shared helper therefore also affects their address/input/output/code/storage encodings. Existing JavaScript tracer tests currently encode unprefixed expectations, including the result-disposal/recovery tests; retain those lifecycle assertions while adding reference-backed empty/nonempty bytes and legacy-tracer coverage. No JavaScript helper fix is included in #13705. The separate ctx.gasPrice compatibility decision remains open.
Parent: #13653. Related method/tracer inventory: #13657.
Custom JavaScript tracers still have observable differences against upstream Geth
23408c2b17c3f4e094921d2ff305bfef018b1ace. These are separate from the indexed-call block-context correction in #13700.toHexoutput prefixWith a funded synthetic caller, an overridden target containing
0x00, and this tracer:debug_traceCallreturns{ "output": "" }in Nethermind7f3fa1ca0848fd80be70006676a6ac4e1ca6584c, versus{ "output": "0x" }in Geth. With target code0x602a60005260206000f3, both return the 32-byte word 42, but Nethermind omits0xwhile Geth includes it. NotxIndexis required. Source:Engine.ToHexcallsToHexString()without the prefix flag. Audit bundled scripts before changing the helper, including empty/nonempty buffers and helper arguments.ctx.gasPriceinterpretationFor a funded synthetic caller and STOP target, override
blockOverrides.baseFeePerGasto0x7and returnctx.gasPrice.toString(10)from the tracer:gasPrice: "0x64""100""93"maxFeePerGas: "0x64", maxPriorityFeePerGas: "0x2""9""2"Verified using identical requests at a matching recent mainnet block, with
txIndexomitted. Nethermind sourceGethLikeBlockJavaScriptTracer.SetTransactionCtxuses the effective gas price; Getheth/tracers/js/goja.go:OnTxStartusestx.EffectiveGasTip(env.BaseFee).Geth's custom-tracer documentation describes gasPrice as the configured transaction price; this differs from its current implementation at nonzero base fee. The execution-apis debug schemas do not specify this custom JavaScript context. Establish and document the compatibility decision before changing this field; no exception to Geth parity has yet been accepted.
Acceptance
0x.No implementation is included in this issue yet; keep it open until the accepted behavior is tested and documented.
Source follow-up: the bundled
4byteTracer_legacy,callTracer_legacyandprestateTracer_legacyscripts usetoHexdirectly, without adding a prefix to its result. Fixing the shared helper therefore also affects their address/input/output/code/storage encodings. Existing JavaScript tracer tests currently encode unprefixed expectations, including the result-disposal/recovery tests; retain those lifecycle assertions while adding reference-backed empty/nonempty bytes and legacy-tracer coverage. No JavaScript helper fix is included in #13705. The separatectx.gasPricecompatibility decision remains open.