github.com/klaytn/klaytn@v1.12.1/blockchain/vm/instructions_test.go (about)

     1  // Modifications Copyright 2018 The klaytn Authors
     2  // Copyright 2017 The go-ethereum Authors
     3  // This file is part of the go-ethereum library.
     4  //
     5  // The go-ethereum library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Lesser General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // The go-ethereum library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  // GNU Lesser General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Lesser General Public License
    16  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    17  //
    18  // This file is derived from core/vm/instructions_test.go (2018/06/04).
    19  // Modified and improved for the klaytn development.
    20  
    21  package vm
    22  
    23  import (
    24  	"bytes"
    25  	"encoding/json"
    26  	"fmt"
    27  	"math/big"
    28  	"os"
    29  	"strings"
    30  	"testing"
    31  
    32  	"github.com/holiman/uint256"
    33  	"github.com/klaytn/klaytn/blockchain/state"
    34  	"github.com/klaytn/klaytn/blockchain/types"
    35  	"github.com/klaytn/klaytn/common"
    36  	"github.com/klaytn/klaytn/common/math"
    37  	"github.com/klaytn/klaytn/crypto"
    38  	"github.com/klaytn/klaytn/params"
    39  	"github.com/klaytn/klaytn/storage/database"
    40  )
    41  
    42  type TwoOperandTestcase struct {
    43  	X        string
    44  	Y        string
    45  	Expected string
    46  }
    47  
    48  type twoOperandParams struct {
    49  	x string
    50  	y string
    51  }
    52  
    53  var (
    54  	commonParams []*twoOperandParams
    55  	twoOpMethods map[string]executionFunc
    56  )
    57  
    58  type contractRef struct {
    59  	addr common.Address
    60  }
    61  
    62  func (c contractRef) Address() common.Address {
    63  	return c.addr
    64  }
    65  
    66  func (c contractRef) FeePayer() common.Address {
    67  	return common.Address{}
    68  }
    69  
    70  func TestOpTstore(t *testing.T) {
    71  	var (
    72  		statedb, _     = state.New(common.Hash{}, state.NewDatabase(database.NewMemoryDBManager()), nil, nil)
    73  		env            = NewEVM(BlockContext{}, TxContext{}, statedb, params.TestChainConfig, &Config{})
    74  		stack          = newstack()
    75  		mem            = NewMemory()
    76  		evmInterpreter = NewEVMInterpreter(env)
    77  		caller         = common.Address{}
    78  		to             = common.Address{1}
    79  		contractRef    = contractRef{caller}
    80  		contract       = NewContract(contractRef, AccountRef(to), new(big.Int), 0)
    81  		scopeContext   = ScopeContext{mem, stack, contract}
    82  		value          = common.Hex2Bytes("abcdef00000000000000abba000000000deaf000000c0de00100000000133700")
    83  	)
    84  
    85  	// Add a stateObject for the caller and the contract being called
    86  	statedb.CreateAccount(caller)
    87  	statedb.CreateAccount(to)
    88  
    89  	env.interpreter = evmInterpreter
    90  	pc := uint64(0)
    91  	// push the value to the stack
    92  	stack.push(new(uint256.Int).SetBytes(value))
    93  	// push the location to the stack
    94  	stack.push(new(uint256.Int))
    95  	opTstore(&pc, evmInterpreter, &scopeContext)
    96  	// there should be no elements on the stack after TSTORE
    97  	if stack.len() != 0 {
    98  		t.Fatal("stack wrong size")
    99  	}
   100  	// push the location to the stack
   101  	stack.push(new(uint256.Int))
   102  	opTload(&pc, evmInterpreter, &scopeContext)
   103  	// there should be one element on the stack after TLOAD
   104  	if stack.len() != 1 {
   105  		t.Fatal("stack wrong size")
   106  	}
   107  	val := stack.peek()
   108  	if !bytes.Equal(val.Bytes(), value) {
   109  		t.Fatal("incorrect element read from transient storage")
   110  	}
   111  }
   112  
   113  func init() {
   114  	// Params is a list of common edgecases that should be used for some common tests
   115  	params := []string{
   116  		"0000000000000000000000000000000000000000000000000000000000000000", // 0
   117  		"0000000000000000000000000000000000000000000000000000000000000001", // +1
   118  		"0000000000000000000000000000000000000000000000000000000000000005", // +5
   119  		"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe", // + max -1
   120  		"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", // + max
   121  		"8000000000000000000000000000000000000000000000000000000000000000", // - max
   122  		"8000000000000000000000000000000000000000000000000000000000000001", // - max+1
   123  		"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb", // - 5
   124  		"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", // - 1
   125  	}
   126  	// Params are combined so each param is used on each 'side'
   127  	commonParams = make([]*twoOperandParams, len(params)*len(params))
   128  	for i, x := range params {
   129  		for j, y := range params {
   130  			commonParams[i*len(params)+j] = &twoOperandParams{x, y}
   131  		}
   132  	}
   133  	twoOpMethods = map[string]executionFunc{
   134  		"add":     opAdd,
   135  		"sub":     opSub,
   136  		"mul":     opMul,
   137  		"div":     opDiv,
   138  		"sdiv":    opSdiv,
   139  		"mod":     opMod,
   140  		"smod":    opSmod,
   141  		"exp":     opExp,
   142  		"signext": opSignExtend,
   143  		"lt":      opLt,
   144  		"gt":      opGt,
   145  		"slt":     opSlt,
   146  		"sgt":     opSgt,
   147  		"eq":      opEq,
   148  		"and":     opAnd,
   149  		"or":      opOr,
   150  		"xor":     opXor,
   151  		"byte":    opByte,
   152  		"shl":     opSHL,
   153  		"shr":     opSHR,
   154  		"sar":     opSAR,
   155  	}
   156  }
   157  
   158  func testTwoOperandOp(t *testing.T, tests []TwoOperandTestcase, opFn executionFunc, name string) {
   159  	var (
   160  		env            = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, &Config{})
   161  		stack          = newstack()
   162  		pc             = uint64(0)
   163  		evmInterpreter = env.interpreter
   164  	)
   165  	for i, test := range tests {
   166  		x := new(uint256.Int).SetBytes(common.Hex2Bytes(test.X))
   167  		y := new(uint256.Int).SetBytes(common.Hex2Bytes(test.Y))
   168  		expected := new(uint256.Int).SetBytes(common.Hex2Bytes(test.Expected))
   169  		stack.push(x)
   170  		stack.push(y)
   171  		opFn(&pc, evmInterpreter, &ScopeContext{nil, stack, nil})
   172  		if len(stack.data) != 1 {
   173  			t.Errorf("Expected one item on stack after %v, got %d: ", name, len(stack.data))
   174  		}
   175  		actual := stack.pop()
   176  
   177  		if actual.Cmp(expected) != 0 {
   178  			t.Errorf("Testcase %v %d, %v(%x, %x): expected  %x, got %x", name, i, name, x, y, expected, actual)
   179  		}
   180  	}
   181  }
   182  
   183  func TestByteOp(t *testing.T) {
   184  	tests := []TwoOperandTestcase{
   185  		{"ABCDEF0908070605040302010000000000000000000000000000000000000000", "00", "AB"},
   186  		{"ABCDEF0908070605040302010000000000000000000000000000000000000000", "01", "CD"},
   187  		{"00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff", "00", "00"},
   188  		{"00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff", "01", "CD"},
   189  		{"0000000000000000000000000000000000000000000000000000000000102030", "1F", "30"},
   190  		{"0000000000000000000000000000000000000000000000000000000000102030", "1E", "20"},
   191  		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "20", "00"},
   192  		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "FFFFFFFFFFFFFFFF", "00"},
   193  	}
   194  	testTwoOperandOp(t, tests, opByte, "byte")
   195  }
   196  
   197  func TestSHL(t *testing.T) {
   198  	// Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#shl-shift-left
   199  	tests := []TwoOperandTestcase{
   200  		{"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000002"},
   201  		{"0000000000000000000000000000000000000000000000000000000000000001", "ff", "8000000000000000000000000000000000000000000000000000000000000000"},
   202  		{"0000000000000000000000000000000000000000000000000000000000000001", "0100", "0000000000000000000000000000000000000000000000000000000000000000"},
   203  		{"0000000000000000000000000000000000000000000000000000000000000001", "0101", "0000000000000000000000000000000000000000000000000000000000000000"},
   204  		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "00", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},
   205  		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "01", "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},
   206  		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ff", "8000000000000000000000000000000000000000000000000000000000000000"},
   207  		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0100", "0000000000000000000000000000000000000000000000000000000000000000"},
   208  		{"0000000000000000000000000000000000000000000000000000000000000000", "01", "0000000000000000000000000000000000000000000000000000000000000000"},
   209  		{"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "01", "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},
   210  	}
   211  	testTwoOperandOp(t, tests, opSHL, "shl")
   212  }
   213  
   214  func TestSHR(t *testing.T) {
   215  	// Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#shr-logical-shift-right
   216  	tests := []TwoOperandTestcase{
   217  		{"0000000000000000000000000000000000000000000000000000000000000001", "00", "0000000000000000000000000000000000000000000000000000000000000001"},
   218  		{"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000000"},
   219  		{"8000000000000000000000000000000000000000000000000000000000000000", "01", "4000000000000000000000000000000000000000000000000000000000000000"},
   220  		{"8000000000000000000000000000000000000000000000000000000000000000", "ff", "0000000000000000000000000000000000000000000000000000000000000001"},
   221  		{"8000000000000000000000000000000000000000000000000000000000000000", "0100", "0000000000000000000000000000000000000000000000000000000000000000"},
   222  		{"8000000000000000000000000000000000000000000000000000000000000000", "0101", "0000000000000000000000000000000000000000000000000000000000000000"},
   223  		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "00", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},
   224  		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "01", "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},
   225  		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ff", "0000000000000000000000000000000000000000000000000000000000000001"},
   226  		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0100", "0000000000000000000000000000000000000000000000000000000000000000"},
   227  		{"0000000000000000000000000000000000000000000000000000000000000000", "01", "0000000000000000000000000000000000000000000000000000000000000000"},
   228  	}
   229  	testTwoOperandOp(t, tests, opSHR, "shr")
   230  }
   231  
   232  func TestSAR(t *testing.T) {
   233  	// Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#sar-arithmetic-shift-right
   234  	tests := []TwoOperandTestcase{
   235  		{"0000000000000000000000000000000000000000000000000000000000000001", "00", "0000000000000000000000000000000000000000000000000000000000000001"},
   236  		{"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000000"},
   237  		{"8000000000000000000000000000000000000000000000000000000000000000", "01", "c000000000000000000000000000000000000000000000000000000000000000"},
   238  		{"8000000000000000000000000000000000000000000000000000000000000000", "ff", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},
   239  		{"8000000000000000000000000000000000000000000000000000000000000000", "0100", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},
   240  		{"8000000000000000000000000000000000000000000000000000000000000000", "0101", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},
   241  		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "00", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},
   242  		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "01", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},
   243  		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ff", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},
   244  		{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0100", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},
   245  		{"0000000000000000000000000000000000000000000000000000000000000000", "01", "0000000000000000000000000000000000000000000000000000000000000000"},
   246  		{"4000000000000000000000000000000000000000000000000000000000000000", "fe", "0000000000000000000000000000000000000000000000000000000000000001"},
   247  		{"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "f8", "000000000000000000000000000000000000000000000000000000000000007f"},
   248  		{"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "fe", "0000000000000000000000000000000000000000000000000000000000000001"},
   249  		{"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ff", "0000000000000000000000000000000000000000000000000000000000000000"},
   250  		{"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0100", "0000000000000000000000000000000000000000000000000000000000000000"},
   251  	}
   252  
   253  	testTwoOperandOp(t, tests, opSAR, "sar")
   254  }
   255  
   256  func TestAddMod(t *testing.T) {
   257  	var (
   258  		env            = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, &Config{})
   259  		stack          = newstack()
   260  		evmInterpreter = NewEVMInterpreter(env)
   261  		pc             = uint64(0)
   262  	)
   263  	tests := []struct {
   264  		x        string
   265  		y        string
   266  		z        string
   267  		expected string
   268  	}{
   269  		{
   270  			"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
   271  			"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe",
   272  			"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
   273  			"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe",
   274  		},
   275  	}
   276  	// x + y = 0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd
   277  	// in 256 bit repr, fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd
   278  
   279  	for i, test := range tests {
   280  		x := new(uint256.Int).SetBytes(common.Hex2Bytes(test.x))
   281  		y := new(uint256.Int).SetBytes(common.Hex2Bytes(test.y))
   282  		z := new(uint256.Int).SetBytes(common.Hex2Bytes(test.z))
   283  		expected := new(uint256.Int).SetBytes(common.Hex2Bytes(test.expected))
   284  		stack.push(z)
   285  		stack.push(y)
   286  		stack.push(x)
   287  		opAddmod(&pc, evmInterpreter, &ScopeContext{nil, stack, nil})
   288  		actual := stack.pop()
   289  		if actual.Cmp(expected) != 0 {
   290  			t.Errorf("Testcase %d, expected  %x, got %x", i, expected, actual)
   291  		}
   292  	}
   293  }
   294  
   295  func TestBlobHash(t *testing.T) {
   296  	type testcase struct {
   297  		name   string
   298  		idx    uint64
   299  		expect common.Hash
   300  		// hashes []common.Hash // klaytn doesn't support blobHashes
   301  	}
   302  	zero := common.Hash{0}
   303  	for _, tt := range []testcase{
   304  		{name: "[{1}]", idx: 0, expect: zero},
   305  		{name: "[1,{2},3]", idx: 2, expect: zero},
   306  		{name: "out-of-bounds (empty)", idx: 10, expect: zero},
   307  		{name: "out-of-bounds", idx: 25, expect: zero},
   308  		{name: "out-of-bounds (nil)", idx: 25, expect: zero},
   309  	} {
   310  		var (
   311  			env            = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, &Config{})
   312  			stack          = newstack()
   313  			pc             = uint64(0)
   314  			evmInterpreter = env.interpreter
   315  		)
   316  		stack.push(uint256.NewInt(tt.idx))
   317  		opBlobHash(&pc, evmInterpreter, &ScopeContext{nil, stack, nil})
   318  		if len(stack.data) != 1 {
   319  			t.Errorf("Expected one item on stack after %v, got %d: ", tt.name, len(stack.data))
   320  		}
   321  		actual := stack.pop()
   322  		expected, overflow := uint256.FromBig(new(big.Int).SetBytes(tt.expect.Bytes()))
   323  		if overflow {
   324  			t.Errorf("Testcase %v: invalid overflow", tt.name)
   325  		}
   326  		if actual.Cmp(expected) != 0 {
   327  			t.Errorf("Testcase %v: expected  %x, got %x", tt.name, expected, actual)
   328  		}
   329  	}
   330  }
   331  
   332  // getResult is a convenience function to generate the expected values
   333  func getResult(args []*twoOperandParams, opFn executionFunc) []TwoOperandTestcase {
   334  	var (
   335  		env         = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, &Config{})
   336  		stack       = newstack()
   337  		pc          = uint64(0)
   338  		interpreter = env.interpreter
   339  	)
   340  	result := make([]TwoOperandTestcase, len(args))
   341  	for i, param := range args {
   342  		x := new(uint256.Int).SetBytes(common.Hex2Bytes(param.x))
   343  		y := new(uint256.Int).SetBytes(common.Hex2Bytes(param.y))
   344  		stack.push(x)
   345  		stack.push(y)
   346  		opFn(&pc, interpreter, &ScopeContext{nil, stack, nil})
   347  		actual := stack.pop()
   348  		result[i] = TwoOperandTestcase{param.x, param.y, fmt.Sprintf("%064x", actual)}
   349  	}
   350  	return result
   351  }
   352  
   353  // utility function to fill the json-file with testcases
   354  // Enable this test to generate the 'testcases_xx.json' files
   355  func xTestWriteExpectedValues(t *testing.T) {
   356  	for name, method := range twoOpMethods {
   357  		data, err := json.Marshal(getResult(commonParams, method))
   358  		if err != nil {
   359  			t.Fatal(err)
   360  		}
   361  		_ = os.WriteFile(fmt.Sprintf("testdata/testcases_%v.json", name), data, 0o644)
   362  		if err != nil {
   363  			t.Fatal(err)
   364  		}
   365  	}
   366  	t.Fatal("This test should not be activated")
   367  }
   368  
   369  // TestJsonTestcases runs through all the testcases defined as json-files
   370  func TestJsonTestcases(t *testing.T) {
   371  	for name := range twoOpMethods {
   372  		data, err := os.ReadFile(fmt.Sprintf("testdata/testcases_%v.json", name))
   373  		if err != nil {
   374  			t.Fatal("Failed to read file", err)
   375  		}
   376  		var testcases []TwoOperandTestcase
   377  		json.Unmarshal(data, &testcases)
   378  		testTwoOperandOp(t, testcases, twoOpMethods[name], name)
   379  	}
   380  }
   381  
   382  func initStateDB(db database.DBManager) *state.StateDB {
   383  	sdb := state.NewDatabase(db)
   384  	statedb, _ := state.New(common.Hash{}, sdb, nil, nil)
   385  
   386  	contractAddress := common.HexToAddress("0x18f30de96ce789fe778b9a5f420f6fdbbd9b34d8")
   387  	code := "60ca60205260005b612710811015630000004557602051506020515060205150602051506020515060205150602051506020515060205150602051506001016300000007565b00"
   388  	statedb.CreateSmartContractAccount(contractAddress, params.CodeFormatEVM, params.Rules{})
   389  	statedb.SetCode(contractAddress, common.Hex2Bytes(code))
   390  	stateHash := common.HexToHash("7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe")
   391  	statedb.SetState(contractAddress, stateHash, stateHash)
   392  	statedb.SetBalance(contractAddress, big.NewInt(1000))
   393  	statedb.SetNonce(contractAddress, uint64(1))
   394  
   395  	{
   396  		// create a contract having a STOP operation.
   397  		contractAddress := common.HexToAddress("0x18f30de96ce789fe778b9a5f420f6fdbbd9b34d9")
   398  		code := "00"
   399  		statedb.CreateSmartContractAccount(contractAddress, params.CodeFormatEVM, params.Rules{})
   400  		statedb.SetCode(contractAddress, common.Hex2Bytes(code))
   401  		statedb.SetBalance(contractAddress, big.NewInt(1000))
   402  		statedb.SetNonce(contractAddress, uint64(1))
   403  	}
   404  
   405  	// Commit and re-open to start with a clean state.
   406  	root, _ := statedb.Commit(false)
   407  	statedb, _ = state.New(root, sdb, nil, nil)
   408  
   409  	return statedb
   410  }
   411  
   412  func opBenchmark(bench *testing.B, op func(pc *uint64, evm *EVMInterpreter, scope *ScopeContext) ([]byte, error), args ...string) {
   413  	var (
   414  		initialCall = true
   415  		canTransfer = func(db StateDB, address common.Address, amount *big.Int) bool {
   416  			if initialCall {
   417  				initialCall = false
   418  				return true
   419  			}
   420  			return db.GetBalance(address).Cmp(amount) >= 0
   421  		}
   422  
   423  		blockCtx = BlockContext{
   424  			BlockNumber: big1024,
   425  			BlockScore:  big.NewInt(0),
   426  			Coinbase:    common.HexToAddress("0xf4b0cb429b7d341bf467f2d51c09b64cd9add37c"),
   427  			BaseFee:     big.NewInt(1000000000000000000),
   428  			GasLimit:    uint64(1000000000000000),
   429  			Time:        big.NewInt(1488928920),
   430  			GetHash: func(num uint64) common.Hash {
   431  				return common.BytesToHash(crypto.Keccak256([]byte(big.NewInt(int64(num)).String())))
   432  			},
   433  			CanTransfer: canTransfer,
   434  			Transfer:    func(db StateDB, sender, recipient common.Address, amount *big.Int) {},
   435  		}
   436  		txCtx = TxContext{
   437  			GasPrice: big.NewInt(1),
   438  		}
   439  
   440  		memDBManager = database.NewMemoryDBManager()
   441  		statedb      = initStateDB(memDBManager)
   442  
   443  		env            = NewEVM(blockCtx, txCtx, statedb, params.TestChainConfig, &Config{})
   444  		stack          = newstack()
   445  		mem            = NewMemory()
   446  		evmInterpreter = NewEVMInterpreter(env)
   447  	)
   448  
   449  	env.Origin = common.HexToAddress("0x9d19bb4553940f422104b1d0c8e5704c5aab63c9")
   450  	env.callGasTemp = uint64(100000000000)
   451  	env.interpreter = evmInterpreter
   452  	evmInterpreter.returnData = []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
   453  	mem.Resize(64)
   454  	mem.Set(uint64(1), uint64(20), common.Hex2Bytes("000164865d7db79197021449b4a6aa650193b09e"))
   455  
   456  	// make contract
   457  	senderAddress := common.HexToAddress("0x91fb186da8f327f999782d1ae1ceacbd4fbbf146")
   458  	payerAddress := common.HexToAddress("0x18f30de96ce789fe778b9a5f420f6fdbbd9b34d8")
   459  
   460  	caller := types.NewAccountRefWithFeePayer(senderAddress, payerAddress)
   461  	object := types.NewAccountRefWithFeePayer(payerAddress, senderAddress)
   462  	contract := NewContract(caller, object, big.NewInt(0), uint64(1000))
   463  	contract.Input = senderAddress.Bytes()
   464  	contract.Gas = uint64(1000)
   465  	contract.Code = common.Hex2Bytes("60ca60205260005b612710811015630000004557602051506020515060205150602051506020515060205150602051506020515060205150602051506001016300000007565b00")
   466  
   467  	// convert args
   468  	byteArgs := make([][]byte, len(args))
   469  	for i, arg := range args {
   470  		byteArgs[i] = common.Hex2Bytes(arg)
   471  	}
   472  	pc := uint64(0)
   473  	bench.ResetTimer()
   474  	for i := 0; i < bench.N; i++ {
   475  		for _, arg := range byteArgs {
   476  			a := new(uint256.Int)
   477  			a.SetBytes(arg)
   478  			stack.push(a)
   479  		}
   480  		op(&pc, evmInterpreter, &ScopeContext{mem, stack, contract})
   481  		if stack.len() > 0 {
   482  			stack.pop()
   483  		}
   484  	}
   485  }
   486  
   487  func BenchmarkOpAdd64(b *testing.B) {
   488  	x := "ffffffff"
   489  	y := "fd37f3e2bba2c4f"
   490  
   491  	opBenchmark(b, opAdd, x, y)
   492  }
   493  
   494  func BenchmarkOpAdd128(b *testing.B) {
   495  	x := "ffffffffffffffff"
   496  	y := "f5470b43c6549b016288e9a65629687"
   497  
   498  	opBenchmark(b, opAdd, x, y)
   499  }
   500  
   501  func BenchmarkOpAdd256(b *testing.B) {
   502  	x := "0802431afcbce1fc194c9eaa417b2fb67dc75a95db0bc7ec6b1c8af11df6a1da9"
   503  	y := "a1f5aac137876480252e5dcac62c354ec0d42b76b0642b6181ed099849ea1d57"
   504  
   505  	opBenchmark(b, opAdd, x, y)
   506  }
   507  
   508  func BenchmarkOpSub64(b *testing.B) {
   509  	x := "51022b6317003a9d"
   510  	y := "a20456c62e00753a"
   511  
   512  	opBenchmark(b, opSub, x, y)
   513  }
   514  
   515  func BenchmarkOpSub128(b *testing.B) {
   516  	x := "4dde30faaacdc14d00327aac314e915d"
   517  	y := "9bbc61f5559b829a0064f558629d22ba"
   518  
   519  	opBenchmark(b, opSub, x, y)
   520  }
   521  
   522  func BenchmarkOpSub256(b *testing.B) {
   523  	x := "4bfcd8bb2ac462735b48a17580690283980aa2d679f091c64364594df113ea37"
   524  	y := "97f9b1765588c4e6b69142eb00d20507301545acf3e1238c86c8b29be227d46e"
   525  
   526  	opBenchmark(b, opSub, x, y)
   527  }
   528  
   529  func BenchmarkOpMul(b *testing.B) {
   530  	x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   531  	y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   532  
   533  	opBenchmark(b, opMul, x, y)
   534  }
   535  
   536  func BenchmarkOpDiv256(b *testing.B) {
   537  	x := "ff3f9014f20db29ae04af2c2d265de17"
   538  	y := "fe7fb0d1f59dfe9492ffbf73683fd1e870eec79504c60144cc7f5fc2bad1e611"
   539  	opBenchmark(b, opDiv, x, y)
   540  }
   541  
   542  func BenchmarkOpDiv128(b *testing.B) {
   543  	x := "fdedc7f10142ff97"
   544  	y := "fbdfda0e2ce356173d1993d5f70a2b11"
   545  	opBenchmark(b, opDiv, x, y)
   546  }
   547  
   548  func BenchmarkOpDiv64(b *testing.B) {
   549  	x := "fcb34eb3"
   550  	y := "f97180878e839129"
   551  	opBenchmark(b, opDiv, x, y)
   552  }
   553  
   554  func BenchmarkOpSdiv(b *testing.B) {
   555  	x := "ff3f9014f20db29ae04af2c2d265de17"
   556  	y := "fe7fb0d1f59dfe9492ffbf73683fd1e870eec79504c60144cc7f5fc2bad1e611"
   557  
   558  	opBenchmark(b, opSdiv, x, y)
   559  }
   560  
   561  func BenchmarkOpMod(b *testing.B) {
   562  	x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   563  	y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   564  
   565  	opBenchmark(b, opMod, x, y)
   566  }
   567  
   568  func BenchmarkOpSmod(b *testing.B) {
   569  	x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   570  	y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   571  
   572  	opBenchmark(b, opSmod, x, y)
   573  }
   574  
   575  func BenchmarkOpExp(b *testing.B) {
   576  	x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   577  	y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   578  
   579  	opBenchmark(b, opExp, x, y)
   580  }
   581  
   582  func BenchmarkOpSignExtend(b *testing.B) {
   583  	x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   584  	y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   585  
   586  	opBenchmark(b, opSignExtend, x, y)
   587  }
   588  
   589  func BenchmarkOpLt(b *testing.B) {
   590  	x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   591  	y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   592  
   593  	opBenchmark(b, opLt, x, y)
   594  }
   595  
   596  func BenchmarkOpGt(b *testing.B) {
   597  	x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   598  	y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   599  
   600  	opBenchmark(b, opGt, x, y)
   601  }
   602  
   603  func BenchmarkOpSlt(b *testing.B) {
   604  	x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   605  	y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   606  
   607  	opBenchmark(b, opSlt, x, y)
   608  }
   609  
   610  func BenchmarkOpSgt(b *testing.B) {
   611  	x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   612  	y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   613  
   614  	opBenchmark(b, opSgt, x, y)
   615  }
   616  
   617  func BenchmarkOpEq(b *testing.B) {
   618  	x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   619  	y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   620  
   621  	opBenchmark(b, opEq, x, y)
   622  }
   623  
   624  func BenchmarkOpEq2(b *testing.B) {
   625  	x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"
   626  	y := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201fffffffe"
   627  	opBenchmark(b, opEq, x, y)
   628  }
   629  
   630  func BenchmarkOpAnd(b *testing.B) {
   631  	x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   632  	y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   633  
   634  	opBenchmark(b, opAnd, x, y)
   635  }
   636  
   637  func BenchmarkOpOr(b *testing.B) {
   638  	x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   639  	y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   640  
   641  	opBenchmark(b, opOr, x, y)
   642  }
   643  
   644  func BenchmarkOpXor(b *testing.B) {
   645  	x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   646  	y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   647  
   648  	opBenchmark(b, opXor, x, y)
   649  }
   650  
   651  func BenchmarkOpByte(b *testing.B) {
   652  	x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   653  	y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   654  
   655  	opBenchmark(b, opByte, x, y)
   656  }
   657  
   658  func BenchmarkOpAddmod(b *testing.B) {
   659  	x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   660  	y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   661  	z := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   662  
   663  	opBenchmark(b, opAddmod, x, y, z)
   664  }
   665  
   666  func BenchmarkOpMulmod(b *testing.B) {
   667  	x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   668  	y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   669  	z := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
   670  
   671  	opBenchmark(b, opMulmod, x, y, z)
   672  }
   673  
   674  func BenchmarkOpSHL(b *testing.B) {
   675  	x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"
   676  	y := "ff"
   677  
   678  	opBenchmark(b, opSHL, x, y)
   679  }
   680  
   681  func BenchmarkOpSHR(b *testing.B) {
   682  	x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"
   683  	y := "ff"
   684  
   685  	opBenchmark(b, opSHR, x, y)
   686  }
   687  
   688  func BenchmarkOpSAR(b *testing.B) {
   689  	x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"
   690  	y := "ff"
   691  
   692  	opBenchmark(b, opSAR, x, y)
   693  }
   694  
   695  func BenchmarkOpIsZero(b *testing.B) {
   696  	x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"
   697  	opBenchmark(b, opIszero, x)
   698  }
   699  
   700  func TestOpMstore(t *testing.T) {
   701  	var (
   702  		env            = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, &Config{})
   703  		stack          = newstack()
   704  		mem            = NewMemory()
   705  		evmInterpreter = NewEVMInterpreter(env)
   706  	)
   707  
   708  	env.interpreter = evmInterpreter
   709  	mem.Resize(64)
   710  	pc := uint64(0)
   711  	v := "abcdef00000000000000abba000000000deaf000000c0de00100000000133700"
   712  	stack.pushN(*new(uint256.Int).SetBytes(common.Hex2Bytes(v)), *new(uint256.Int))
   713  	opMstore(&pc, evmInterpreter, &ScopeContext{mem, stack, nil})
   714  	if got := common.Bytes2Hex(mem.GetCopy(0, 32)); got != v {
   715  		t.Fatalf("Mstore fail, got %v, expected %v", got, v)
   716  	}
   717  	stack.pushN(*new(uint256.Int).SetUint64(0x1), *new(uint256.Int))
   718  	opMstore(&pc, evmInterpreter, &ScopeContext{mem, stack, nil})
   719  	if common.Bytes2Hex(mem.GetCopy(0, 32)) != "0000000000000000000000000000000000000000000000000000000000000001" {
   720  		t.Fatalf("Mstore failed to overwrite previous value")
   721  	}
   722  }
   723  
   724  func BenchmarkOpMstore(bench *testing.B) {
   725  	var (
   726  		env            = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, &Config{})
   727  		stack          = newstack()
   728  		mem            = NewMemory()
   729  		evmInterpreter = NewEVMInterpreter(env)
   730  	)
   731  
   732  	env.interpreter = evmInterpreter
   733  	mem.Resize(64)
   734  	pc := uint64(0)
   735  	memStart := new(uint256.Int)
   736  	value := new(uint256.Int).SetUint64(0x1337)
   737  
   738  	bench.ResetTimer()
   739  	for i := 0; i < bench.N; i++ {
   740  		stack.pushN(*value, *memStart)
   741  		opMstore(&pc, evmInterpreter, &ScopeContext{mem, stack, nil})
   742  	}
   743  }
   744  
   745  func BenchmarkOpSHA3(bench *testing.B) {
   746  	var (
   747  		env            = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, &Config{})
   748  		stack          = newstack()
   749  		mem            = NewMemory()
   750  		evmInterpreter = NewEVMInterpreter(env)
   751  	)
   752  	env.interpreter = evmInterpreter
   753  	mem.Resize(32)
   754  	pc := uint64(0)
   755  	start := new(uint256.Int)
   756  
   757  	bench.ResetTimer()
   758  	for i := 0; i < bench.N; i++ {
   759  		stack.push(uint256.NewInt(32))
   760  		stack.push(start)
   761  		opSha3(&pc, evmInterpreter, &ScopeContext{mem, stack, nil})
   762  	}
   763  }
   764  
   765  func TestCreate2Addreses(t *testing.T) {
   766  	type testcase struct {
   767  		origin   string
   768  		salt     string
   769  		code     string
   770  		expected string
   771  	}
   772  
   773  	for i, tt := range []testcase{
   774  		{
   775  			origin:   "0x0000000000000000000000000000000000000000",
   776  			salt:     "0x0000000000000000000000000000000000000000",
   777  			code:     "0x00",
   778  			expected: "0x4d1a2e2bb4f88f0250f26ffff098b0b30b26bf38",
   779  		},
   780  		{
   781  			origin:   "0xdeadbeef00000000000000000000000000000000",
   782  			salt:     "0x0000000000000000000000000000000000000000",
   783  			code:     "0x00",
   784  			expected: "0xB928f69Bb1D91Cd65274e3c79d8986362984fDA3",
   785  		},
   786  		{
   787  			origin:   "0xdeadbeef00000000000000000000000000000000",
   788  			salt:     "0xfeed000000000000000000000000000000000000",
   789  			code:     "0x00",
   790  			expected: "0xD04116cDd17beBE565EB2422F2497E06cC1C9833",
   791  		},
   792  		{
   793  			origin:   "0x0000000000000000000000000000000000000000",
   794  			salt:     "0x0000000000000000000000000000000000000000",
   795  			code:     "0xdeadbeef",
   796  			expected: "0x70f2b2914A2a4b783FaEFb75f459A580616Fcb5e",
   797  		},
   798  		{
   799  			origin:   "0x00000000000000000000000000000000deadbeef",
   800  			salt:     "0xcafebabe",
   801  			code:     "0xdeadbeef",
   802  			expected: "0x60f3f640a8508fC6a86d45DF051962668E1e8AC7",
   803  		},
   804  		{
   805  			origin:   "0x00000000000000000000000000000000deadbeef",
   806  			salt:     "0xcafebabe",
   807  			code:     "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
   808  			expected: "0x1d8bfDC5D46DC4f61D6b6115972536eBE6A8854C",
   809  		},
   810  		{
   811  			origin:   "0x0000000000000000000000000000000000000000",
   812  			salt:     "0x0000000000000000000000000000000000000000",
   813  			code:     "0x",
   814  			expected: "0xE33C0C7F7df4809055C3ebA6c09CFe4BaF1BD9e0",
   815  		},
   816  	} {
   817  
   818  		origin := common.BytesToAddress(common.FromHex(tt.origin))
   819  		salt := common.BytesToHash(common.FromHex(tt.salt))
   820  		code := common.FromHex(tt.code)
   821  		codeHash := crypto.Keccak256(code)
   822  		address := crypto.CreateAddress2(origin, salt, codeHash)
   823  		/*
   824  			stack          := newstack()
   825  			// salt, but we don't need that for this test
   826  			stack.push(big.NewInt(int64(len(code)))) //size
   827  			stack.push(big.NewInt(0)) // memstart
   828  			stack.push(big.NewInt(0)) // value
   829  			gas, _ := gasCreate2(params.GasTable{}, nil, nil, stack, nil, 0)
   830  			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())
   831  		*/
   832  		expected := common.BytesToAddress(common.FromHex(tt.expected))
   833  		if !bytes.Equal(expected.Bytes(), address.Bytes()) {
   834  			t.Errorf("test %d: expected %s, got %s", i, expected.String(), address.String())
   835  		}
   836  
   837  	}
   838  }
   839  
   840  func BenchmarkOpStop(b *testing.B) {
   841  	opBenchmark(b, opStop)
   842  }
   843  
   844  func BenchmarkOpNot(b *testing.B) {
   845  	x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"
   846  	opBenchmark(b, opNot, x)
   847  }
   848  
   849  func BenchmarkOpAddress(b *testing.B) {
   850  	opBenchmark(b, opAddress)
   851  }
   852  
   853  func BenchmarkOpBalance(b *testing.B) {
   854  	addr := "18f30de96ce789fe778b9a5f420f6fdbbd9b34d8"
   855  	opBenchmark(b, opBalance, addr)
   856  }
   857  
   858  func BenchmarkOpOrigin(b *testing.B) {
   859  	opBenchmark(b, opOrigin)
   860  }
   861  
   862  func BenchmarkOpCaller(b *testing.B) {
   863  	opBenchmark(b, opCaller)
   864  }
   865  
   866  func BenchmarkOpCallValue(b *testing.B) {
   867  	opBenchmark(b, opCallValue)
   868  }
   869  
   870  func BenchmarkOpCallDataLoad(b *testing.B) {
   871  	x := "0000000000000000000000000000000000000000000000000000000000000001" // 1
   872  	opBenchmark(b, opCallDataLoad, x)
   873  }
   874  
   875  func BenchmarkOpCallDataSize(b *testing.B) {
   876  	opBenchmark(b, opCallDataSize)
   877  }
   878  
   879  func BenchmarkOpCallDataCopy(b *testing.B) {
   880  	length := "0000000000000000000000000000000000000000000000000000000000000013"     // 19
   881  	dataOffset := "0000000000000000000000000000000000000000000000000000000000000001" // 1
   882  	memOffset := "0000000000000000000000000000000000000000000000000000000000000001"  // 1
   883  	opBenchmark(b, opCallDataCopy, length, dataOffset, memOffset)
   884  }
   885  
   886  func BenchmarkOpReturnDataSize(b *testing.B) {
   887  	opBenchmark(b, opReturnDataSize)
   888  }
   889  
   890  func BenchmarkOpReturnDataCopy(b *testing.B) {
   891  	length := "0000000000000000000000000000000000000000000000000000000000000009"     // 9
   892  	dataOffset := "0000000000000000000000000000000000000000000000000000000000000001" // 1
   893  	memOffset := "0000000000000000000000000000000000000000000000000000000000000001"  // 1
   894  	opBenchmark(b, opReturnDataCopy, length, dataOffset, memOffset)
   895  }
   896  
   897  func BenchmarkOpExtCodeSize(b *testing.B) {
   898  	addr := "18f30de96ce789fe778b9a5f420f6fdbbd9b34d8"
   899  	opBenchmark(b, opExtCodeSize, addr)
   900  }
   901  
   902  func BenchmarkOpCodeSize(b *testing.B) {
   903  	opBenchmark(b, opCodeSize)
   904  }
   905  
   906  func BenchmarkOpCodeCopy(b *testing.B) {
   907  	length := "000000000000000000000000000000000000000000000000000000000000003c"     // 60
   908  	dataOffset := "0000000000000000000000000000000000000000000000000000000000000001" // 1
   909  	memOffset := "0000000000000000000000000000000000000000000000000000000000000001"  // 1
   910  	opBenchmark(b, opCodeCopy, length, dataOffset, memOffset)
   911  }
   912  
   913  func BenchmarkOpExtCodeCopy(b *testing.B) {
   914  	length := "000000000000000000000000000000000000000000000000000000000000003c"     // 60
   915  	codeOffset := "0000000000000000000000000000000000000000000000000000000000000001" // 1
   916  	memOffset := "0000000000000000000000000000000000000000000000000000000000000001"  // 1
   917  	addr := "18f30de96ce789fe778b9a5f420f6fdbbd9b34d8"
   918  	opBenchmark(b, opExtCodeCopy, length, codeOffset, memOffset, addr)
   919  }
   920  
   921  func BenchmarkOpExtCodeHash(b *testing.B) {
   922  	addr := "18f30de96ce789fe778b9a5f420f6fdbbd9b34d8"
   923  	opBenchmark(b, opExtCodeHash, addr)
   924  }
   925  
   926  func BenchmarkOpGasprice(b *testing.B) {
   927  	opBenchmark(b, opGasprice)
   928  }
   929  
   930  func BenchmarkOpBlockhash(b *testing.B) {
   931  	num := "00000000000000000000000000000000000000000000000000000000000003E8" // 1000
   932  	opBenchmark(b, opBlockhash, num)
   933  }
   934  
   935  func BenchmarkOpCoinbase(b *testing.B) {
   936  	opBenchmark(b, opCoinbase)
   937  }
   938  
   939  func BenchmarkOpTimestamp(b *testing.B) {
   940  	opBenchmark(b, opTimestamp)
   941  }
   942  
   943  func BenchmarkOpNumber(b *testing.B) {
   944  	opBenchmark(b, opNumber)
   945  }
   946  
   947  func BenchmarkOpDifficulty(b *testing.B) {
   948  	opBenchmark(b, opDifficulty)
   949  }
   950  
   951  func BenchmarkOpRandom(b *testing.B) {
   952  	opBenchmark(b, opRandom)
   953  }
   954  
   955  func BenchmarkOpGasLimit(b *testing.B) {
   956  	opBenchmark(b, opGasLimit)
   957  }
   958  
   959  func BenchmarkOpPop(b *testing.B) {
   960  	x := "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
   961  	opBenchmark(b, opPop, x)
   962  }
   963  
   964  func BenchmarkOpMload(b *testing.B) {
   965  	offset := "0000000000000000000000000000000000000000000000000000000000000001"
   966  	opBenchmark(b, opMload, offset)
   967  }
   968  
   969  func BenchmarkOpMstore8(b *testing.B) {
   970  	val := "7FFFFFFFFFFFFFFF"
   971  	off := "0000000000000000000000000000000000000000000000000000000000000001"
   972  	opBenchmark(b, opMstore8, val, off)
   973  }
   974  
   975  func BenchmarkOpSload(b *testing.B) {
   976  	loc := "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
   977  	opBenchmark(b, opSload, loc)
   978  }
   979  
   980  func BenchmarkOpSstore(bench *testing.B) {
   981  	var (
   982  		memDBManager = database.NewMemoryDBManager()
   983  		statedb      = initStateDB(memDBManager)
   984  
   985  		env            = NewEVM(BlockContext{}, TxContext{}, statedb, params.TestChainConfig, &Config{})
   986  		stack          = newstack()
   987  		evmInterpreter = NewEVMInterpreter(env)
   988  	)
   989  
   990  	env.interpreter = evmInterpreter
   991  
   992  	// make contract
   993  	senderAddress := common.HexToAddress("0x91fb186da8f327f999782d1ae1ceacbd4fbbf146")
   994  	payerAddress := common.HexToAddress("0x18f30de96ce789fe778b9a5f420f6fdbbd9b34d8")
   995  
   996  	caller := types.NewAccountRefWithFeePayer(senderAddress, payerAddress)
   997  	object := types.NewAccountRefWithFeePayer(payerAddress, senderAddress)
   998  	contract := NewContract(caller, object, big.NewInt(0), uint64(1000))
   999  
  1000  	// convert args
  1001  	byteArgs := make([][]byte, 2)
  1002  	byteArgs[0] = common.Hex2Bytes("7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd") // val
  1003  	byteArgs[1] = common.Hex2Bytes("7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")  // loc
  1004  
  1005  	pc := uint64(0)
  1006  	bench.ResetTimer()
  1007  	for i := 0; i < bench.N; i++ {
  1008  		stack.push(new(uint256.Int).SetBytes(byteArgs[0]))
  1009  		stack.push(new(uint256.Int).SetBytes(append(byteArgs[1], byte(i))))
  1010  		opSstore(&pc, evmInterpreter, &ScopeContext{nil, stack, contract})
  1011  		if stack.len() > 0 {
  1012  			stack.pop()
  1013  		}
  1014  	}
  1015  }
  1016  
  1017  func BenchmarkOpJump(b *testing.B) {
  1018  	pos := "0000000000000000000000000000000000000000000000000000000000000045"
  1019  	opBenchmark(b, opJump, pos)
  1020  }
  1021  
  1022  func BenchmarkOpJumpi(b *testing.B) {
  1023  	cond := "0000000000000000000000000000000000000000000000000000000000000001"
  1024  	pos := "0000000000000000000000000000000000000000000000000000000000000045"
  1025  	opBenchmark(b, opJumpi, cond, pos)
  1026  }
  1027  
  1028  func BenchmarkOpJumpdest(b *testing.B) {
  1029  	opBenchmark(b, opJumpdest)
  1030  }
  1031  
  1032  func BenchmarkOpPc(b *testing.B) {
  1033  	opBenchmark(b, opPc)
  1034  }
  1035  
  1036  func BenchmarkOpMsize(b *testing.B) {
  1037  	opBenchmark(b, opMsize)
  1038  }
  1039  
  1040  func BenchmarkOpGas(b *testing.B) {
  1041  	opBenchmark(b, opGas)
  1042  }
  1043  
  1044  func BenchmarkOpCreate(b *testing.B) {
  1045  	size := "0000000000000014"
  1046  	offset := "0000000000000001"
  1047  	value := "7FFFFFFFFFFFFFFF"
  1048  	opBenchmark(b, opCreate, size, offset, value)
  1049  }
  1050  
  1051  func BenchmarkOpCreate2(b *testing.B) {
  1052  	salt := "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
  1053  	size := "0000000000000014"
  1054  	offset := "0000000000000001"
  1055  	endowment := "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
  1056  	opBenchmark(b, opCreate2, salt, size, offset, endowment)
  1057  }
  1058  
  1059  func BenchmarkOpCall(b *testing.B) {
  1060  	retSize := "0000000000000000000000000000000000000000000000000000000000000001"
  1061  	retOffset := "0000000000000000000000000000000000000000000000000000000000000001"
  1062  	inSize := "0000000000000014"
  1063  	inOffset := "0000000000000001"
  1064  	value := "0000000000000000000000000000000000000000000000000000000000000001"
  1065  	addr := "18f30de96ce789fe778b9a5f420f6fdbbd9b34d9"
  1066  	gas := "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
  1067  	opBenchmark(b, opCall, retSize, retOffset, inSize, inOffset, value, addr, gas)
  1068  }
  1069  
  1070  func BenchmarkOpCallCode(b *testing.B) {
  1071  	retSize := "0000000000000000000000000000000000000000000000000000000000000001"
  1072  	retOffset := "0000000000000000000000000000000000000000000000000000000000000001"
  1073  	inSize := "0000000000000014"
  1074  	inOffset := "0000000000000001"
  1075  	value := "0000000000000000000000000000000000000000000000000000000000000001"
  1076  	addr := "18f30de96ce789fe778b9a5f420f6fdbbd9b34d9"
  1077  	gas := "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
  1078  	opBenchmark(b, opCallCode, retSize, retOffset, inSize, inOffset, value, addr, gas)
  1079  }
  1080  
  1081  func BenchmarkOpDelegateCall(b *testing.B) {
  1082  	retSize := "0000000000000000000000000000000000000000000000000000000000000001"
  1083  	retOffset := "0000000000000000000000000000000000000000000000000000000000000001"
  1084  	inSize := "0000000000000014"
  1085  	inOffset := "0000000000000001"
  1086  	addr := "18f30de96ce789fe778b9a5f420f6fdbbd9b34d9"
  1087  	gas := "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
  1088  	opBenchmark(b, opDelegateCall, retSize, retOffset, inSize, inOffset, addr, gas)
  1089  }
  1090  
  1091  func BenchmarkOpStaticCall(b *testing.B) {
  1092  	retSize := "0000000000000000000000000000000000000000000000000000000000000001"
  1093  	retOffset := "0000000000000000000000000000000000000000000000000000000000000001"
  1094  	inSize := "0000000000000014"
  1095  	inOffset := "0000000000000001"
  1096  	addr := "18f30de96ce789fe778b9a5f420f6fdbbd9b34d9"
  1097  	gas := "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
  1098  	opBenchmark(b, opStaticCall, retSize, retOffset, inSize, inOffset, addr, gas)
  1099  }
  1100  
  1101  func BenchmarkOpReturn(b *testing.B) {
  1102  	size := "0000000000000014"
  1103  	offset := "0000000000000001"
  1104  	opBenchmark(b, opReturn, size, offset)
  1105  }
  1106  
  1107  func BenchmarkOpRevert(b *testing.B) {
  1108  	size := "0000000000000014"
  1109  	offset := "0000000000000001"
  1110  	opBenchmark(b, opRevert, size, offset)
  1111  }
  1112  
  1113  func BenchmarkOpSelfDestruct(b *testing.B) {
  1114  	addr := "18f30de96ce789fe778b9a5f420f6fdbbd9b34d8"
  1115  	opBenchmark(b, opSelfdestruct, addr)
  1116  }
  1117  
  1118  func BenchmarkOpPush1(b *testing.B) {
  1119  	opBenchmark(b, opPush1)
  1120  }
  1121  
  1122  func BenchmarkOpPush2(b *testing.B) {
  1123  	opBenchmark(b, makePush(uint64(2), 2))
  1124  }
  1125  
  1126  func BenchmarkOpPush3(b *testing.B) {
  1127  	opBenchmark(b, makePush(uint64(3), 3))
  1128  }
  1129  
  1130  func BenchmarkOpPush4(b *testing.B) {
  1131  	opBenchmark(b, makePush(uint64(4), 4))
  1132  }
  1133  
  1134  func BenchmarkOpPush5(b *testing.B) {
  1135  	opBenchmark(b, makePush(uint64(5), 5))
  1136  }
  1137  
  1138  func BenchmarkOpPush6(b *testing.B) {
  1139  	opBenchmark(b, makePush(uint64(6), 6))
  1140  }
  1141  
  1142  func BenchmarkOpPush7(b *testing.B) {
  1143  	opBenchmark(b, makePush(uint64(7), 7))
  1144  }
  1145  
  1146  func BenchmarkOpPush8(b *testing.B) {
  1147  	opBenchmark(b, makePush(uint64(8), 8))
  1148  }
  1149  
  1150  func BenchmarkOpPush9(b *testing.B) {
  1151  	opBenchmark(b, makePush(uint64(9), 9))
  1152  }
  1153  
  1154  func BenchmarkOpPush10(b *testing.B) {
  1155  	opBenchmark(b, makePush(uint64(10), 10))
  1156  }
  1157  
  1158  func BenchmarkOpPush11(b *testing.B) {
  1159  	opBenchmark(b, makePush(uint64(11), 11))
  1160  }
  1161  
  1162  func BenchmarkOpPush12(b *testing.B) {
  1163  	opBenchmark(b, makePush(uint64(12), 12))
  1164  }
  1165  
  1166  func BenchmarkOpPush13(b *testing.B) {
  1167  	opBenchmark(b, makePush(uint64(13), 13))
  1168  }
  1169  
  1170  func BenchmarkOpPush14(b *testing.B) {
  1171  	opBenchmark(b, makePush(uint64(14), 14))
  1172  }
  1173  
  1174  func BenchmarkOpPush15(b *testing.B) {
  1175  	opBenchmark(b, makePush(uint64(15), 15))
  1176  }
  1177  
  1178  func BenchmarkOpPush16(b *testing.B) {
  1179  	opBenchmark(b, makePush(uint64(16), 16))
  1180  }
  1181  
  1182  func BenchmarkOpPush17(b *testing.B) {
  1183  	opBenchmark(b, makePush(uint64(17), 17))
  1184  }
  1185  
  1186  func BenchmarkOpPush18(b *testing.B) {
  1187  	opBenchmark(b, makePush(uint64(18), 18))
  1188  }
  1189  
  1190  func BenchmarkOpPush19(b *testing.B) {
  1191  	opBenchmark(b, makePush(uint64(19), 19))
  1192  }
  1193  
  1194  func BenchmarkOpPush20(b *testing.B) {
  1195  	opBenchmark(b, makePush(uint64(20), 20))
  1196  }
  1197  
  1198  func BenchmarkOpPush21(b *testing.B) {
  1199  	opBenchmark(b, makePush(uint64(21), 21))
  1200  }
  1201  
  1202  func BenchmarkOpPush22(b *testing.B) {
  1203  	opBenchmark(b, makePush(uint64(22), 22))
  1204  }
  1205  
  1206  func BenchmarkOpPush23(b *testing.B) {
  1207  	opBenchmark(b, makePush(uint64(23), 23))
  1208  }
  1209  
  1210  func BenchmarkOpPush24(b *testing.B) {
  1211  	opBenchmark(b, makePush(uint64(24), 24))
  1212  }
  1213  
  1214  func BenchmarkOpPush25(b *testing.B) {
  1215  	opBenchmark(b, makePush(uint64(25), 25))
  1216  }
  1217  
  1218  func BenchmarkOpPush26(b *testing.B) {
  1219  	opBenchmark(b, makePush(uint64(26), 26))
  1220  }
  1221  
  1222  func BenchmarkOpPush27(b *testing.B) {
  1223  	opBenchmark(b, makePush(uint64(27), 27))
  1224  }
  1225  
  1226  func BenchmarkOpPush28(b *testing.B) {
  1227  	opBenchmark(b, makePush(uint64(28), 28))
  1228  }
  1229  
  1230  func BenchmarkOpPush29(b *testing.B) {
  1231  	opBenchmark(b, makePush(uint64(29), 29))
  1232  }
  1233  
  1234  func BenchmarkOpPush30(b *testing.B) {
  1235  	opBenchmark(b, makePush(uint64(30), 30))
  1236  }
  1237  
  1238  func BenchmarkOpPush31(b *testing.B) {
  1239  	opBenchmark(b, makePush(uint64(31), 31))
  1240  }
  1241  
  1242  func BenchmarkOpPush32(b *testing.B) {
  1243  	opBenchmark(b, makePush(uint64(32), 32))
  1244  }
  1245  
  1246  func BenchmarkOpDup1(b *testing.B) {
  1247  	size := 1
  1248  	stacks := genStacksForDup(size)
  1249  	opBenchmark(b, makeDup(int64(size)), stacks...)
  1250  }
  1251  
  1252  func BenchmarkOpDup2(b *testing.B) {
  1253  	size := 2
  1254  	stacks := genStacksForDup(size)
  1255  	opBenchmark(b, makeDup(int64(size)), stacks...)
  1256  }
  1257  
  1258  func BenchmarkOpDup3(b *testing.B) {
  1259  	size := 3
  1260  	stacks := genStacksForDup(size)
  1261  	opBenchmark(b, makeDup(int64(size)), stacks...)
  1262  }
  1263  
  1264  func BenchmarkOpDup4(b *testing.B) {
  1265  	size := 4
  1266  	stacks := genStacksForDup(size)
  1267  	opBenchmark(b, makeDup(int64(size)), stacks...)
  1268  }
  1269  
  1270  func BenchmarkOpDup5(b *testing.B) {
  1271  	size := 5
  1272  	stacks := genStacksForDup(size)
  1273  	opBenchmark(b, makeDup(int64(size)), stacks...)
  1274  }
  1275  
  1276  func BenchmarkOpDup6(b *testing.B) {
  1277  	size := 6
  1278  	stacks := genStacksForDup(size)
  1279  	opBenchmark(b, makeDup(int64(size)), stacks...)
  1280  }
  1281  
  1282  func BenchmarkOpDup7(b *testing.B) {
  1283  	size := 7
  1284  	stacks := genStacksForDup(size)
  1285  	opBenchmark(b, makeDup(int64(size)), stacks...)
  1286  }
  1287  
  1288  func BenchmarkOpDup8(b *testing.B) {
  1289  	size := 8
  1290  	stacks := genStacksForDup(size)
  1291  	opBenchmark(b, makeDup(int64(size)), stacks...)
  1292  }
  1293  
  1294  func BenchmarkOpDup9(b *testing.B) {
  1295  	size := 9
  1296  	stacks := genStacksForDup(size)
  1297  	opBenchmark(b, makeDup(int64(size)), stacks...)
  1298  }
  1299  
  1300  func BenchmarkOpDup10(b *testing.B) {
  1301  	size := 10
  1302  	stacks := genStacksForDup(size)
  1303  	opBenchmark(b, makeDup(int64(size)), stacks...)
  1304  }
  1305  
  1306  func BenchmarkOpDup11(b *testing.B) {
  1307  	size := 11
  1308  	stacks := genStacksForDup(size)
  1309  	opBenchmark(b, makeDup(int64(size)), stacks...)
  1310  }
  1311  
  1312  func BenchmarkOpDup12(b *testing.B) {
  1313  	size := 12
  1314  	stacks := genStacksForDup(size)
  1315  	opBenchmark(b, makeDup(int64(size)), stacks...)
  1316  }
  1317  
  1318  func BenchmarkOpDup13(b *testing.B) {
  1319  	size := 13
  1320  	stacks := genStacksForDup(size)
  1321  	opBenchmark(b, makeDup(int64(size)), stacks...)
  1322  }
  1323  
  1324  func BenchmarkOpDup14(b *testing.B) {
  1325  	size := 14
  1326  	stacks := genStacksForDup(size)
  1327  	opBenchmark(b, makeDup(int64(size)), stacks...)
  1328  }
  1329  
  1330  func BenchmarkOpDup15(b *testing.B) {
  1331  	size := 15
  1332  	stacks := genStacksForDup(size)
  1333  	opBenchmark(b, makeDup(int64(size)), stacks...)
  1334  }
  1335  
  1336  func BenchmarkOpDup16(b *testing.B) {
  1337  	size := 16
  1338  	stacks := genStacksForDup(size)
  1339  	opBenchmark(b, makeDup(int64(size)), stacks...)
  1340  }
  1341  
  1342  func BenchmarkOpSwap1(b *testing.B) {
  1343  	size := 1
  1344  	stacks := genStacksForSwap(size)
  1345  	opBenchmark(b, makeSwap(int64(size)), stacks...)
  1346  }
  1347  
  1348  func BenchmarkOpSwap2(b *testing.B) {
  1349  	size := 2
  1350  	stacks := genStacksForSwap(size)
  1351  	opBenchmark(b, makeSwap(int64(size)), stacks...)
  1352  }
  1353  
  1354  func BenchmarkOpSwap3(b *testing.B) {
  1355  	size := 3
  1356  	stacks := genStacksForSwap(size)
  1357  	opBenchmark(b, makeSwap(int64(size)), stacks...)
  1358  }
  1359  
  1360  func BenchmarkOpSwap4(b *testing.B) {
  1361  	size := 4
  1362  	stacks := genStacksForSwap(size)
  1363  	opBenchmark(b, makeSwap(int64(size)), stacks...)
  1364  }
  1365  
  1366  func BenchmarkOpSwap5(b *testing.B) {
  1367  	size := 5
  1368  	stacks := genStacksForSwap(size)
  1369  	opBenchmark(b, makeSwap(int64(size)), stacks...)
  1370  }
  1371  
  1372  func BenchmarkOpSwap6(b *testing.B) {
  1373  	size := 6
  1374  	stacks := genStacksForSwap(size)
  1375  	opBenchmark(b, makeSwap(int64(size)), stacks...)
  1376  }
  1377  
  1378  func BenchmarkOpSwap7(b *testing.B) {
  1379  	size := 7
  1380  	stacks := genStacksForSwap(size)
  1381  	opBenchmark(b, makeSwap(int64(size)), stacks...)
  1382  }
  1383  
  1384  func BenchmarkOpSwap8(b *testing.B) {
  1385  	size := 8
  1386  	stacks := genStacksForSwap(size)
  1387  	opBenchmark(b, makeSwap(int64(size)), stacks...)
  1388  }
  1389  
  1390  func BenchmarkOpSwap9(b *testing.B) {
  1391  	size := 9
  1392  	stacks := genStacksForSwap(size)
  1393  	opBenchmark(b, makeSwap(int64(size)), stacks...)
  1394  }
  1395  
  1396  func BenchmarkOpSwap10(b *testing.B) {
  1397  	size := 10
  1398  	stacks := genStacksForSwap(size)
  1399  	opBenchmark(b, makeSwap(int64(size)), stacks...)
  1400  }
  1401  
  1402  func BenchmarkOpSwap11(b *testing.B) {
  1403  	size := 11
  1404  	stacks := genStacksForSwap(size)
  1405  	opBenchmark(b, makeSwap(int64(size)), stacks...)
  1406  }
  1407  
  1408  func BenchmarkOpSwap12(b *testing.B) {
  1409  	size := 12
  1410  	stacks := genStacksForSwap(size)
  1411  	opBenchmark(b, makeSwap(int64(size)), stacks...)
  1412  }
  1413  
  1414  func BenchmarkOpSwap13(b *testing.B) {
  1415  	size := 13
  1416  	stacks := genStacksForSwap(size)
  1417  	opBenchmark(b, makeSwap(int64(size)), stacks...)
  1418  }
  1419  
  1420  func BenchmarkOpSwap14(b *testing.B) {
  1421  	size := 14
  1422  	stacks := genStacksForSwap(size)
  1423  	opBenchmark(b, makeSwap(int64(size)), stacks...)
  1424  }
  1425  
  1426  func BenchmarkOpSwap15(b *testing.B) {
  1427  	size := 15
  1428  	stacks := genStacksForSwap(size)
  1429  	opBenchmark(b, makeSwap(int64(size)), stacks...)
  1430  }
  1431  
  1432  func BenchmarkOpSwap16(b *testing.B) {
  1433  	size := 16
  1434  	stacks := genStacksForSwap(size)
  1435  	opBenchmark(b, makeSwap(int64(size)), stacks...)
  1436  }
  1437  
  1438  func BenchmarkOpLog0(b *testing.B) {
  1439  	size := 0
  1440  	stacks := genStacksForLog(size)
  1441  	opBenchmark(b, makeLog(size), stacks...)
  1442  }
  1443  
  1444  func BenchmarkOpLog1(b *testing.B) {
  1445  	size := 1
  1446  	stacks := genStacksForLog(size)
  1447  	opBenchmark(b, makeLog(size), stacks...)
  1448  }
  1449  
  1450  func BenchmarkOpLog2(b *testing.B) {
  1451  	size := 2
  1452  	stacks := genStacksForLog(size)
  1453  	opBenchmark(b, makeLog(size), stacks...)
  1454  }
  1455  
  1456  func BenchmarkOpLog3(b *testing.B) {
  1457  	size := 3
  1458  	stacks := genStacksForLog(size)
  1459  	opBenchmark(b, makeLog(size), stacks...)
  1460  }
  1461  
  1462  func BenchmarkOpLog4(b *testing.B) {
  1463  	size := 4
  1464  	stacks := genStacksForLog(size)
  1465  	opBenchmark(b, makeLog(size), stacks...)
  1466  }
  1467  
  1468  func BenchmarkOpChainID(b *testing.B) {
  1469  	opBenchmark(b, opChainID)
  1470  }
  1471  
  1472  func BenchmarkOpSelfBalance(b *testing.B) {
  1473  	opBenchmark(b, opSelfBalance)
  1474  }
  1475  
  1476  func BenchmarkOpBaseFee(b *testing.B) {
  1477  	opBenchmark(b, opBaseFee)
  1478  }
  1479  
  1480  func BenchmarkOpBlobHash(b *testing.B) {
  1481  	x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"
  1482  	opBenchmark(b, opBlobHash, x)
  1483  }
  1484  
  1485  func BenchmarkOpBlobBaseFee(b *testing.B) {
  1486  	opBenchmark(b, opBlobBaseFee)
  1487  }
  1488  
  1489  func genStacksForDup(size int) []string {
  1490  	stacks := make([]string, size)
  1491  	return fillStacks(stacks, size)
  1492  }
  1493  
  1494  func genStacksForSwap(size int) []string {
  1495  	stacks := make([]string, size+1)
  1496  	fillStacks(stacks, size)
  1497  	stacks[len(stacks)-1] = "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
  1498  	return stacks
  1499  }
  1500  
  1501  func genStacksForLog(size int) []string {
  1502  	stacks := make([]string, size+2)
  1503  	fillStacks(stacks, size)
  1504  	stacks[len(stacks)-2] = "0000000000000000000000000000000000000000000000000000000000000014" // 20
  1505  	stacks[len(stacks)-1] = "0000000000000000000000000000000000000000000000000000000000000001" // 1
  1506  	return stacks
  1507  }
  1508  
  1509  func fillStacks(stacks []string, n int) []string {
  1510  	for i := 0; i < n; i++ {
  1511  		stacks[i] = "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"
  1512  	}
  1513  	return stacks
  1514  }
  1515  
  1516  func BenchmarkOpMcopy(b *testing.B) {
  1517  	opBenchmark(b, opMcopy, "0x20" /*len*/, "0x20" /*src*/, "0x0" /*dst*/)
  1518  }
  1519  
  1520  func BenchmarkOpTload(b *testing.B) {
  1521  	x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"
  1522  	opBenchmark(b, opTload, x)
  1523  }
  1524  
  1525  func BenchmarkOpTstore(b *testing.B) {
  1526  	x := "ffffffff"
  1527  	y := "ffffffff"
  1528  	opBenchmark(b, opTstore, x, y)
  1529  }
  1530  
  1531  func TestOpMCopy(t *testing.T) {
  1532  	// Test cases from https://eips.ethereum.org/EIPS/eip-5656#test-cases
  1533  	for i, tc := range []struct {
  1534  		dst, src, len string
  1535  		pre           string
  1536  		want          string
  1537  		wantGas       uint64
  1538  	}{
  1539  		{ // MCOPY 0 32 32 - copy 32 bytes from offset 32 to offset 0.
  1540  			dst: "0x0", src: "0x20", len: "0x20",
  1541  			pre:     "0000000000000000000000000000000000000000000000000000000000000000 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
  1542  			want:    "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
  1543  			wantGas: 6,
  1544  		},
  1545  
  1546  		{ // MCOPY 0 0 32 - copy 32 bytes from offset 0 to offset 0.
  1547  			dst: "0x0", src: "0x0", len: "0x20",
  1548  			pre:     "0101010101010101010101010101010101010101010101010101010101010101",
  1549  			want:    "0101010101010101010101010101010101010101010101010101010101010101",
  1550  			wantGas: 6,
  1551  		},
  1552  		{ // MCOPY 0 1 8 - copy 8 bytes from offset 1 to offset 0 (overlapping).
  1553  			dst: "0x0", src: "0x1", len: "0x8",
  1554  			pre:     "000102030405060708 000000000000000000000000000000000000000000000000",
  1555  			want:    "010203040506070808 000000000000000000000000000000000000000000000000",
  1556  			wantGas: 6,
  1557  		},
  1558  		{ // MCOPY 1 0 8 - copy 8 bytes from offset 0 to offset 1 (overlapping).
  1559  			dst: "0x1", src: "0x0", len: "0x8",
  1560  			pre:     "000102030405060708 000000000000000000000000000000000000000000000000",
  1561  			want:    "000001020304050607 000000000000000000000000000000000000000000000000",
  1562  			wantGas: 6,
  1563  		},
  1564  		// Tests below are not in the EIP, but maybe should be added
  1565  		{ // MCOPY 0xFFFFFFFFFFFF 0xFFFFFFFFFFFF 0 - copy zero bytes from out-of-bounds index(overlapping).
  1566  			dst: "0xFFFFFFFFFFFF", src: "0xFFFFFFFFFFFF", len: "0x0",
  1567  			pre:     "11",
  1568  			want:    "11",
  1569  			wantGas: 3,
  1570  		},
  1571  		{ // MCOPY 0xFFFFFFFFFFFF 0 0 - copy zero bytes from start of mem to out-of-bounds.
  1572  			dst: "0xFFFFFFFFFFFF", src: "0x0", len: "0x0",
  1573  			pre:     "11",
  1574  			want:    "11",
  1575  			wantGas: 3,
  1576  		},
  1577  		{ // MCOPY 0 0xFFFFFFFFFFFF 0 - copy zero bytes from out-of-bounds to start of mem
  1578  			dst: "0x0", src: "0xFFFFFFFFFFFF", len: "0x0",
  1579  			pre:     "11",
  1580  			want:    "11",
  1581  			wantGas: 3,
  1582  		},
  1583  		{ // MCOPY - copy 1 from space outside of uint64  space
  1584  			dst: "0x0", src: "0x10000000000000000", len: "0x1",
  1585  			pre: "0",
  1586  		},
  1587  		{ // MCOPY - copy 1 from 0 to space outside of uint64
  1588  			dst: "0x10000000000000000", src: "0x0", len: "0x1",
  1589  			pre: "0",
  1590  		},
  1591  		{ // MCOPY - copy nothing from 0 to space outside of uint64
  1592  			dst: "0x10000000000000000", src: "0x0", len: "0x0",
  1593  			pre:     "",
  1594  			want:    "",
  1595  			wantGas: 3,
  1596  		},
  1597  		{ // MCOPY - copy 1 from 0x20 to 0x10, with no prior allocated mem
  1598  			dst: "0x10", src: "0x20", len: "0x1",
  1599  			pre: "",
  1600  			// 64 bytes
  1601  			want:    "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  1602  			wantGas: 12,
  1603  		},
  1604  		{ // MCOPY - copy 1 from 0x19 to 0x10, with no prior allocated mem
  1605  			dst: "0x10", src: "0x19", len: "0x1",
  1606  			pre: "",
  1607  			// 32 bytes
  1608  			want:    "0x0000000000000000000000000000000000000000000000000000000000000000",
  1609  			wantGas: 9,
  1610  		},
  1611  	} {
  1612  		var (
  1613  			env            = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, &Config{})
  1614  			stack          = newstack()
  1615  			pc             = uint64(0)
  1616  			evmInterpreter = env.interpreter
  1617  		)
  1618  		data := common.FromHex(strings.ReplaceAll(tc.pre, " ", ""))
  1619  		// Set pre
  1620  		mem := NewMemory()
  1621  		mem.Resize(uint64(len(data)))
  1622  		mem.Set(0, uint64(len(data)), data)
  1623  		// Push stack args
  1624  		len, _ := uint256.FromHex(tc.len)
  1625  		src, _ := uint256.FromHex(tc.src)
  1626  		dst, _ := uint256.FromHex(tc.dst)
  1627  
  1628  		stack.push(len)
  1629  		stack.push(src)
  1630  		stack.push(dst)
  1631  		wantErr := (tc.wantGas == 0)
  1632  		// Calc mem expansion
  1633  		var memorySize uint64
  1634  		if memSize, overflow := memoryMcopy(stack); overflow {
  1635  			if wantErr {
  1636  				continue
  1637  			}
  1638  			t.Errorf("overflow")
  1639  		} else {
  1640  			var overflow bool
  1641  			if memorySize, overflow = math.SafeMul(toWordSize(memSize), 32); overflow {
  1642  				t.Error(errGasUintOverflow)
  1643  			}
  1644  		}
  1645  		// and the dynamic cost
  1646  		var haveGas uint64
  1647  		if dynamicCost, err := gasMcopy(env, nil, stack, mem, memorySize); err != nil {
  1648  			t.Error(err)
  1649  		} else {
  1650  			haveGas = GasFastestStep + dynamicCost
  1651  		}
  1652  
  1653  		// Expand mem
  1654  		if memorySize > 0 {
  1655  			mem.Resize(memorySize)
  1656  		}
  1657  		// Do the copy
  1658  		opMcopy(&pc, evmInterpreter, &ScopeContext{mem, stack, nil})
  1659  		want := common.FromHex(strings.ReplaceAll(tc.want, " ", ""))
  1660  		if have := mem.store; !bytes.Equal(want, have) {
  1661  			t.Errorf("case %d: \nwant: %#x\nhave: %#x\n", i, want, have)
  1662  		}
  1663  		wantGas := tc.wantGas
  1664  		if haveGas != wantGas {
  1665  			t.Errorf("case %d: gas wrong, want %d have %d\n", i, wantGas, haveGas)
  1666  		}
  1667  	}
  1668  }