1// Copyright 2017 The go-ethereum Authors
2// This file is part of the go-ethereum library.
3//
4// The go-ethereum library is free software: you can redistribute it and/or modify
5// it under the terms of the GNU Lesser General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// The go-ethereum library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU Lesser General Public License for more details.
13//
14// You should have received a copy of the GNU Lesser General Public License
15// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
16
17package vm
18
19import (
20	"bytes"
21	"encoding/json"
22	"fmt"
23	"io/ioutil"
24	"testing"
25
26	"github.com/ethereum/go-ethereum/common"
27	"github.com/ethereum/go-ethereum/crypto"
28	"github.com/ethereum/go-ethereum/params"
29	"github.com/holiman/uint256"
30)
31
32type TwoOperandTestcase struct {
33	X        string
34	Y        string
35	Expected string
36}
37
38type twoOperandParams struct {
39	x string
40	y string
41}
42
43var alphabetSoup = "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
44var commonParams []*twoOperandParams
45var twoOpMethods map[string]executionFunc
46
47func init() {
48
49	// Params is a list of common edgecases that should be used for some common tests
50	params := []string{
51		"0000000000000000000000000000000000000000000000000000000000000000", // 0
52		"0000000000000000000000000000000000000000000000000000000000000001", // +1
53		"0000000000000000000000000000000000000000000000000000000000000005", // +5
54		"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe", // + max -1
55		"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", // + max
56		"8000000000000000000000000000000000000000000000000000000000000000", // - max
57		"8000000000000000000000000000000000000000000000000000000000000001", // - max+1
58		"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb", // - 5
59		"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", // - 1
60	}
61	// Params are combined so each param is used on each 'side'
62	commonParams = make([]*twoOperandParams, len(params)*len(params))
63	for i, x := range params {
64		for j, y := range params {
65			commonParams[i*len(params)+j] = &twoOperandParams{x, y}
66		}
67	}
68	twoOpMethods = map[string]executionFunc{
69		"add":     opAdd,
70		"sub":     opSub,
71		"mul":     opMul,
72		"div":     opDiv,
73		"sdiv":    opSdiv,
74		"mod":     opMod,
75		"smod":    opSmod,
76		"exp":     opExp,
77		"signext": opSignExtend,
78		"lt":      opLt,
79		"gt":      opGt,
80		"slt":     opSlt,
81		"sgt":     opSgt,
82		"eq":      opEq,
83		"and":     opAnd,
84		"or":      opOr,
85		"xor":     opXor,
86		"byte":    opByte,
87		"shl":     opSHL,
88		"shr":     opSHR,
89		"sar":     opSAR,
90	}
91}
92
93func testTwoOperandOp(t *testing.T, tests []TwoOperandTestcase, opFn executionFunc, name string) {
94
95	var (
96		env            = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
97		stack          = newstack()
98		pc             = uint64(0)
99		evmInterpreter = env.interpreter
100	)
101
102	for i, test := range tests {
103		x := new(uint256.Int).SetBytes(common.Hex2Bytes(test.X))
104		y := new(uint256.Int).SetBytes(common.Hex2Bytes(test.Y))
105		expected := new(uint256.Int).SetBytes(common.Hex2Bytes(test.Expected))
106		stack.push(x)
107		stack.push(y)
108		opFn(&pc, evmInterpreter, &ScopeContext{nil, stack, nil})
109		if len(stack.data) != 1 {
110			t.Errorf("Expected one item on stack after %v, got %d: ", name, len(stack.data))
111		}
112		actual := stack.pop()
113
114		if actual.Cmp(expected) != 0 {
115			t.Errorf("Testcase %v %d, %v(%x, %x): expected  %x, got %x", name, i, name, x, y, expected, actual)
116		}
117	}
118}
119
120func TestByteOp(t *testing.T) {
121	tests := []TwoOperandTestcase{
122		{"ABCDEF0908070605040302010000000000000000000000000000000000000000", "00", "AB"},
123		{"ABCDEF0908070605040302010000000000000000000000000000000000000000", "01", "CD"},
124		{"00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff", "00", "00"},
125		{"00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff", "01", "CD"},
126		{"0000000000000000000000000000000000000000000000000000000000102030", "1F", "30"},
127		{"0000000000000000000000000000000000000000000000000000000000102030", "1E", "20"},
128		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "20", "00"},
129		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "FFFFFFFFFFFFFFFF", "00"},
130	}
131	testTwoOperandOp(t, tests, opByte, "byte")
132}
133
134func TestSHL(t *testing.T) {
135	// Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#shl-shift-left
136	tests := []TwoOperandTestcase{
137		{"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000002"},
138		{"0000000000000000000000000000000000000000000000000000000000000001", "ff", "8000000000000000000000000000000000000000000000000000000000000000"},
139		{"0000000000000000000000000000000000000000000000000000000000000001", "0100", "0000000000000000000000000000000000000000000000000000000000000000"},
140		{"0000000000000000000000000000000000000000000000000000000000000001", "0101", "0000000000000000000000000000000000000000000000000000000000000000"},
141		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "00", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},
142		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "01", "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},
143		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ff", "8000000000000000000000000000000000000000000000000000000000000000"},
144		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0100", "0000000000000000000000000000000000000000000000000000000000000000"},
145		{"0000000000000000000000000000000000000000000000000000000000000000", "01", "0000000000000000000000000000000000000000000000000000000000000000"},
146		{"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "01", "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},
147	}
148	testTwoOperandOp(t, tests, opSHL, "shl")
149}
150
151func TestSHR(t *testing.T) {
152	// Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#shr-logical-shift-right
153	tests := []TwoOperandTestcase{
154		{"0000000000000000000000000000000000000000000000000000000000000001", "00", "0000000000000000000000000000000000000000000000000000000000000001"},
155		{"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000000"},
156		{"8000000000000000000000000000000000000000000000000000000000000000", "01", "4000000000000000000000000000000000000000000000000000000000000000"},
157		{"8000000000000000000000000000000000000000000000000000000000000000", "ff", "0000000000000000000000000000000000000000000000000000000000000001"},
158		{"8000000000000000000000000000000000000000000000000000000000000000", "0100", "0000000000000000000000000000000000000000000000000000000000000000"},
159		{"8000000000000000000000000000000000000000000000000000000000000000", "0101", "0000000000000000000000000000000000000000000000000000000000000000"},
160		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "00", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},
161		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "01", "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},
162		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ff", "0000000000000000000000000000000000000000000000000000000000000001"},
163		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0100", "0000000000000000000000000000000000000000000000000000000000000000"},
164		{"0000000000000000000000000000000000000000000000000000000000000000", "01", "0000000000000000000000000000000000000000000000000000000000000000"},
165	}
166	testTwoOperandOp(t, tests, opSHR, "shr")
167}
168
169func TestSAR(t *testing.T) {
170	// Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#sar-arithmetic-shift-right
171	tests := []TwoOperandTestcase{
172		{"0000000000000000000000000000000000000000000000000000000000000001", "00", "0000000000000000000000000000000000000000000000000000000000000001"},
173		{"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000000"},
174		{"8000000000000000000000000000000000000000000000000000000000000000", "01", "c000000000000000000000000000000000000000000000000000000000000000"},
175		{"8000000000000000000000000000000000000000000000000000000000000000", "ff", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},
176		{"8000000000000000000000000000000000000000000000000000000000000000", "0100", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},
177		{"8000000000000000000000000000000000000000000000000000000000000000", "0101", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},
178		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "00", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},
179		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "01", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},
180		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ff", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},
181		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0100", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},
182		{"0000000000000000000000000000000000000000000000000000000000000000", "01", "0000000000000000000000000000000000000000000000000000000000000000"},
183		{"4000000000000000000000000000000000000000000000000000000000000000", "fe", "0000000000000000000000000000000000000000000000000000000000000001"},
184		{"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "f8", "000000000000000000000000000000000000000000000000000000000000007f"},
185		{"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "fe", "0000000000000000000000000000000000000000000000000000000000000001"},
186		{"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ff", "0000000000000000000000000000000000000000000000000000000000000000"},
187		{"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0100", "0000000000000000000000000000000000000000000000000000000000000000"},
188	}
189
190	testTwoOperandOp(t, tests, opSAR, "sar")
191}
192
193func TestAddMod(t *testing.T) {
194	var (
195		env            = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
196		stack          = newstack()
197		evmInterpreter = NewEVMInterpreter(env, env.Config)
198		pc             = uint64(0)
199	)
200	tests := []struct {
201		x        string
202		y        string
203		z        string
204		expected string
205	}{
206		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
207			"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe",
208			"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
209			"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe",
210		},
211	}
212	// x + y = 0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd
213	// in 256 bit repr, fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd
214
215	for i, test := range tests {
216		x := new(uint256.Int).SetBytes(common.Hex2Bytes(test.x))
217		y := new(uint256.Int).SetBytes(common.Hex2Bytes(test.y))
218		z := new(uint256.Int).SetBytes(common.Hex2Bytes(test.z))
219		expected := new(uint256.Int).SetBytes(common.Hex2Bytes(test.expected))
220		stack.push(z)
221		stack.push(y)
222		stack.push(x)
223		opAddmod(&pc, evmInterpreter, &ScopeContext{nil, stack, nil})
224		actual := stack.pop()
225		if actual.Cmp(expected) != 0 {
226			t.Errorf("Testcase %d, expected  %x, got %x", i, expected, actual)
227		}
228	}
229}
230
231// getResult is a convenience function to generate the expected values
232func getResult(args []*twoOperandParams, opFn executionFunc) []TwoOperandTestcase {
233	var (
234		env         = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
235		stack       = newstack()
236		pc          = uint64(0)
237		interpreter = env.interpreter
238	)
239	result := make([]TwoOperandTestcase, len(args))
240	for i, param := range args {
241		x := new(uint256.Int).SetBytes(common.Hex2Bytes(param.x))
242		y := new(uint256.Int).SetBytes(common.Hex2Bytes(param.y))
243		stack.push(x)
244		stack.push(y)
245		opFn(&pc, interpreter, &ScopeContext{nil, stack, nil})
246		actual := stack.pop()
247		result[i] = TwoOperandTestcase{param.x, param.y, fmt.Sprintf("%064x", actual)}
248	}
249	return result
250}
251
252// utility function to fill the json-file with testcases
253// Enable this test to generate the 'testcases_xx.json' files
254func TestWriteExpectedValues(t *testing.T) {
255	t.Skip("Enable this test to create json test cases.")
256
257	for name, method := range twoOpMethods {
258		data, err := json.Marshal(getResult(commonParams, method))
259		if err != nil {
260			t.Fatal(err)
261		}
262		_ = ioutil.WriteFile(fmt.Sprintf("testdata/testcases_%v.json", name), data, 0644)
263		if err != nil {
264			t.Fatal(err)
265		}
266	}
267}
268
269// TestJsonTestcases runs through all the testcases defined as json-files
270func TestJsonTestcases(t *testing.T) {
271	for name := range twoOpMethods {
272		data, err := ioutil.ReadFile(fmt.Sprintf("testdata/testcases_%v.json", name))
273		if err != nil {
274			t.Fatal("Failed to read file", err)
275		}
276		var testcases []TwoOperandTestcase
277		json.Unmarshal(data, &testcases)
278		testTwoOperandOp(t, testcases, twoOpMethods[name], name)
279	}
280}
281
282func opBenchmark(bench *testing.B, op executionFunc, args ...string) {
283	var (
284		env            = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
285		stack          = newstack()
286		evmInterpreter = NewEVMInterpreter(env, env.Config)
287	)
288
289	env.interpreter = evmInterpreter
290	// convert args
291	byteArgs := make([][]byte, len(args))
292	for i, arg := range args {
293		byteArgs[i] = common.Hex2Bytes(arg)
294	}
295	pc := uint64(0)
296	bench.ResetTimer()
297	for i := 0; i < bench.N; i++ {
298		for _, arg := range byteArgs {
299			a := new(uint256.Int)
300			a.SetBytes(arg)
301			stack.push(a)
302		}
303		op(&pc, evmInterpreter, &ScopeContext{nil, stack, nil})
304		stack.pop()
305	}
306}
307
308func BenchmarkOpAdd64(b *testing.B) {
309	x := "ffffffff"
310	y := "fd37f3e2bba2c4f"
311
312	opBenchmark(b, opAdd, x, y)
313}
314
315func BenchmarkOpAdd128(b *testing.B) {
316	x := "ffffffffffffffff"
317	y := "f5470b43c6549b016288e9a65629687"
318
319	opBenchmark(b, opAdd, x, y)
320}
321
322func BenchmarkOpAdd256(b *testing.B) {
323	x := "0802431afcbce1fc194c9eaa417b2fb67dc75a95db0bc7ec6b1c8af11df6a1da9"
324	y := "a1f5aac137876480252e5dcac62c354ec0d42b76b0642b6181ed099849ea1d57"
325
326	opBenchmark(b, opAdd, x, y)
327}
328
329func BenchmarkOpSub64(b *testing.B) {
330	x := "51022b6317003a9d"
331	y := "a20456c62e00753a"
332
333	opBenchmark(b, opSub, x, y)
334}
335
336func BenchmarkOpSub128(b *testing.B) {
337	x := "4dde30faaacdc14d00327aac314e915d"
338	y := "9bbc61f5559b829a0064f558629d22ba"
339
340	opBenchmark(b, opSub, x, y)
341}
342
343func BenchmarkOpSub256(b *testing.B) {
344	x := "4bfcd8bb2ac462735b48a17580690283980aa2d679f091c64364594df113ea37"
345	y := "97f9b1765588c4e6b69142eb00d20507301545acf3e1238c86c8b29be227d46e"
346
347	opBenchmark(b, opSub, x, y)
348}
349
350func BenchmarkOpMul(b *testing.B) {
351	x := alphabetSoup
352	y := alphabetSoup
353
354	opBenchmark(b, opMul, x, y)
355}
356
357func BenchmarkOpDiv256(b *testing.B) {
358	x := "ff3f9014f20db29ae04af2c2d265de17"
359	y := "fe7fb0d1f59dfe9492ffbf73683fd1e870eec79504c60144cc7f5fc2bad1e611"
360	opBenchmark(b, opDiv, x, y)
361}
362
363func BenchmarkOpDiv128(b *testing.B) {
364	x := "fdedc7f10142ff97"
365	y := "fbdfda0e2ce356173d1993d5f70a2b11"
366	opBenchmark(b, opDiv, x, y)
367}
368
369func BenchmarkOpDiv64(b *testing.B) {
370	x := "fcb34eb3"
371	y := "f97180878e839129"
372	opBenchmark(b, opDiv, x, y)
373}
374
375func BenchmarkOpSdiv(b *testing.B) {
376	x := "ff3f9014f20db29ae04af2c2d265de17"
377	y := "fe7fb0d1f59dfe9492ffbf73683fd1e870eec79504c60144cc7f5fc2bad1e611"
378
379	opBenchmark(b, opSdiv, x, y)
380}
381
382func BenchmarkOpMod(b *testing.B) {
383	x := alphabetSoup
384	y := alphabetSoup
385
386	opBenchmark(b, opMod, x, y)
387}
388
389func BenchmarkOpSmod(b *testing.B) {
390	x := alphabetSoup
391	y := alphabetSoup
392
393	opBenchmark(b, opSmod, x, y)
394}
395
396func BenchmarkOpExp(b *testing.B) {
397	x := alphabetSoup
398	y := alphabetSoup
399
400	opBenchmark(b, opExp, x, y)
401}
402
403func BenchmarkOpSignExtend(b *testing.B) {
404	x := alphabetSoup
405	y := alphabetSoup
406
407	opBenchmark(b, opSignExtend, x, y)
408}
409
410func BenchmarkOpLt(b *testing.B) {
411	x := alphabetSoup
412	y := alphabetSoup
413
414	opBenchmark(b, opLt, x, y)
415}
416
417func BenchmarkOpGt(b *testing.B) {
418	x := alphabetSoup
419	y := alphabetSoup
420
421	opBenchmark(b, opGt, x, y)
422}
423
424func BenchmarkOpSlt(b *testing.B) {
425	x := alphabetSoup
426	y := alphabetSoup
427
428	opBenchmark(b, opSlt, x, y)
429}
430
431func BenchmarkOpSgt(b *testing.B) {
432	x := alphabetSoup
433	y := alphabetSoup
434
435	opBenchmark(b, opSgt, x, y)
436}
437
438func BenchmarkOpEq(b *testing.B) {
439	x := alphabetSoup
440	y := alphabetSoup
441
442	opBenchmark(b, opEq, x, y)
443}
444func BenchmarkOpEq2(b *testing.B) {
445	x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"
446	y := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201fffffffe"
447	opBenchmark(b, opEq, x, y)
448}
449func BenchmarkOpAnd(b *testing.B) {
450	x := alphabetSoup
451	y := alphabetSoup
452
453	opBenchmark(b, opAnd, x, y)
454}
455
456func BenchmarkOpOr(b *testing.B) {
457	x := alphabetSoup
458	y := alphabetSoup
459
460	opBenchmark(b, opOr, x, y)
461}
462
463func BenchmarkOpXor(b *testing.B) {
464	x := alphabetSoup
465	y := alphabetSoup
466
467	opBenchmark(b, opXor, x, y)
468}
469
470func BenchmarkOpByte(b *testing.B) {
471	x := alphabetSoup
472	y := alphabetSoup
473
474	opBenchmark(b, opByte, x, y)
475}
476
477func BenchmarkOpAddmod(b *testing.B) {
478	x := alphabetSoup
479	y := alphabetSoup
480	z := alphabetSoup
481
482	opBenchmark(b, opAddmod, x, y, z)
483}
484
485func BenchmarkOpMulmod(b *testing.B) {
486	x := alphabetSoup
487	y := alphabetSoup
488	z := alphabetSoup
489
490	opBenchmark(b, opMulmod, x, y, z)
491}
492
493func BenchmarkOpSHL(b *testing.B) {
494	x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"
495	y := "ff"
496
497	opBenchmark(b, opSHL, x, y)
498}
499func BenchmarkOpSHR(b *testing.B) {
500	x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"
501	y := "ff"
502
503	opBenchmark(b, opSHR, x, y)
504}
505func BenchmarkOpSAR(b *testing.B) {
506	x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"
507	y := "ff"
508
509	opBenchmark(b, opSAR, x, y)
510}
511func BenchmarkOpIsZero(b *testing.B) {
512	x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"
513	opBenchmark(b, opIszero, x)
514}
515
516func TestOpMstore(t *testing.T) {
517	var (
518		env            = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
519		stack          = newstack()
520		mem            = NewMemory()
521		evmInterpreter = NewEVMInterpreter(env, env.Config)
522	)
523
524	env.interpreter = evmInterpreter
525	mem.Resize(64)
526	pc := uint64(0)
527	v := "abcdef00000000000000abba000000000deaf000000c0de00100000000133700"
528	stack.push(new(uint256.Int).SetBytes(common.Hex2Bytes(v)))
529	stack.push(new(uint256.Int))
530	opMstore(&pc, evmInterpreter, &ScopeContext{mem, stack, nil})
531	if got := common.Bytes2Hex(mem.GetCopy(0, 32)); got != v {
532		t.Fatalf("Mstore fail, got %v, expected %v", got, v)
533	}
534	stack.push(new(uint256.Int).SetUint64(0x1))
535	stack.push(new(uint256.Int))
536	opMstore(&pc, evmInterpreter, &ScopeContext{mem, stack, nil})
537	if common.Bytes2Hex(mem.GetCopy(0, 32)) != "0000000000000000000000000000000000000000000000000000000000000001" {
538		t.Fatalf("Mstore failed to overwrite previous value")
539	}
540}
541
542func BenchmarkOpMstore(bench *testing.B) {
543	var (
544		env            = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
545		stack          = newstack()
546		mem            = NewMemory()
547		evmInterpreter = NewEVMInterpreter(env, env.Config)
548	)
549
550	env.interpreter = evmInterpreter
551	mem.Resize(64)
552	pc := uint64(0)
553	memStart := new(uint256.Int)
554	value := new(uint256.Int).SetUint64(0x1337)
555
556	bench.ResetTimer()
557	for i := 0; i < bench.N; i++ {
558		stack.push(value)
559		stack.push(memStart)
560		opMstore(&pc, evmInterpreter, &ScopeContext{mem, stack, nil})
561	}
562}
563
564func BenchmarkOpKeccak256(bench *testing.B) {
565	var (
566		env            = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
567		stack          = newstack()
568		mem            = NewMemory()
569		evmInterpreter = NewEVMInterpreter(env, env.Config)
570	)
571	env.interpreter = evmInterpreter
572	mem.Resize(32)
573	pc := uint64(0)
574	start := new(uint256.Int)
575
576	bench.ResetTimer()
577	for i := 0; i < bench.N; i++ {
578		stack.push(uint256.NewInt(32))
579		stack.push(start)
580		opKeccak256(&pc, evmInterpreter, &ScopeContext{mem, stack, nil})
581	}
582}
583
584func TestCreate2Addreses(t *testing.T) {
585	type testcase struct {
586		origin   string
587		salt     string
588		code     string
589		expected string
590	}
591
592	for i, tt := range []testcase{
593		{
594			origin:   "0x0000000000000000000000000000000000000000",
595			salt:     "0x0000000000000000000000000000000000000000",
596			code:     "0x00",
597			expected: "0x4d1a2e2bb4f88f0250f26ffff098b0b30b26bf38",
598		},
599		{
600			origin:   "0xdeadbeef00000000000000000000000000000000",
601			salt:     "0x0000000000000000000000000000000000000000",
602			code:     "0x00",
603			expected: "0xB928f69Bb1D91Cd65274e3c79d8986362984fDA3",
604		},
605		{
606			origin:   "0xdeadbeef00000000000000000000000000000000",
607			salt:     "0xfeed000000000000000000000000000000000000",
608			code:     "0x00",
609			expected: "0xD04116cDd17beBE565EB2422F2497E06cC1C9833",
610		},
611		{
612			origin:   "0x0000000000000000000000000000000000000000",
613			salt:     "0x0000000000000000000000000000000000000000",
614			code:     "0xdeadbeef",
615			expected: "0x70f2b2914A2a4b783FaEFb75f459A580616Fcb5e",
616		},
617		{
618			origin:   "0x00000000000000000000000000000000deadbeef",
619			salt:     "0xcafebabe",
620			code:     "0xdeadbeef",
621			expected: "0x60f3f640a8508fC6a86d45DF051962668E1e8AC7",
622		},
623		{
624			origin:   "0x00000000000000000000000000000000deadbeef",
625			salt:     "0xcafebabe",
626			code:     "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
627			expected: "0x1d8bfDC5D46DC4f61D6b6115972536eBE6A8854C",
628		},
629		{
630			origin:   "0x0000000000000000000000000000000000000000",
631			salt:     "0x0000000000000000000000000000000000000000",
632			code:     "0x",
633			expected: "0xE33C0C7F7df4809055C3ebA6c09CFe4BaF1BD9e0",
634		},
635	} {
636
637		origin := common.BytesToAddress(common.FromHex(tt.origin))
638		salt := common.BytesToHash(common.FromHex(tt.salt))
639		code := common.FromHex(tt.code)
640		codeHash := crypto.Keccak256(code)
641		address := crypto.CreateAddress2(origin, salt, codeHash)
642		/*
643			stack          := newstack()
644			// salt, but we don't need that for this test
645			stack.push(big.NewInt(int64(len(code)))) //size
646			stack.push(big.NewInt(0)) // memstart
647			stack.push(big.NewInt(0)) // value
648			gas, _ := gasCreate2(params.GasTable{}, nil, nil, stack, nil, 0)
649			fmt.Printf("Example %d\n* address `0x%x`\n* salt `0x%x`\n* init_code `0x%x`\n* gas (assuming no mem expansion): `%v`\n* result: `%s`\n\n", i,origin, salt, code, gas, address.String())
650		*/
651		expected := common.BytesToAddress(common.FromHex(tt.expected))
652		if !bytes.Equal(expected.Bytes(), address.Bytes()) {
653			t.Errorf("test %d: expected %s, got %s", i, expected.String(), address.String())
654		}
655	}
656}
657