21
21
package tracers
22
22
23
23
import (
24
+ "crypto/ecdsa"
25
+ "crypto/rand"
24
26
"encoding/json"
25
27
"github.com/klaytn/klaytn/blockchain"
26
28
"github.com/klaytn/klaytn/blockchain/types"
@@ -29,6 +31,7 @@ import (
29
31
"github.com/klaytn/klaytn/common/hexutil"
30
32
"github.com/klaytn/klaytn/common/math"
31
33
"github.com/klaytn/klaytn/crypto"
34
+ "github.com/klaytn/klaytn/params"
32
35
"github.com/klaytn/klaytn/ser/rlp"
33
36
"github.com/klaytn/klaytn/storage/database"
34
37
"github.com/klaytn/klaytn/tests"
@@ -126,6 +129,82 @@ type callTracerTest struct {
126
129
Result * callTrace `json:"result"`
127
130
}
128
131
132
+ func TestPrestateTracerCreate2 (t * testing.T ) {
133
+ unsigned_tx := types .NewTransaction (1 , common .HexToAddress ("0x00000000000000000000000000000000deadbeef" ),
134
+ new (big.Int ), 5000000 , big .NewInt (1 ), []byte {})
135
+
136
+ privateKeyECDSA , err := ecdsa .GenerateKey (crypto .S256 (), rand .Reader )
137
+ if err != nil {
138
+ t .Fatalf ("err %v" , err )
139
+ }
140
+ signer := types .NewEIP155Signer (big .NewInt (1 ))
141
+ tx , err := types .SignTx (unsigned_tx , signer , privateKeyECDSA )
142
+ if err != nil {
143
+ t .Fatalf ("err %v" , err )
144
+ }
145
+ /**
146
+ This comes from one of the test-vectors on the Skinny Create2 - EIP
147
+ address 0x00000000000000000000000000000000deadbeef
148
+ salt 0x00000000000000000000000000000000000000000000000000000000cafebabe
149
+ init_code 0xdeadbeef
150
+ gas (assuming no mem expansion): 32006
151
+ result: 0x60f3f640a8508fC6a86d45DF051962668E1e8AC7
152
+ */
153
+ origin , _ := signer .Sender (tx )
154
+ context := vm.Context {
155
+ CanTransfer : blockchain .CanTransfer ,
156
+ Transfer : blockchain .Transfer ,
157
+ Origin : origin ,
158
+ Coinbase : common.Address {},
159
+ BlockNumber : new (big.Int ).SetUint64 (8000000 ),
160
+ Time : new (big.Int ).SetUint64 (5 ),
161
+ BlockScore : big .NewInt (0x30000 ),
162
+ GasLimit : uint64 (6000000 ),
163
+ GasPrice : big .NewInt (1 ),
164
+ }
165
+ alloc := blockchain.GenesisAlloc {}
166
+ // The code pushes 'deadbeef' into memory, then the other params, and calls CREATE2, then returns
167
+ // the address
168
+ alloc [common .HexToAddress ("0x00000000000000000000000000000000deadbeef" )] = blockchain.GenesisAccount {
169
+ Nonce : 1 ,
170
+ Code : hexutil .MustDecode ("0x63deadbeef60005263cafebabe6004601c6000F560005260206000F3" ),
171
+ Balance : big .NewInt (1 ),
172
+ }
173
+ alloc [origin ] = blockchain.GenesisAccount {
174
+ Nonce : 1 ,
175
+ Code : []byte {},
176
+ Balance : big .NewInt (500000000000000 ),
177
+ }
178
+ statedb := tests .MakePreState (database .NewMemoryDBManager (), alloc )
179
+ // Create the tracer, the EVM environment and run it
180
+ tracer , err := New ("prestateTracer" )
181
+ if err != nil {
182
+ t .Fatalf ("failed to create call tracer: %v" , err )
183
+ }
184
+ evm := vm .NewEVM (context , statedb , params .MainnetChainConfig , & vm.Config {Debug : true , Tracer : tracer })
185
+
186
+ msg , err := tx .AsMessageWithAccountKeyPicker (signer , statedb , context .BlockNumber .Uint64 ())
187
+ if err != nil {
188
+ t .Fatalf ("failed to prepare transaction for tracing: %v" , err )
189
+ }
190
+ st := blockchain .NewStateTransition (evm , msg )
191
+ if _ , _ , kerr := st .TransitionDb (); kerr .ErrTxInvalid != nil {
192
+ t .Fatalf ("failed to execute transaction: %v" , kerr .ErrTxInvalid )
193
+ }
194
+ // Retrieve the trace result and compare against the etalon
195
+ res , err := tracer .GetResult ()
196
+ if err != nil {
197
+ t .Fatalf ("failed to retrieve trace result: %v" , err )
198
+ }
199
+ ret := make (map [string ]interface {})
200
+ if err := json .Unmarshal (res , & ret ); err != nil {
201
+ t .Fatalf ("failed to unmarshal trace result: %v" , err )
202
+ }
203
+ if _ , has := ret ["0x60f3f640a8508fc6a86d45df051962668e1e8ac7" ]; ! has {
204
+ t .Fatalf ("Expected 0x60f3f640a8508fc6a86d45df051962668e1e8ac7 in result" )
205
+ }
206
+ }
207
+
129
208
// Iterates over all the input-output datasets in the tracer test harness and
130
209
// runs the JavaScript tracers against them.
131
210
func TestCallTracer (t * testing.T ) {
@@ -221,7 +300,7 @@ func TestCallTracer(t *testing.T) {
221
300
t .Fatalf ("failed to unmarshal trace result: %v" , err )
222
301
}
223
302
if ! reflect .DeepEqual (ret , test .Result ) {
224
- t .Fatalf ("trace mismatch: have %+v, want %+v" , ret , test .Result )
303
+ t .Fatalf ("trace mismatch: \n have %+v, \n want %+v" , ret , test .Result )
225
304
}
226
305
})
227
306
}
0 commit comments