core, eth: fix precompile addresses for tracers (#23097)
* core,eth/tracers: make isPrecompiled dependent on HF * eth/tracers: use keys when constructing chain config struct * eth/tracers: dont initialize activePrecompiles with random value
This commit is contained in:
parent
dde6f1e92d
commit
1b5582acf7
|
@ -310,6 +310,8 @@ type Tracer struct {
|
||||||
|
|
||||||
interrupt uint32 // Atomic flag to signal execution interruption
|
interrupt uint32 // Atomic flag to signal execution interruption
|
||||||
reason error // Textual reason for the interruption
|
reason error // Textual reason for the interruption
|
||||||
|
|
||||||
|
activePrecompiles []common.Address // Updated on CaptureStart based on given rules
|
||||||
}
|
}
|
||||||
|
|
||||||
// Context contains some contextual infos for a transaction execution that is not
|
// Context contains some contextual infos for a transaction execution that is not
|
||||||
|
@ -414,8 +416,14 @@ func New(code string, ctx *Context) (*Tracer, error) {
|
||||||
return 1
|
return 1
|
||||||
})
|
})
|
||||||
tracer.vm.PushGlobalGoFunction("isPrecompiled", func(ctx *duktape.Context) int {
|
tracer.vm.PushGlobalGoFunction("isPrecompiled", func(ctx *duktape.Context) int {
|
||||||
_, ok := vm.PrecompiledContractsIstanbul[common.BytesToAddress(popSlice(ctx))]
|
addr := common.BytesToAddress(popSlice(ctx))
|
||||||
ctx.PushBoolean(ok)
|
for _, p := range tracer.activePrecompiles {
|
||||||
|
if p == addr {
|
||||||
|
ctx.PushBoolean(true)
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.PushBoolean(false)
|
||||||
return 1
|
return 1
|
||||||
})
|
})
|
||||||
tracer.vm.PushGlobalGoFunction("slice", func(ctx *duktape.Context) int {
|
tracer.vm.PushGlobalGoFunction("slice", func(ctx *duktape.Context) int {
|
||||||
|
@ -570,6 +578,9 @@ func (jst *Tracer) CaptureStart(env *vm.EVM, from common.Address, to common.Addr
|
||||||
// Initialize the context
|
// Initialize the context
|
||||||
jst.ctx["block"] = env.Context.BlockNumber.Uint64()
|
jst.ctx["block"] = env.Context.BlockNumber.Uint64()
|
||||||
jst.dbWrapper.db = env.StateDB
|
jst.dbWrapper.db = env.StateDB
|
||||||
|
// Update list of precompiles based on current block
|
||||||
|
rules := env.ChainConfig().Rules(env.Context.BlockNumber)
|
||||||
|
jst.activePrecompiles = vm.ActivePrecompiles(rules)
|
||||||
|
|
||||||
// Compute intrinsic gas
|
// Compute intrinsic gas
|
||||||
isHomestead := env.ChainConfig().IsHomestead(env.Context.BlockNumber)
|
isHomestead := env.ChainConfig().IsHomestead(env.Context.BlockNumber)
|
||||||
|
|
|
@ -58,8 +58,8 @@ func testCtx() *vmContext {
|
||||||
return &vmContext{blockCtx: vm.BlockContext{BlockNumber: big.NewInt(1)}, txCtx: vm.TxContext{GasPrice: big.NewInt(100000)}}
|
return &vmContext{blockCtx: vm.BlockContext{BlockNumber: big.NewInt(1)}, txCtx: vm.TxContext{GasPrice: big.NewInt(100000)}}
|
||||||
}
|
}
|
||||||
|
|
||||||
func runTrace(tracer *Tracer, vmctx *vmContext) (json.RawMessage, error) {
|
func runTrace(tracer *Tracer, vmctx *vmContext, chaincfg *params.ChainConfig) (json.RawMessage, error) {
|
||||||
env := vm.NewEVM(vmctx.blockCtx, vmctx.txCtx, &dummyStatedb{}, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer})
|
env := vm.NewEVM(vmctx.blockCtx, vmctx.txCtx, &dummyStatedb{}, chaincfg, vm.Config{Debug: true, Tracer: tracer})
|
||||||
var (
|
var (
|
||||||
startGas uint64 = 10000
|
startGas uint64 = 10000
|
||||||
value = big.NewInt(0)
|
value = big.NewInt(0)
|
||||||
|
@ -86,7 +86,7 @@ func TestTracer(t *testing.T) {
|
||||||
ret, err := runTrace(tracer, &vmContext{
|
ret, err := runTrace(tracer, &vmContext{
|
||||||
blockCtx: vm.BlockContext{BlockNumber: big.NewInt(1)},
|
blockCtx: vm.BlockContext{BlockNumber: big.NewInt(1)},
|
||||||
txCtx: vm.TxContext{GasPrice: big.NewInt(100000)},
|
txCtx: vm.TxContext{GasPrice: big.NewInt(100000)},
|
||||||
})
|
}, params.TestChainConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err.Error() // Stringify to allow comparison without nil checks
|
return nil, err.Error() // Stringify to allow comparison without nil checks
|
||||||
}
|
}
|
||||||
|
@ -141,7 +141,7 @@ func TestHalt(t *testing.T) {
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
tracer.Stop(timeout)
|
tracer.Stop(timeout)
|
||||||
}()
|
}()
|
||||||
if _, err = runTrace(tracer, testCtx()); err.Error() != "stahp in server-side tracer function 'step'" {
|
if _, err = runTrace(tracer, testCtx(), params.TestChainConfig); err.Error() != "stahp in server-side tracer function 'step'" {
|
||||||
t.Errorf("Expected timeout error, got %v", err)
|
t.Errorf("Expected timeout error, got %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -205,3 +205,34 @@ func TestNoStepExec(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIsPrecompile(t *testing.T) {
|
||||||
|
chaincfg := ¶ms.ChainConfig{ChainID: big.NewInt(1), HomesteadBlock: big.NewInt(0), DAOForkBlock: nil, DAOForkSupport: false, EIP150Block: big.NewInt(0), EIP150Hash: common.Hash{}, EIP155Block: big.NewInt(0), EIP158Block: big.NewInt(0), ByzantiumBlock: big.NewInt(100), ConstantinopleBlock: big.NewInt(0), PetersburgBlock: big.NewInt(0), IstanbulBlock: big.NewInt(200), MuirGlacierBlock: big.NewInt(0), BerlinBlock: big.NewInt(300), LondonBlock: big.NewInt(0), EWASMBlock: nil, CatalystBlock: nil, Ethash: new(params.EthashConfig), Clique: nil}
|
||||||
|
chaincfg.ByzantiumBlock = big.NewInt(100)
|
||||||
|
chaincfg.IstanbulBlock = big.NewInt(200)
|
||||||
|
chaincfg.BerlinBlock = big.NewInt(300)
|
||||||
|
txCtx := vm.TxContext{GasPrice: big.NewInt(100000)}
|
||||||
|
tracer, err := New("{addr: toAddress('0000000000000000000000000000000000000009'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}", new(Context))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
blockCtx := vm.BlockContext{BlockNumber: big.NewInt(150)}
|
||||||
|
res, err := runTrace(tracer, &vmContext{blockCtx, txCtx}, chaincfg)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if string(res) != "false" {
|
||||||
|
t.Errorf("Tracer should not consider blake2f as precompile in byzantium")
|
||||||
|
}
|
||||||
|
|
||||||
|
tracer, _ = New("{addr: toAddress('0000000000000000000000000000000000000009'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}", new(Context))
|
||||||
|
blockCtx = vm.BlockContext{BlockNumber: big.NewInt(250)}
|
||||||
|
res, err = runTrace(tracer, &vmContext{blockCtx, txCtx}, chaincfg)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if string(res) != "true" {
|
||||||
|
t.Errorf("Tracer should consider blake2f as precompile in istanbul")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue