1717package tracers
1818
1919import (
20- "bytes"
2120 "encoding/json"
2221 "errors"
2322 "math/big"
@@ -55,16 +54,17 @@ type vmContext struct {
5554 txContext vm.TxContext
5655}
5756
58- func runTrace (tracer Tracer , blockNumber * big.Int , chaincfg * params.ChainConfig ) (json.RawMessage , error ) {
57+ func testCtx () * vmContext {
58+ return & vmContext {ctx : vm.BlockContext {BlockNumber : big .NewInt (1 )}, txContext : vm.TxContext {GasPrice : big .NewInt (100000 )}}
59+ }
60+
61+ func runTrace (tracer Tracer , vmctx * vmContext , chaincfg * params.ChainConfig ) (json.RawMessage , error ) {
62+ env := vm .NewEVM (vmctx .ctx , vmctx .txContext , & dummyStatedb {}, nil , chaincfg , vm.Config {Tracer : tracer })
5963 var (
60- startGas uint64 = 10000
61- value = big .NewInt (0 )
62- ctx = vm.BlockContext {BlockNumber : blockNumber }
63- txContext = vm.TxContext {GasPrice : big .NewInt (100000 )}
64+ startGas uint64 = 10000
65+ value = big .NewInt (0 )
6466 )
6567
66- env := vm .NewEVM (ctx , txContext , & dummyStatedb {}, nil , chaincfg , vm.Config {Tracer : tracer })
67-
6868 contract := vm .NewContract (account {}, account {}, value , startGas )
6969 contract .Code = []byte {byte (vm .PUSH1 ), 0x1 , byte (vm .PUSH1 ), 0x1 , 0x0 }
7070
@@ -80,11 +80,12 @@ func runTrace(tracer Tracer, blockNumber *big.Int, chaincfg *params.ChainConfig)
8080func TestTracer (t * testing.T ) {
8181 execTracer := func (code string ) ([]byte , string ) {
8282 t .Helper ()
83- tracer , err := New (code , new (Context ), nil )
83+ ctx := & vmContext {ctx : vm.BlockContext {BlockNumber : big .NewInt (1 )}, txContext : vm.TxContext {GasPrice : big .NewInt (100000 )}}
84+ tracer , err := New (code , ctx .txContext , new (Context ), nil )
8485 if err != nil {
8586 t .Fatal (err )
8687 }
87- ret , err := runTrace (tracer , big . NewInt ( 1 ) , params .TestChainConfig )
88+ ret , err := runTrace (tracer , ctx , params .TestChainConfig )
8889 if err != nil {
8990 return nil , err .Error () // Stringify to allow comparison without nil checks
9091 }
@@ -131,21 +132,23 @@ func TestHalt(t *testing.T) {
131132 t .Skip ("duktape doesn't support abortion" )
132133
133134 timeout := errors .New ("stahp" )
134- tracer , err := New ("{step: function() { while(1); }, result: function() { return null; }}" , new (Context ), nil )
135+ vmctx := testCtx ()
136+ tracer , err := New ("{step: function() { while(1); }, result: function() { return null; }}" , vmctx .txContext , new (Context ), nil )
135137 if err != nil {
136138 t .Fatal (err )
137139 }
138140 go func () {
139141 time .Sleep (1 * time .Second )
140142 tracer .Stop (timeout )
141143 }()
142- if _ , err = runTrace (tracer , big . NewInt ( 1 ) , params .TestChainConfig ); err .Error () != "stahp in server-side tracer function 'step'" {
144+ if _ , err = runTrace (tracer , vmctx , params .TestChainConfig ); err .Error () != "stahp in server-side tracer function 'step'" {
143145 t .Errorf ("Expected timeout error, got %v" , err )
144146 }
145147}
146148
147149func TestHaltBetweenSteps (t * testing.T ) {
148- tracer , err := New ("{step: function() {}, fault: function() {}, result: function() { return null; }}" , new (Context ), nil )
150+ vmctx := testCtx ()
151+ tracer , err := New ("{step: function() {}, fault: function() {}, result: function() { return null; }}" , vmctx .txContext , new (Context ), nil )
149152 if err != nil {
150153 t .Fatal (err )
151154 }
@@ -166,23 +169,18 @@ func TestHaltBetweenSteps(t *testing.T) {
166169// TestNoStepExec tests a regular value transfer (no exec), and accessing the statedb
167170// in 'result'
168171func TestNoStepExec (t * testing.T ) {
169- runEmptyTrace := func (tracer Tracer ) (json.RawMessage , error ) {
170- ctx := vm.BlockContext {BlockNumber : big .NewInt (1 )}
171- txContext := vm.TxContext {GasPrice : big .NewInt (100000 )}
172- env := vm .NewEVM (ctx , txContext , & dummyStatedb {}, nil , params .TestChainConfig , vm.Config {Tracer : tracer })
173- startGas := uint64 (10000 )
174- contract := vm .NewContract (account {}, account {}, big .NewInt (0 ), startGas )
175- tracer .CaptureStart (env , contract .Caller (), contract .Address (), false , []byte {}, startGas , big .NewInt (0 ))
176- tracer .CaptureEnd (nil , startGas - contract .Gas , 1 , nil )
177- return tracer .GetResult ()
178- }
179172 execTracer := func (code string ) []byte {
180173 t .Helper ()
181- tracer , err := New (code , new (Context ), nil )
174+ txContext := vm.TxContext {GasPrice : big .NewInt (100000 )}
175+ tracer , err := New (code , txContext , new (Context ), nil )
182176 if err != nil {
183177 t .Fatal (err )
184178 }
185- ret , err := runEmptyTrace (tracer )
179+ ctx := vm.BlockContext {BlockNumber : big .NewInt (1 )}
180+ env := vm .NewEVM (ctx , txContext , & dummyStatedb {}, nil , params .TestChainConfig , vm.Config {Tracer : tracer })
181+ tracer .CaptureStart (env , common.Address {}, common.Address {}, false , []byte {}, 1000 , big .NewInt (0 ))
182+ tracer .CaptureEnd (nil , 0 , 1 , nil )
183+ ret , err := tracer .GetResult ()
186184 if err != nil {
187185 t .Fatal (err )
188186 }
@@ -224,20 +222,25 @@ func TestIsPrecompile(t *testing.T) {
224222 chaincfg .ByzantiumBlock = big .NewInt (100 )
225223 chaincfg .IstanbulBlock = big .NewInt (200 )
226224 chaincfg .BerlinBlock = big .NewInt (300 )
227- tracer , err := New ("{addr: toAddress('0000000000000000000000000000000000000009'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}" , new (Context ), nil )
225+ txCtx := vm.TxContext {GasPrice : big .NewInt (100000 )}
226+
227+ tracer , err := New ("{addr: toAddress('0000000000000000000000000000000000000009'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}" , txCtx , new (Context ), nil )
228228 if err != nil {
229229 t .Fatal (err )
230230 }
231- res , err := runTrace (tracer , big .NewInt (150 ), chaincfg )
231+
232+ blockCtx := vm.BlockContext {BlockNumber : big .NewInt (150 )}
233+ res , err := runTrace (tracer , & vmContext {blockCtx , txCtx }, chaincfg )
232234 if err != nil {
233235 t .Error (err )
234236 }
235237 if string (res ) != "false" {
236238 t .Errorf ("Tracer should not consider blake2f as precompile in byzantium" )
237239 }
238240
239- tracer , _ = New ("{addr: toAddress('0000000000000000000000000000000000000009'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}" , new (Context ), nil )
240- res , err = runTrace (tracer , big .NewInt (250 ), chaincfg )
241+ blockCtx = vm.BlockContext {BlockNumber : big .NewInt (250 )}
242+ tracer , _ = New ("{addr: toAddress('0000000000000000000000000000000000000009'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}" , txCtx , new (Context ), nil )
243+ res , err = runTrace (tracer , & vmContext {blockCtx , txCtx }, chaincfg )
241244 if err != nil {
242245 t .Error (err )
243246 }
@@ -247,16 +250,18 @@ func TestIsPrecompile(t *testing.T) {
247250}
248251
249252func TestEnterExit (t * testing.T ) {
253+ txCtx := vm.TxContext {GasPrice : big .NewInt (100000 )}
254+
250255 // test that either both or none of enter() and exit() are defined
251- if _ , err := New ("{step: function() {}, fault: function() {}, result: function() { return null; }, enter: function() {}}" , new (Context ), nil ); err == nil {
256+ if _ , err := New ("{step: function() {}, fault: function() {}, result: function() { return null; }, enter: function() {}}" , txCtx , new (Context ), nil ); err == nil {
252257 t .Fatal ("tracer creation should've failed without exit() definition" )
253258 }
254- if _ , err := New ("{step: function() {}, fault: function() {}, result: function() { return null; }, enter: function() {}, exit: function() {}}" , new (Context ), nil ); err != nil {
259+ if _ , err := New ("{step: function() {}, fault: function() {}, result: function() { return null; }, enter: function() {}, exit: function() {}}" , txCtx , new (Context ), nil ); err != nil {
255260 t .Fatal (err )
256261 }
257262
258263 // test that the enter and exit method are correctly invoked and the values passed
259- tracer , err := New ("{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 (Context ), nil )
264+ tracer , err := New ("{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(); }}" , txCtx , new (Context ), nil )
260265 if err != nil {
261266 t .Fatal (err )
262267 }
@@ -277,81 +282,3 @@ func TestEnterExit(t *testing.T) {
277282 t .Errorf ("Number of invocations of enter() and exit() is wrong. Have %s, want %s\n " , have , want )
278283 }
279284}
280-
281- // TestRegressionPanicSlice tests that we don't panic on bad arguments to memory access
282- func TestRegressionPanicSlice (t * testing.T ) {
283- tracer , err := New ("{depths: [], step: function(log) { this.depths.push(log.memory.slice(-1,-2)); }, fault: function() {}, result: function() { return this.depths; }}" , new (Context ), nil )
284- if err != nil {
285- t .Fatal (err )
286- }
287- if _ , err = runTrace (tracer , big .NewInt (1 ), params .TestChainConfig ); err != nil {
288- t .Fatal (err )
289- }
290- }
291-
292- // TestRegressionPanicPeek tests that we don't panic on bad arguments to stack peeks
293- func TestRegressionPanicPeek (t * testing.T ) {
294- tracer , err := New ("{depths: [], step: function(log) { this.depths.push(log.stack.peek(-1)); }, fault: function() {}, result: function() { return this.depths; }}" , new (Context ), nil )
295- if err != nil {
296- t .Fatal (err )
297- }
298- if _ , err = runTrace (tracer , big .NewInt (1 ), params .TestChainConfig ); err != nil {
299- t .Fatal (err )
300- }
301- }
302-
303- // TestRegressionPanicGetUint tests that we don't panic on bad arguments to memory getUint
304- func TestRegressionPanicGetUint (t * testing.T ) {
305- tracer , err := New ("{ depths: [], step: function(log, db) { this.depths.push(log.memory.getUint(-64));}, fault: function() {}, result: function() { return this.depths; }}" , new (Context ), nil )
306- if err != nil {
307- t .Fatal (err )
308- }
309- if _ , err = runTrace (tracer , big .NewInt (1 ), params .TestChainConfig ); err != nil {
310- t .Fatal (err )
311- }
312- }
313-
314- func TestTracing (t * testing.T ) {
315- tracer , err := New ("{count: 0, step: function() { this.count += 1; }, fault: function() {}, result: function() { return this.count; }}" , new (Context ), nil )
316- if err != nil {
317- t .Fatal (err )
318- }
319-
320- ret , err := runTrace (tracer , big .NewInt (1 ), params .TestChainConfig )
321- if err != nil {
322- t .Fatal (err )
323- }
324- if ! bytes .Equal (ret , []byte ("3" )) {
325- t .Errorf ("Expected return value to be 3, got %s" , string (ret ))
326- }
327- }
328-
329- func TestStack (t * testing.T ) {
330- tracer , err := New ("{depths: [], step: function(log) { this.depths.push(log.stack.length()); }, fault: function() {}, result: function() { return this.depths; }}" , new (Context ), nil )
331- if err != nil {
332- t .Fatal (err )
333- }
334-
335- ret , err := runTrace (tracer , big .NewInt (1 ), params .TestChainConfig )
336- if err != nil {
337- t .Fatal (err )
338- }
339- if ! bytes .Equal (ret , []byte ("[0,1,2]" )) {
340- t .Errorf ("Expected return value to be [0,1,2], got %s" , string (ret ))
341- }
342- }
343-
344- func TestOpcodes (t * testing.T ) {
345- tracer , err := New ("{opcodes: [], step: function(log) { this.opcodes.push(log.op.toString()); }, fault: function() {}, result: function() { return this.opcodes; }}" , new (Context ), nil )
346- if err != nil {
347- t .Fatal (err )
348- }
349-
350- ret , err := runTrace (tracer , big .NewInt (1 ), params .TestChainConfig )
351- if err != nil {
352- t .Fatal (err )
353- }
354- if ! bytes .Equal (ret , []byte ("[\" PUSH1\" ,\" PUSH1\" ,\" STOP\" ]" )) {
355- t .Errorf ("Expected return value to be [\" PUSH1\" ,\" PUSH1\" ,\" STOP\" ], got %s" , string (ret ))
356- }
357- }
0 commit comments