|
|
@ -24,6 +24,48 @@ import ( |
|
|
|
"github.com/ethereum/go-ethereum/params" |
|
|
|
"github.com/ethereum/go-ethereum/params" |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type twoOperandTest struct { |
|
|
|
|
|
|
|
x string |
|
|
|
|
|
|
|
y string |
|
|
|
|
|
|
|
expected string |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func testTwoOperandOp(t *testing.T, tests []twoOperandTest, opFn func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error)) { |
|
|
|
|
|
|
|
var ( |
|
|
|
|
|
|
|
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{EnableJit: false, ForceJit: false}) |
|
|
|
|
|
|
|
stack = newstack() |
|
|
|
|
|
|
|
pc = uint64(0) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
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, env, 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 env.interpreter.intPool.pool.len() > 0 { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
poolvals := make(map[*big.Int]struct{}) |
|
|
|
|
|
|
|
poolvals[actual] = struct{}{} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for env.interpreter.intPool.pool.len() > 0 { |
|
|
|
|
|
|
|
key := env.interpreter.intPool.get() |
|
|
|
|
|
|
|
if _, exist := poolvals[key]; exist { |
|
|
|
|
|
|
|
t.Errorf("Testcase %d, pool contains double-entry", i) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
poolvals[key] = struct{}{} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestByteOp(t *testing.T) { |
|
|
|
func TestByteOp(t *testing.T) { |
|
|
|
var ( |
|
|
|
var ( |
|
|
|
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{EnableJit: false, ForceJit: false}) |
|
|
|
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{EnableJit: false, ForceJit: false}) |
|
|
@ -57,6 +99,98 @@ func TestByteOp(t *testing.T) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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"}, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
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"}, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
testTwoOperandOp(t, tests, opSlt) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func opBenchmark(bench *testing.B, op func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error), args ...string) { |
|
|
|
func opBenchmark(bench *testing.B, op func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error), args ...string) { |
|
|
|
var ( |
|
|
|
var ( |
|
|
|
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{EnableJit: false, ForceJit: false}) |
|
|
|
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{EnableJit: false, ForceJit: false}) |
|
|
@ -259,3 +393,22 @@ func BenchmarkOpMulmod(b *testing.B) { |
|
|
|
|
|
|
|
|
|
|
|
opBenchmark(b, opMulmod, x, y, z) |
|
|
|
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) |
|
|
|
|
|
|
|
} |
|
|
|