@@ -32,7 +32,6 @@ import (
3232 "github.com/XinFinOrg/XDPoSChain/core/rawdb"
3333 "github.com/XinFinOrg/XDPoSChain/core/types"
3434 "github.com/XinFinOrg/XDPoSChain/core/vm"
35- "github.com/XinFinOrg/XDPoSChain/crypto"
3635 "github.com/XinFinOrg/XDPoSChain/eth/tracers"
3736 "github.com/XinFinOrg/XDPoSChain/params"
3837 "github.com/XinFinOrg/XDPoSChain/rlp"
@@ -259,76 +258,123 @@ func benchTracer(tracerName string, test *callTracerTest, b *testing.B) {
259258 }
260259}
261260
262- // TestZeroValueToNotExitCall tests the calltracer(s) on the following:
263- // Tx to A, A calls B with zero value. B does not already exist.
264- // Expected: that enter/exit is invoked and the inner call is shown in the result
265- func TestZeroValueToNotExitCall (t * testing.T ) {
266- var to = common .HexToAddress ("0x00000000000000000000000000000000deadbeef" )
267- privkey , err := crypto .HexToECDSA ("0000000000000000deadbeef00000000000000000000000000000000deadbeef" )
268- if err != nil {
269- t .Fatalf ("err %v" , err )
270- }
271- signer := types .NewEIP155Signer (big .NewInt (1 ))
272- tx , err := types .SignNewTx (privkey , signer , & types.LegacyTx {
273- GasPrice : big .NewInt (0 ),
274- Gas : 50000 ,
275- To : & to ,
276- })
277- if err != nil {
278- t .Fatalf ("err %v" , err )
279- }
280- origin , _ := signer .Sender (tx )
281- txContext := vm.TxContext {
282- Origin : origin ,
283- GasPrice : big .NewInt (1 ),
284- }
285- context := vm.BlockContext {
286- CanTransfer : core .CanTransfer ,
287- Transfer : core .Transfer ,
288- Coinbase : common.Address {},
289- BlockNumber : new (big.Int ).SetUint64 (8000000 ),
290- Time : new (big.Int ).SetUint64 (5 ),
291- Difficulty : big .NewInt (0x30000 ),
292- GasLimit : uint64 (6000000 ),
293- }
294- var code = []byte {
295- byte (vm .PUSH1 ), 0x0 , byte (vm .DUP1 ), byte (vm .DUP1 ), byte (vm .DUP1 ), // in and outs zero
296- byte (vm .DUP1 ), byte (vm .PUSH1 ), 0xff , byte (vm .GAS ), // value=0,address=0xff, gas=GAS
297- byte (vm .CALL ),
261+ func TestInternals (t * testing.T ) {
262+ var (
263+ to = common .HexToAddress ("0x00000000000000000000000000000000deadbeef" )
264+ origin = common .HexToAddress ("0x00000000000000000000000000000000feed" )
265+ txContext = vm.TxContext {
266+ Origin : origin ,
267+ GasPrice : big .NewInt (1 ),
268+ }
269+ context = vm.BlockContext {
270+ CanTransfer : core .CanTransfer ,
271+ Transfer : core .Transfer ,
272+ Coinbase : common.Address {},
273+ BlockNumber : new (big.Int ).SetUint64 (8000000 ),
274+ Time : new (big.Int ).SetUint64 (5 ),
275+ Difficulty : big .NewInt (0x30000 ),
276+ GasLimit : uint64 (6000000 ),
277+ }
278+ )
279+ mkTracer := func (name string , cfg json.RawMessage ) tracers.Tracer {
280+ tr , err := tracers .DefaultDirectory .New (name , nil , cfg )
281+ if err != nil {
282+ t .Fatalf ("failed to create call tracer: %v" , err )
283+ }
284+ return tr
298285 }
299- var alloc = types.GenesisAlloc {
300- to : types.Account {
301- Nonce : 1 ,
302- Code : code ,
286+
287+ for _ , tc := range []struct {
288+ name string
289+ code []byte
290+ tracer tracers.Tracer
291+ want string
292+ }{
293+ {
294+ // TestZeroValueToNotExitCall tests the calltracer(s) on the following:
295+ // Tx to A, A calls B with zero value. B does not already exist.
296+ // Expected: that enter/exit is invoked and the inner call is shown in the result
297+ name : "ZeroValueToNotExitCall" ,
298+ code : []byte {
299+ byte (vm .PUSH1 ), 0x0 , byte (vm .DUP1 ), byte (vm .DUP1 ), byte (vm .DUP1 ), // in and outs zero
300+ byte (vm .DUP1 ), byte (vm .PUSH1 ), 0xff , byte (vm .GAS ), // value=0,address=0xff, gas=GAS
301+ byte (vm .CALL ),
302+ },
303+ tracer : mkTracer ("callTracer" , nil ),
304+ want : `{"from":"0x000000000000000000000000000000000000feed","gas":"0x7148","gasUsed":"0x54d8","to":"0x00000000000000000000000000000000deadbeef","input":"0x","calls":[{"from":"0x00000000000000000000000000000000deadbeef","gas":"0x6cbf","gasUsed":"0x0","to":"0x00000000000000000000000000000000000000ff","input":"0x","value":"0x0","type":"CALL"}],"value":"0x0","type":"CALL"}` ,
303305 },
304- origin : types.Account {
305- Nonce : 0 ,
306- Balance : big .NewInt (500000000000000 ),
306+ {
307+ name : "Stack depletion in LOG0" ,
308+ code : []byte {byte (vm .LOG3 )},
309+ tracer : mkTracer ("callTracer" , json .RawMessage (`{ "withLog": true }` )),
310+ want : `{"from":"0x000000000000000000000000000000000000feed","gas":"0x7148","gasUsed":"0xc350","to":"0x00000000000000000000000000000000deadbeef","input":"0x","error":"stack underflow (0 \u003c=\u003e 5)","value":"0x0","type":"CALL"}` ,
307311 },
308- }
309- statedb := tests .MakePreState (rawdb .NewMemoryDatabase (), alloc )
310- // Create the tracer, the EVM environment and run it
311- tracer , err := tracers .DefaultDirectory .New ("callTracer" , nil , nil )
312- if err != nil {
313- t .Fatalf ("failed to create call tracer: %v" , err )
314- }
315- evm := vm .NewEVM (context , txContext , statedb , nil , params .MainnetChainConfig , vm.Config {Tracer : tracer })
316- msg , err := core .TransactionToMessage (tx , signer , nil , nil , nil )
317- if err != nil {
318- t .Fatalf ("failed to prepare transaction for tracing: %v" , err )
319- }
320- st := core .NewStateTransition (evm , msg , new (core.GasPool ).AddGas (tx .Gas ()))
321- if _ , err = st .TransitionDb (common.Address {}); err != nil {
322- t .Fatalf ("failed to execute transaction: %v" , err )
323- }
324- // Retrieve the trace result and compare against the expected.
325- res , err := tracer .GetResult ()
326- if err != nil {
327- t .Fatalf ("failed to retrieve trace result: %v" , err )
328- }
329- wantStr := `{"from":"0x682a80a6f560eec50d54e63cbeda1c324c5f8d1b","gas":"0x7148","gasUsed":"0x54d8","to":"0x00000000000000000000000000000000deadbeef","input":"0x","calls":[{"from":"0x00000000000000000000000000000000deadbeef","gas":"0x6cbf","gasUsed":"0x0","to":"0x00000000000000000000000000000000000000ff","input":"0x","value":"0x0","type":"CALL"}],"value":"0x0","type":"CALL"}`
330- if string (res ) != wantStr {
331- t .Fatalf ("trace mismatch\n have: %v\n want: %v\n " , string (res ), wantStr )
312+ {
313+ name : "Mem expansion in LOG0" ,
314+ code : []byte {
315+ byte (vm .PUSH1 ), 0x1 ,
316+ byte (vm .PUSH1 ), 0x0 ,
317+ byte (vm .MSTORE ),
318+ byte (vm .PUSH1 ), 0xff ,
319+ byte (vm .PUSH1 ), 0x0 ,
320+ byte (vm .LOG0 ),
321+ },
322+ tracer : mkTracer ("callTracer" , json .RawMessage (`{ "withLog": true }` )),
323+ want : `{"from":"0x000000000000000000000000000000000000feed","gas":"0x7148","gasUsed":"0x5b9e","to":"0x00000000000000000000000000000000deadbeef","input":"0x","logs":[{"address":"0x00000000000000000000000000000000deadbeef","topics":[],"data":"0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}],"value":"0x0","type":"CALL"}` ,
324+ },
325+ // TODO(daniel): make this test case pass, ref: PR #26848
326+ // {
327+ // // Leads to OOM on the prestate tracer
328+ // name: "Prestate-tracer - mem expansion in CREATE2",
329+ // code: []byte{
330+ // byte(vm.PUSH1), 0x1,
331+ // byte(vm.PUSH1), 0x0,
332+ // byte(vm.MSTORE),
333+ // byte(vm.PUSH1), 0x1,
334+ // byte(vm.PUSH5), 0xff, 0xff, 0xff, 0xff, 0xff,
335+ // byte(vm.PUSH1), 0x1,
336+ // byte(vm.PUSH1), 0x0,
337+ // byte(vm.CREATE2),
338+ // byte(vm.PUSH1), 0xff,
339+ // byte(vm.PUSH1), 0x0,
340+ // byte(vm.LOG0),
341+ // },
342+ // tracer: mkTracer("prestateTracer", json.RawMessage(`{ "withLog": true }`)),
343+ // want: `{"0x0000000000000000000000000000000000000000":{"balance":"0x0"},"0x000000000000000000000000000000000000feed":{"balance":"0x1c6bf52640350"},"0x00000000000000000000000000000000deadbeef":{"balance":"0x0","code":"0x6001600052600164ffffffffff60016000f560ff6000a0"}}`,
344+ // },
345+ } {
346+ statedb := tests .MakePreState (rawdb .NewMemoryDatabase (),
347+ types.GenesisAlloc {
348+ to : types.Account {
349+ Code : tc .code ,
350+ },
351+ origin : types.Account {
352+ Balance : big .NewInt (500000000000000 ),
353+ },
354+ })
355+ evm := vm .NewEVM (context , txContext , statedb , nil , params .MainnetChainConfig , vm.Config {Tracer : tc .tracer })
356+ msg := & core.Message {
357+ To : & to ,
358+ From : origin ,
359+ Value : big .NewInt (0 ),
360+ GasLimit : 50000 ,
361+ GasPrice : big .NewInt (0 ),
362+ GasFeeCap : big .NewInt (0 ),
363+ GasTipCap : big .NewInt (0 ),
364+ SkipAccountChecks : false ,
365+ }
366+ st := core .NewStateTransition (evm , msg , new (core.GasPool ).AddGas (msg .GasLimit ))
367+ if _ , err := st .TransitionDb (common.Address {}); err != nil {
368+ t .Fatalf ("test %v: failed to execute transaction: %v" , tc .name , err )
369+ }
370+ // Retrieve the trace result and compare against the expected
371+ res , err := tc .tracer .GetResult ()
372+ if err != nil {
373+ t .Fatalf ("test %v: failed to retrieve trace result: %v" , tc .name , err )
374+ }
375+ if string (res ) != tc .want {
376+ t .Fatalf ("test %v: trace mismatch\n have: %v\n want: %v\n " , tc .name , string (res ), tc .want )
377+ }
332378 }
333379}
334380
0 commit comments