@ -90,11 +90,12 @@ func runTrace(tracer *tracers.Tracer, vmctx *vmContext, chaincfg *params.ChainCo
func TestTracer ( t * testing . T ) {
func TestTracer ( t * testing . T ) {
execTracer := func ( code string , contract [ ] byte ) ( [ ] byte , string ) {
execTracer := func ( code string , contract [ ] byte ) ( [ ] byte , string ) {
t . Helper ( )
t . Helper ( )
tracer , err := newJsTracer ( code , nil , nil )
chainConfig := params . TestChainConfig
tracer , err := newJsTracer ( code , nil , nil , chainConfig )
if err != nil {
if err != nil {
t . Fatal ( err )
t . Fatal ( err )
}
}
ret , err := runTrace ( tracer , testCtx ( ) , params . TestC hainConfig, contract )
ret , err := runTrace ( tracer , testCtx ( ) , c hainConfig, contract )
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
}
}
@ -167,7 +168,8 @@ func TestTracer(t *testing.T) {
func TestHalt ( t * testing . T ) {
func TestHalt ( t * testing . T ) {
timeout := errors . New ( "stahp" )
timeout := errors . New ( "stahp" )
tracer , err := newJsTracer ( "{step: function() { while(1); }, result: function() { return null; }, fault: function(){}}" , nil , nil )
chainConfig := params . TestChainConfig
tracer , err := newJsTracer ( "{step: function() { while(1); }, result: function() { return null; }, fault: function(){}}" , nil , nil , chainConfig )
if err != nil {
if err != nil {
t . Fatal ( err )
t . Fatal ( err )
}
}
@ -175,20 +177,21 @@ 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 ( ) , params . TestC hainConfig, nil ) ; ! strings . Contains ( err . Error ( ) , "stahp" ) {
if _ , err = runTrace ( tracer , testCtx ( ) , c hainConfig, nil ) ; ! strings . Contains ( err . Error ( ) , "stahp" ) {
t . Errorf ( "Expected timeout error, got %v" , err )
t . Errorf ( "Expected timeout error, got %v" , err )
}
}
}
}
func TestHaltBetweenSteps ( t * testing . T ) {
func TestHaltBetweenSteps ( t * testing . T ) {
tracer , err := newJsTracer ( "{step: function() {}, fault: function() {}, result: function() { return null; }}" , nil , nil )
chainConfig := params . TestChainConfig
tracer , err := newJsTracer ( "{step: function() {}, fault: function() {}, result: function() { return null; }}" , nil , nil , chainConfig )
if err != nil {
if err != nil {
t . Fatal ( err )
t . Fatal ( err )
}
}
scope := & vm . ScopeContext {
scope := & vm . ScopeContext {
Contract : vm . NewContract ( & account { } , & account { } , uint256 . NewInt ( 0 ) , 0 ) ,
Contract : vm . NewContract ( & account { } , & account { } , uint256 . NewInt ( 0 ) , 0 ) ,
}
}
env := vm . NewEVM ( vm . BlockContext { BlockNumber : big . NewInt ( 1 ) } , vm . TxContext { GasPrice : big . NewInt ( 1 ) } , & dummyStatedb { } , params . TestC hainConfig, vm . Config { Tracer : tracer . Hooks } )
env := vm . NewEVM ( vm . BlockContext { BlockNumber : big . NewInt ( 1 ) } , vm . TxContext { GasPrice : big . NewInt ( 1 ) } , & dummyStatedb { } , c hainConfig, vm . Config { Tracer : tracer . Hooks } )
tracer . OnTxStart ( env . GetVMContext ( ) , types . NewTx ( & types . LegacyTx { } ) , common . Address { } )
tracer . OnTxStart ( env . GetVMContext ( ) , types . NewTx ( & types . LegacyTx { } ) , common . Address { } )
tracer . OnEnter ( 0 , byte ( vm . CALL ) , common . Address { } , common . Address { } , [ ] byte { } , 0 , big . NewInt ( 0 ) )
tracer . OnEnter ( 0 , byte ( vm . CALL ) , common . Address { } , common . Address { } , [ ] byte { } , 0 , big . NewInt ( 0 ) )
tracer . OnOpcode ( 0 , 0 , 0 , 0 , scope , nil , 0 , nil )
tracer . OnOpcode ( 0 , 0 , 0 , 0 , scope , nil , 0 , nil )
@ -206,11 +209,12 @@ func TestHaltBetweenSteps(t *testing.T) {
func TestNoStepExec ( t * testing . T ) {
func TestNoStepExec ( t * testing . T ) {
execTracer := func ( code string ) [ ] byte {
execTracer := func ( code string ) [ ] byte {
t . Helper ( )
t . Helper ( )
tracer , err := newJsTracer ( code , nil , nil )
chainConfig := params . TestChainConfig
tracer , err := newJsTracer ( code , nil , nil , chainConfig )
if err != nil {
if err != nil {
t . Fatal ( err )
t . Fatal ( err )
}
}
env := vm . NewEVM ( vm . BlockContext { BlockNumber : big . NewInt ( 1 ) } , vm . TxContext { GasPrice : big . NewInt ( 100 ) } , & dummyStatedb { } , params . TestC hainConfig, vm . Config { Tracer : tracer . Hooks } )
env := vm . NewEVM ( vm . BlockContext { BlockNumber : big . NewInt ( 1 ) } , vm . TxContext { GasPrice : big . NewInt ( 100 ) } , & dummyStatedb { } , c hainConfig, vm . Config { Tracer : tracer . Hooks } )
tracer . OnTxStart ( env . GetVMContext ( ) , types . NewTx ( & types . LegacyTx { } ) , common . Address { } )
tracer . OnTxStart ( env . GetVMContext ( ) , types . NewTx ( & types . LegacyTx { } ) , common . Address { } )
tracer . OnEnter ( 0 , byte ( vm . CALL ) , common . Address { } , common . Address { } , [ ] byte { } , 1000 , big . NewInt ( 0 ) )
tracer . OnEnter ( 0 , byte ( vm . CALL ) , common . Address { } , common . Address { } , [ ] byte { } , 1000 , big . NewInt ( 0 ) )
tracer . OnExit ( 0 , nil , 0 , nil , false )
tracer . OnExit ( 0 , nil , 0 , nil , false )
@ -241,7 +245,7 @@ func TestIsPrecompile(t *testing.T) {
chaincfg . IstanbulBlock = big . NewInt ( 200 )
chaincfg . IstanbulBlock = big . NewInt ( 200 )
chaincfg . BerlinBlock = big . NewInt ( 300 )
chaincfg . BerlinBlock = big . NewInt ( 300 )
txCtx := vm . TxContext { GasPrice : big . NewInt ( 100000 ) }
txCtx := vm . TxContext { GasPrice : big . NewInt ( 100000 ) }
tracer , err := newJsTracer ( "{addr: toAddress('0000000000000000000000000000000000000009'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}" , nil , nil )
tracer , err := newJsTracer ( "{addr: toAddress('0000000000000000000000000000000000000009'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}" , nil , nil , chaincfg )
if err != nil {
if err != nil {
t . Fatal ( err )
t . Fatal ( err )
}
}
@ -255,7 +259,7 @@ func TestIsPrecompile(t *testing.T) {
t . Errorf ( "tracer should not consider blake2f as precompile in byzantium" )
t . Errorf ( "tracer should not consider blake2f as precompile in byzantium" )
}
}
tracer , _ = newJsTracer ( "{addr: toAddress('0000000000000000000000000000000000000009'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}" , nil , nil )
tracer , _ = newJsTracer ( "{addr: toAddress('0000000000000000000000000000000000000009'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}" , nil , nil , chaincfg )
blockCtx = vm . BlockContext { BlockNumber : big . NewInt ( 250 ) }
blockCtx = vm . BlockContext { BlockNumber : big . NewInt ( 250 ) }
res , err = runTrace ( tracer , & vmContext { blockCtx , txCtx } , chaincfg , nil )
res , err = runTrace ( tracer , & vmContext { blockCtx , txCtx } , chaincfg , nil )
if err != nil {
if err != nil {
@ -267,15 +271,16 @@ func TestIsPrecompile(t *testing.T) {
}
}
func TestEnterExit ( t * testing . T ) {
func TestEnterExit ( t * testing . T ) {
chainConfig := params . TestChainConfig
// test that either both or none of enter() and exit() are defined
// test that either both or none of enter() and exit() are defined
if _ , err := newJsTracer ( "{step: function() {}, fault: function() {}, result: function() { return null; }, enter: function() {}}" , new ( tracers . Context ) , nil ) ; err == nil {
if _ , err := newJsTracer ( "{step: function() {}, fault: function() {}, result: function() { return null; }, enter: function() {}}" , new ( tracers . Context ) , nil , chainConfig ) ; err == nil {
t . Fatal ( "tracer creation should've failed without exit() definition" )
t . Fatal ( "tracer creation should've failed without exit() definition" )
}
}
if _ , err := newJsTracer ( "{step: function() {}, fault: function() {}, result: function() { return null; }, enter: function() {}, exit: function() {}}" , new ( tracers . Context ) , nil ) ; err != nil {
if _ , err := newJsTracer ( "{step: function() {}, fault: function() {}, result: function() { return null; }, enter: function() {}, exit: function() {}}" , new ( tracers . Context ) , nil , chainConfig ) ; err != nil {
t . Fatal ( err )
t . Fatal ( err )
}
}
// test that the enter and exit method are correctly invoked and the values passed
// test that the enter and exit method are correctly invoked and the values passed
tracer , err := newJsTracer ( "{enters: 0, exits: 0, enterGas: 0, gasUsed: 0, step: function() {}, fault: function() {}, result: function() { return {enters: this.enters, exits: this.exits, enterGas: this.enterGas, gasUsed: this.gasUsed} }, enter: function(frame) { this.enters++; this.enterGas = frame.getGas(); }, exit: function(res) { this.exits++; this.gasUsed = res.getGasUsed(); }}" , new ( tracers . Context ) , nil )
tracer , err := newJsTracer ( "{enters: 0, exits: 0, enterGas: 0, gasUsed: 0, step: function() {}, fault: function() {}, result: function() { return {enters: this.enters, exits: this.exits, enterGas: this.enterGas, gasUsed: this.gasUsed} }, enter: function(frame) { this.enters++; this.enterGas = frame.getGas(); }, exit: function(res) { this.exits++; this.gasUsed = res.getGasUsed(); }}" , new ( tracers . Context ) , nil , chainConfig )
if err != nil {
if err != nil {
t . Fatal ( err )
t . Fatal ( err )
}
}
@ -297,7 +302,8 @@ func TestEnterExit(t *testing.T) {
func TestSetup ( t * testing . T ) {
func TestSetup ( t * testing . T ) {
// Test empty config
// Test empty config
_ , err := newJsTracer ( ` { setup: function(cfg) { if (cfg !== " { }") { throw("invalid empty config") } }, fault: function() { }, result: function() { }} ` , new ( tracers . Context ) , nil )
chainConfig := params . TestChainConfig
_ , err := newJsTracer ( ` { setup: function(cfg) { if (cfg !== " { }") { throw("invalid empty config") } }, fault: function() { }, result: function() { }} ` , new ( tracers . Context ) , nil , chainConfig )
if err != nil {
if err != nil {
t . Error ( err )
t . Error ( err )
}
}
@ -307,12 +313,12 @@ func TestSetup(t *testing.T) {
t . Fatal ( err )
t . Fatal ( err )
}
}
// Test no setup func
// Test no setup func
_ , err = newJsTracer ( ` { fault: function() { }, result: function() { }} ` , new ( tracers . Context ) , cfg )
_ , err = newJsTracer ( ` { fault: function() { }, result: function() { }} ` , new ( tracers . Context ) , cfg , chainConfig )
if err != nil {
if err != nil {
t . Fatal ( err )
t . Fatal ( err )
}
}
// Test config value
// Test config value
tracer , err := newJsTracer ( "{config: null, setup: function(cfg) { this.config = JSON.parse(cfg) }, step: function() {}, fault: function() {}, result: function() { return this.config.foo }}" , new ( tracers . Context ) , cfg )
tracer , err := newJsTracer ( "{config: null, setup: function(cfg) { this.config = JSON.parse(cfg) }, step: function() {}, fault: function() {}, result: function() { return this.config.foo }}" , new ( tracers . Context ) , cfg , chainConfig )
if err != nil {
if err != nil {
t . Fatal ( err )
t . Fatal ( err )
}
}