@@ -120,6 +120,85 @@ type callTracerTest struct {
120120 Result * callTrace `json:"result"`
121121}
122122
123+ // TestZeroValueToNotExitCall tests the calltracer(s) on the following:
124+ // Tx to A, A calls B with zero value. B does not already exist.
125+ // Expected: that enter/exit is invoked and the inner call is shown in the result
126+ func TestZeroValueToNotExitCall (t * testing.T ) {
127+ var to = common .HexToAddress ("0x00000000000000000000000000000000deadbeef" )
128+ privkey , err := crypto .HexToECDSA ("0000000000000000deadbeef00000000000000000000000000000000deadbeef" )
129+ if err != nil {
130+ t .Fatalf ("err %v" , err )
131+ }
132+ signer := types .NewEIP155Signer (big .NewInt (1 ))
133+ tx , err := types .SignNewTx (privkey , signer , & types.LegacyTx {
134+ GasPrice : big .NewInt (0 ),
135+ Gas : 50000 ,
136+ To : & to ,
137+ })
138+ if err != nil {
139+ t .Fatalf ("err %v" , err )
140+ }
141+ origin , _ := signer .Sender (tx )
142+ txContext := vm.TxContext {
143+ Origin : origin ,
144+ GasPrice : big .NewInt (1 ),
145+ }
146+ context := vm.BlockContext {
147+ CanTransfer : core .CanTransfer ,
148+ Transfer : core .Transfer ,
149+ Coinbase : common.Address {},
150+ BlockNumber : new (big.Int ).SetUint64 (8000000 ),
151+ Time : new (big.Int ).SetUint64 (5 ),
152+ Difficulty : big .NewInt (0x30000 ),
153+ GasLimit : uint64 (6000000 ),
154+ }
155+ var code = []byte {
156+ byte (vm .PUSH1 ), 0x0 , byte (vm .DUP1 ), byte (vm .DUP1 ), byte (vm .DUP1 ), // in and outs zero
157+ byte (vm .DUP1 ), byte (vm .PUSH1 ), 0xff , byte (vm .GAS ), // value=0,address=0xff, gas=GAS
158+ byte (vm .CALL ),
159+ }
160+ var alloc = core.GenesisAlloc {
161+ to : core.GenesisAccount {
162+ Nonce : 1 ,
163+ Code : code ,
164+ },
165+ origin : core.GenesisAccount {
166+ Nonce : 0 ,
167+ Balance : big .NewInt (500000000000000 ),
168+ },
169+ }
170+ _ , statedb := tests .MakePreState (rawdb .NewMemoryDatabase (), alloc , false )
171+ // Create the tracer, the EVM environment and run it
172+ tracer , err := New ("callTracer" , new (Context ))
173+ if err != nil {
174+ t .Fatalf ("failed to create call tracer: %v" , err )
175+ }
176+ evm := vm .NewEVM (context , txContext , statedb , params .MainnetChainConfig , vm.Config {Debug : true , Tracer : tracer })
177+ msg , err := tx .AsMessage (signer , nil )
178+ if err != nil {
179+ t .Fatalf ("failed to prepare transaction for tracing: %v" , err )
180+ }
181+ st := core .NewStateTransition (evm , msg , new (core.GasPool ).AddGas (tx .Gas ()))
182+ if _ , err = st .TransitionDb (); err != nil {
183+ t .Fatalf ("failed to execute transaction: %v" , err )
184+ }
185+ // Retrieve the trace result and compare against the etalon
186+ res , err := tracer .GetResult ()
187+ if err != nil {
188+ t .Fatalf ("failed to retrieve trace result: %v" , err )
189+ }
190+ have := new (callTrace )
191+ if err := json .Unmarshal (res , have ); err != nil {
192+ t .Fatalf ("failed to unmarshal trace result: %v" , err )
193+ }
194+ wantStr := `{"type":"CALL","from":"0x682a80a6f560eec50d54e63cbeda1c324c5f8d1b","to":"0x00000000000000000000000000000000deadbeef","value":"0x0","gas":"0x7148","gasUsed":"0x2d0","input":"0x","output":"0x","calls":[{"type":"CALL","from":"0x00000000000000000000000000000000deadbeef","to":"0x00000000000000000000000000000000000000ff","value":"0x0","gas":"0x6cbf","gasUsed":"0x0","input":"0x","output":"0x"}]}`
195+ want := new (callTrace )
196+ json .Unmarshal ([]byte (wantStr ), want )
197+ if ! jsonEqual (have , want ) {
198+ t .Error ("have != want" )
199+ }
200+ }
201+
123202func TestPrestateTracerCreate2 (t * testing.T ) {
124203 unsignedTx := types .NewTransaction (1 , common .HexToAddress ("0x00000000000000000000000000000000deadbeef" ),
125204 new (big.Int ), 5000000 , big .NewInt (1 ), []byte {})
0 commit comments