// Copyright 2017 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package vm
import (
"bytes"
"math/big"
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/harmony-one/harmony/internal/params"
)
type twoOperandTest struct {
x string
y string
expected string
}
func testTwoOperandOp ( t * testing . T , tests [ ] twoOperandTest , opFn func ( pc * uint64 , interpreter * EVMInterpreter , contract * Contract , memory * Memory , stack * Stack ) ( [ ] byte , error ) ) {
var (
env = NewEVM ( Context { } , nil , params . TestChainConfig , Config { } )
stack = newstack ( )
pc = uint64 ( 0 )
evmInterpreter = NewEVMInterpreter ( env , env . vmConfig )
)
env . interpreter = evmInterpreter
evmInterpreter . intPool = poolOfIntPools . get ( )
for i , test := range tests {
x := new ( big . Int ) . SetBytes ( common . Hex2Bytes ( test . x ) )
shift := new ( big . Int ) . SetBytes ( common . Hex2Bytes ( test . y ) )
expected := new ( big . Int ) . SetBytes ( common . Hex2Bytes ( test . expected ) )
stack . push ( x )
stack . push ( shift )
opFn ( & pc , evmInterpreter , nil , nil , stack )
actual := stack . pop ( )
if actual . Cmp ( expected ) != 0 {
t . Errorf ( "Testcase %d, expected %v, got %v" , i , expected , actual )
}
// Check pool usage
// 1.pool is not allowed to contain anything on the stack
// 2.pool is not allowed to contain the same pointers twice
if evmInterpreter . intPool . pool . len ( ) > 0 {
poolvals := make ( map [ * big . Int ] struct { } )
poolvals [ actual ] = struct { } { }
for evmInterpreter . intPool . pool . len ( ) > 0 {
key := evmInterpreter . intPool . get ( )
if _ , exist := poolvals [ key ] ; exist {
t . Errorf ( "Testcase %d, pool contains double-entry" , i )
}
poolvals [ key ] = struct { } { }
}
}
}
poolOfIntPools . put ( evmInterpreter . intPool )
}
func TestByteOp ( t * testing . T ) {
var (
env = NewEVM ( Context { } , nil , params . TestChainConfig , Config { } )
stack = newstack ( )
evmInterpreter = NewEVMInterpreter ( env , env . vmConfig )
)
env . interpreter = evmInterpreter
evmInterpreter . intPool = poolOfIntPools . get ( )
tests := [ ] struct {
v string
th uint64
expected * big . Int
} {
{ "ABCDEF0908070605040302010000000000000000000000000000000000000000" , 0 , big . NewInt ( 0xAB ) } ,
{ "ABCDEF0908070605040302010000000000000000000000000000000000000000" , 1 , big . NewInt ( 0xCD ) } ,
{ "00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" , 0 , big . NewInt ( 0x00 ) } ,
{ "00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" , 1 , big . NewInt ( 0xCD ) } ,
{ "0000000000000000000000000000000000000000000000000000000000102030" , 31 , big . NewInt ( 0x30 ) } ,
{ "0000000000000000000000000000000000000000000000000000000000102030" , 30 , big . NewInt ( 0x20 ) } ,
{ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , 32 , big . NewInt ( 0x0 ) } ,
{ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , 0xFFFFFFFFFFFFFFFF , big . NewInt ( 0x0 ) } ,
}
pc := uint64 ( 0 )
for _ , test := range tests {
val := new ( big . Int ) . SetBytes ( common . Hex2Bytes ( test . v ) )
th := new ( big . Int ) . SetUint64 ( test . th )
stack . push ( val )
stack . push ( th )
opByte ( & pc , evmInterpreter , nil , nil , stack )
actual := stack . pop ( )
if actual . Cmp ( test . expected ) != 0 {
t . Fatalf ( "Expected [%v] %v:th byte to be %v, was %v." , test . v , test . th , test . expected , actual )
}
}
poolOfIntPools . put ( evmInterpreter . intPool )
}
func TestSHL ( t * testing . T ) {
// Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#shl-shift-left
tests := [ ] twoOperandTest {
{ "0000000000000000000000000000000000000000000000000000000000000001" , "00" , "0000000000000000000000000000000000000000000000000000000000000001" } ,
{ "0000000000000000000000000000000000000000000000000000000000000001" , "01" , "0000000000000000000000000000000000000000000000000000000000000002" } ,
{ "0000000000000000000000000000000000000000000000000000000000000001" , "ff" , "8000000000000000000000000000000000000000000000000000000000000000" } ,
{ "0000000000000000000000000000000000000000000000000000000000000001" , "0100" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
{ "0000000000000000000000000000000000000000000000000000000000000001" , "0101" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
{ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "00" , "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" } ,
{ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "01" , "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" } ,
{ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "ff" , "8000000000000000000000000000000000000000000000000000000000000000" } ,
{ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "0100" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
{ "0000000000000000000000000000000000000000000000000000000000000000" , "01" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
{ "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "01" , "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" } ,
}
testTwoOperandOp ( t , tests , opSHL )
}
func TestSHR ( t * testing . T ) {
// Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#shr-logical-shift-right
tests := [ ] twoOperandTest {
{ "0000000000000000000000000000000000000000000000000000000000000001" , "00" , "0000000000000000000000000000000000000000000000000000000000000001" } ,
{ "0000000000000000000000000000000000000000000000000000000000000001" , "01" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
{ "8000000000000000000000000000000000000000000000000000000000000000" , "01" , "4000000000000000000000000000000000000000000000000000000000000000" } ,
{ "8000000000000000000000000000000000000000000000000000000000000000" , "ff" , "0000000000000000000000000000000000000000000000000000000000000001" } ,
{ "8000000000000000000000000000000000000000000000000000000000000000" , "0100" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
{ "8000000000000000000000000000000000000000000000000000000000000000" , "0101" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
{ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "00" , "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" } ,
{ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "01" , "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" } ,
{ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "ff" , "0000000000000000000000000000000000000000000000000000000000000001" } ,
{ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "0100" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
{ "0000000000000000000000000000000000000000000000000000000000000000" , "01" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
}
testTwoOperandOp ( t , tests , opSHR )
}
func TestSAR ( t * testing . T ) {
// Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#sar-arithmetic-shift-right
tests := [ ] twoOperandTest {
{ "0000000000000000000000000000000000000000000000000000000000000001" , "00" , "0000000000000000000000000000000000000000000000000000000000000001" } ,
{ "0000000000000000000000000000000000000000000000000000000000000001" , "01" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
{ "8000000000000000000000000000000000000000000000000000000000000000" , "01" , "c000000000000000000000000000000000000000000000000000000000000000" } ,
{ "8000000000000000000000000000000000000000000000000000000000000000" , "ff" , "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" } ,
{ "8000000000000000000000000000000000000000000000000000000000000000" , "0100" , "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" } ,
{ "8000000000000000000000000000000000000000000000000000000000000000" , "0101" , "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" } ,
{ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "00" , "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" } ,
{ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "01" , "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" } ,
{ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "ff" , "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" } ,
{ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "0100" , "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" } ,
{ "0000000000000000000000000000000000000000000000000000000000000000" , "01" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
{ "4000000000000000000000000000000000000000000000000000000000000000" , "fe" , "0000000000000000000000000000000000000000000000000000000000000001" } ,
{ "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "f8" , "000000000000000000000000000000000000000000000000000000000000007f" } ,
{ "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "fe" , "0000000000000000000000000000000000000000000000000000000000000001" } ,
{ "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "ff" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
{ "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "0100" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
}
testTwoOperandOp ( t , tests , opSAR )
}
func TestSGT ( t * testing . T ) {
tests := [ ] twoOperandTest {
{ "0000000000000000000000000000000000000000000000000000000000000001" , "0000000000000000000000000000000000000000000000000000000000000001" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
{ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
{ "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
{ "0000000000000000000000000000000000000000000000000000000000000001" , "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "0000000000000000000000000000000000000000000000000000000000000001" } ,
{ "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "0000000000000000000000000000000000000000000000000000000000000001" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
{ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "0000000000000000000000000000000000000000000000000000000000000001" , "0000000000000000000000000000000000000000000000000000000000000001" } ,
{ "0000000000000000000000000000000000000000000000000000000000000001" , "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
{ "8000000000000000000000000000000000000000000000000000000000000001" , "8000000000000000000000000000000000000000000000000000000000000001" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
{ "8000000000000000000000000000000000000000000000000000000000000001" , "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "0000000000000000000000000000000000000000000000000000000000000001" } ,
{ "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "8000000000000000000000000000000000000000000000000000000000000001" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
{ "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb" , "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd" , "0000000000000000000000000000000000000000000000000000000000000001" } ,
{ "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd" , "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
}
testTwoOperandOp ( t , tests , opSgt )
}
func TestSLT ( t * testing . T ) {
tests := [ ] twoOperandTest {
{ "0000000000000000000000000000000000000000000000000000000000000001" , "0000000000000000000000000000000000000000000000000000000000000001" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
{ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
{ "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
{ "0000000000000000000000000000000000000000000000000000000000000001" , "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
{ "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "0000000000000000000000000000000000000000000000000000000000000001" , "0000000000000000000000000000000000000000000000000000000000000001" } ,
{ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "0000000000000000000000000000000000000000000000000000000000000001" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
{ "0000000000000000000000000000000000000000000000000000000000000001" , "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "0000000000000000000000000000000000000000000000000000000000000001" } ,
{ "8000000000000000000000000000000000000000000000000000000000000001" , "8000000000000000000000000000000000000000000000000000000000000001" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
{ "8000000000000000000000000000000000000000000000000000000000000001" , "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
{ "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" , "8000000000000000000000000000000000000000000000000000000000000001" , "0000000000000000000000000000000000000000000000000000000000000001" } ,
{ "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb" , "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd" , "0000000000000000000000000000000000000000000000000000000000000000" } ,
{ "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd" , "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb" , "0000000000000000000000000000000000000000000000000000000000000001" } ,
}
testTwoOperandOp ( t , tests , opSlt )
}
func opBenchmark ( bench * testing . B , op func ( pc * uint64 , interpreter * EVMInterpreter , contract * Contract , memory * Memory , stack * Stack ) ( [ ] byte , error ) , args ... string ) {
var (
env = NewEVM ( Context { } , nil , params . TestChainConfig , Config { } )
stack = newstack ( )
evmInterpreter = NewEVMInterpreter ( env , env . vmConfig )
)
env . interpreter = evmInterpreter
evmInterpreter . intPool = poolOfIntPools . get ( )
// convert args
byteArgs := make ( [ ] [ ] byte , len ( args ) )
for i , arg := range args {
byteArgs [ i ] = common . Hex2Bytes ( arg )
}
pc := uint64 ( 0 )
bench . ResetTimer ( )
for i := 0 ; i < bench . N ; i ++ {
for _ , arg := range byteArgs {
a := new ( big . Int ) . SetBytes ( arg )
stack . push ( a )
}
op ( & pc , evmInterpreter , nil , nil , stack )
stack . pop ( )
}
poolOfIntPools . put ( evmInterpreter . intPool )
}
func BenchmarkOpAdd64 ( b * testing . B ) {
x := "ffffffff"
y := "fd37f3e2bba2c4f"
opBenchmark ( b , opAdd , x , y )
}
func BenchmarkOpAdd128 ( b * testing . B ) {
x := "ffffffffffffffff"
y := "f5470b43c6549b016288e9a65629687"
opBenchmark ( b , opAdd , x , y )
}
func BenchmarkOpAdd256 ( b * testing . B ) {
x := "0802431afcbce1fc194c9eaa417b2fb67dc75a95db0bc7ec6b1c8af11df6a1da9"
y := "a1f5aac137876480252e5dcac62c354ec0d42b76b0642b6181ed099849ea1d57"
opBenchmark ( b , opAdd , x , y )
}
func BenchmarkOpSub64 ( b * testing . B ) {
x := "51022b6317003a9d"
y := "a20456c62e00753a"
opBenchmark ( b , opSub , x , y )
}
func BenchmarkOpSub128 ( b * testing . B ) {
x := "4dde30faaacdc14d00327aac314e915d"
y := "9bbc61f5559b829a0064f558629d22ba"
opBenchmark ( b , opSub , x , y )
}
func BenchmarkOpSub256 ( b * testing . B ) {
x := "4bfcd8bb2ac462735b48a17580690283980aa2d679f091c64364594df113ea37"
y := "97f9b1765588c4e6b69142eb00d20507301545acf3e1238c86c8b29be227d46e"
opBenchmark ( b , opSub , x , y )
}
func BenchmarkOpMul ( b * testing . B ) {
x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
opBenchmark ( b , opMul , x , y )
}
func BenchmarkOpDiv256 ( b * testing . B ) {
x := "ff3f9014f20db29ae04af2c2d265de17"
y := "fe7fb0d1f59dfe9492ffbf73683fd1e870eec79504c60144cc7f5fc2bad1e611"
opBenchmark ( b , opDiv , x , y )
}
func BenchmarkOpDiv128 ( b * testing . B ) {
x := "fdedc7f10142ff97"
y := "fbdfda0e2ce356173d1993d5f70a2b11"
opBenchmark ( b , opDiv , x , y )
}
func BenchmarkOpDiv64 ( b * testing . B ) {
x := "fcb34eb3"
y := "f97180878e839129"
opBenchmark ( b , opDiv , x , y )
}
func BenchmarkOpSdiv ( b * testing . B ) {
x := "ff3f9014f20db29ae04af2c2d265de17"
y := "fe7fb0d1f59dfe9492ffbf73683fd1e870eec79504c60144cc7f5fc2bad1e611"
opBenchmark ( b , opSdiv , x , y )
}
func BenchmarkOpMod ( b * testing . B ) {
x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
opBenchmark ( b , opMod , x , y )
}
func BenchmarkOpSmod ( b * testing . B ) {
x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
opBenchmark ( b , opSmod , x , y )
}
func BenchmarkOpExp ( b * testing . B ) {
x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
opBenchmark ( b , opExp , x , y )
}
func BenchmarkOpSignExtend ( b * testing . B ) {
x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
opBenchmark ( b , opSignExtend , x , y )
}
func BenchmarkOpLt ( b * testing . B ) {
x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
opBenchmark ( b , opLt , x , y )
}
func BenchmarkOpGt ( b * testing . B ) {
x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
opBenchmark ( b , opGt , x , y )
}
func BenchmarkOpSlt ( b * testing . B ) {
x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
opBenchmark ( b , opSlt , x , y )
}
func BenchmarkOpSgt ( b * testing . B ) {
x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
opBenchmark ( b , opSgt , x , y )
}
func BenchmarkOpEq ( b * testing . B ) {
x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
opBenchmark ( b , opEq , x , y )
}
func BenchmarkOpEq2 ( b * testing . B ) {
x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"
y := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201fffffffe"
opBenchmark ( b , opEq , x , y )
}
func BenchmarkOpAnd ( b * testing . B ) {
x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
opBenchmark ( b , opAnd , x , y )
}
func BenchmarkOpOr ( b * testing . B ) {
x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
opBenchmark ( b , opOr , x , y )
}
func BenchmarkOpXor ( b * testing . B ) {
x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
opBenchmark ( b , opXor , x , y )
}
func BenchmarkOpByte ( b * testing . B ) {
x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
opBenchmark ( b , opByte , x , y )
}
func BenchmarkOpAddmod ( b * testing . B ) {
x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
z := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
opBenchmark ( b , opAddmod , x , y , z )
}
func BenchmarkOpMulmod ( b * testing . B ) {
x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
z := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
opBenchmark ( b , opMulmod , x , y , z )
}
func BenchmarkOpSHL ( b * testing . B ) {
x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"
y := "ff"
opBenchmark ( b , opSHL , x , y )
}
func BenchmarkOpSHR ( b * testing . B ) {
x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"
y := "ff"
opBenchmark ( b , opSHR , x , y )
}
func BenchmarkOpSAR ( b * testing . B ) {
x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"
y := "ff"
opBenchmark ( b , opSAR , x , y )
}
func BenchmarkOpIsZero ( b * testing . B ) {
x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"
opBenchmark ( b , opIszero , x )
}
func TestOpMstore ( t * testing . T ) {
var (
env = NewEVM ( Context { } , nil , params . TestChainConfig , Config { } )
stack = newstack ( )
mem = NewMemory ( )
evmInterpreter = NewEVMInterpreter ( env , env . vmConfig )
)
env . interpreter = evmInterpreter
evmInterpreter . intPool = poolOfIntPools . get ( )
mem . Resize ( 64 )
pc := uint64 ( 0 )
v := "abcdef00000000000000abba000000000deaf000000c0de00100000000133700"
stack . pushN ( new ( big . Int ) . SetBytes ( common . Hex2Bytes ( v ) ) , big . NewInt ( 0 ) )
opMstore ( & pc , evmInterpreter , nil , mem , stack )
if got := common . Bytes2Hex ( mem . Get ( 0 , 32 ) ) ; got != v {
t . Fatalf ( "Mstore fail, got %v, expected %v" , got , v )
}
stack . pushN ( big . NewInt ( 0x1 ) , big . NewInt ( 0 ) )
opMstore ( & pc , evmInterpreter , nil , mem , stack )
if common . Bytes2Hex ( mem . Get ( 0 , 32 ) ) != "0000000000000000000000000000000000000000000000000000000000000001" {
t . Fatalf ( "Mstore failed to overwrite previous value" )
}
poolOfIntPools . put ( evmInterpreter . intPool )
}
func BenchmarkOpMstore ( bench * testing . B ) {
var (
env = NewEVM ( Context { } , nil , params . TestChainConfig , Config { } )
stack = newstack ( )
mem = NewMemory ( )
evmInterpreter = NewEVMInterpreter ( env , env . vmConfig )
)
env . interpreter = evmInterpreter
evmInterpreter . intPool = poolOfIntPools . get ( )
mem . Resize ( 64 )
pc := uint64 ( 0 )
memStart := big . NewInt ( 0 )
value := big . NewInt ( 0x1337 )
bench . ResetTimer ( )
for i := 0 ; i < bench . N ; i ++ {
stack . pushN ( value , memStart )
opMstore ( & pc , evmInterpreter , nil , mem , stack )
}
poolOfIntPools . put ( evmInterpreter . intPool )
}
func BenchmarkOpSHA3 ( bench * testing . B ) {
var (
env = NewEVM ( Context { } , nil , params . TestChainConfig , Config { } )
stack = newstack ( )
mem = NewMemory ( )
evmInterpreter = NewEVMInterpreter ( env , env . vmConfig )
)
env . interpreter = evmInterpreter
evmInterpreter . intPool = poolOfIntPools . get ( )
mem . Resize ( 32 )
pc := uint64 ( 0 )
start := big . NewInt ( 0 )
bench . ResetTimer ( )
for i := 0 ; i < bench . N ; i ++ {
stack . pushN ( big . NewInt ( 32 ) , start )
opSha3 ( & pc , evmInterpreter , nil , mem , stack )
}
poolOfIntPools . put ( evmInterpreter . intPool )
}
func TestCreate2Addreses ( t * testing . T ) {
type testcase struct {
origin string
salt string
code string
expected string
}
for i , tt := range [ ] testcase {
{
origin : "0x0000000000000000000000000000000000000000" ,
salt : "0x0000000000000000000000000000000000000000" ,
code : "0x00" ,
expected : "0x4d1a2e2bb4f88f0250f26ffff098b0b30b26bf38" ,
} ,
{
origin : "0xdeadbeef00000000000000000000000000000000" ,
salt : "0x0000000000000000000000000000000000000000" ,
code : "0x00" ,
expected : "0xB928f69Bb1D91Cd65274e3c79d8986362984fDA3" ,
} ,
{
origin : "0xdeadbeef00000000000000000000000000000000" ,
salt : "0xfeed000000000000000000000000000000000000" ,
code : "0x00" ,
expected : "0xD04116cDd17beBE565EB2422F2497E06cC1C9833" ,
} ,
{
origin : "0x0000000000000000000000000000000000000000" ,
salt : "0x0000000000000000000000000000000000000000" ,
code : "0xdeadbeef" ,
expected : "0x70f2b2914A2a4b783FaEFb75f459A580616Fcb5e" ,
} ,
{
origin : "0x00000000000000000000000000000000deadbeef" ,
salt : "0xcafebabe" ,
code : "0xdeadbeef" ,
expected : "0x60f3f640a8508fC6a86d45DF051962668E1e8AC7" ,
} ,
{
origin : "0x00000000000000000000000000000000deadbeef" ,
salt : "0xcafebabe" ,
code : "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef" ,
expected : "0x1d8bfDC5D46DC4f61D6b6115972536eBE6A8854C" ,
} ,
{
origin : "0x0000000000000000000000000000000000000000" ,
salt : "0x0000000000000000000000000000000000000000" ,
code : "0x" ,
expected : "0xE33C0C7F7df4809055C3ebA6c09CFe4BaF1BD9e0" ,
} ,
} {
origin := common . BytesToAddress ( common . FromHex ( tt . origin ) )
salt := common . BytesToHash ( common . FromHex ( tt . salt ) )
code := common . FromHex ( tt . code )
codeHash := crypto . Keccak256 ( code )
address := crypto . CreateAddress2 ( origin , salt , codeHash )
/ *
stack := newstack ( )
// salt, but we don't need that for this test
stack . push ( big . NewInt ( int64 ( len ( code ) ) ) ) //size
stack . push ( big . NewInt ( 0 ) ) // memstart
stack . push ( big . NewInt ( 0 ) ) // value
gas , _ := gasCreate2 ( params . GasTable { } , nil , nil , stack , nil , 0 )
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 ( ) )
* /
expected := common . BytesToAddress ( common . FromHex ( tt . expected ) )
if ! bytes . Equal ( expected . Bytes ( ) , address . Bytes ( ) ) {
t . Errorf ( "test %d: expected %s, got %s" , i , expected . String ( ) , address . String ( ) )
}
}
}