mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 01:43:47 +00:00
vm: more testcases
This commit is contained in:
parent
50cecb8f72
commit
385fd13272
2 changed files with 77 additions and 84 deletions
|
|
@ -308,15 +308,14 @@ func opMulmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *S
|
||||||
func opSHL(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opSHL(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
// Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards
|
// Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards
|
||||||
shift, value := math.U256(stack.pop()), math.U256(stack.peek())
|
shift, value := math.U256(stack.pop()), math.U256(stack.peek())
|
||||||
defer evm.interpreter.intPool.put(shift) // First operand back into the pool
|
defer evm.interpreter.intPool.put(shift) // First operand back into the pool
|
||||||
|
|
||||||
if shift.Cmp(common.Big256) >= 0{
|
if shift.Cmp(common.Big256) >= 0 {
|
||||||
value.SetUint64(0)
|
value.SetUint64(0)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
n := uint( shift.Uint64() )
|
n := uint(shift.Uint64())
|
||||||
math.U256(value.Lsh(value, n))
|
math.U256(value.Lsh(value, n))
|
||||||
evm.interpreter.intPool.put(shift) // First operand back into the pool
|
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
@ -327,13 +326,13 @@ func opSHL(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stac
|
||||||
func opSHR(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opSHR(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
// Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards
|
// Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards
|
||||||
shift, value := math.U256(stack.pop()), math.U256(stack.peek())
|
shift, value := math.U256(stack.pop()), math.U256(stack.peek())
|
||||||
defer evm.interpreter.intPool.put(shift) // First operand back into the pool
|
defer evm.interpreter.intPool.put(shift) // First operand back into the pool
|
||||||
|
|
||||||
if shift.Cmp(common.Big256) >= 0{
|
if shift.Cmp(common.Big256) >= 0 {
|
||||||
value.SetUint64(0)
|
value.SetUint64(0)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
n := uint( shift.Uint64() )
|
n := uint(shift.Uint64())
|
||||||
math.U256(value.Rsh(value, n))
|
math.U256(value.Rsh(value, n))
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
|
@ -345,18 +344,18 @@ func opSHR(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stac
|
||||||
func opSAR(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opSAR(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
// Note, S256 returns (potentially) a new bigint, so we're popping, not peeking this one
|
// Note, S256 returns (potentially) a new bigint, so we're popping, not peeking this one
|
||||||
shift, value := math.U256(stack.pop()), math.S256(stack.pop())
|
shift, value := math.U256(stack.pop()), math.S256(stack.pop())
|
||||||
defer evm.interpreter.intPool.put(shift) // First operand back into the pool
|
defer evm.interpreter.intPool.put(shift) // First operand back into the pool
|
||||||
|
|
||||||
if shift.Cmp(common.Big256) >= 0{
|
if shift.Cmp(common.Big256) >= 0 {
|
||||||
if value.Sign() > 0{
|
if value.Sign() > 0 {
|
||||||
value.SetUint64(0)
|
value.SetUint64(0)
|
||||||
}else{
|
} else {
|
||||||
value.SetInt64(-1)
|
value.SetInt64(-1)
|
||||||
}
|
}
|
||||||
stack.push(math.U256(value))
|
stack.push(math.U256(value))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
n := uint( shift.Uint64() )
|
n := uint(shift.Uint64())
|
||||||
value.Rsh(value, n)
|
value.Rsh(value, n)
|
||||||
stack.push(math.U256(value))
|
stack.push(math.U256(value))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,32 @@ 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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})
|
||||||
|
|
@ -58,18 +84,8 @@ func TestByteOp(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSHL(t *testing.T) {
|
func TestSHL(t *testing.T) {
|
||||||
var (
|
|
||||||
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{EnableJit: false, ForceJit: false})
|
|
||||||
stack = newstack()
|
|
||||||
pc = uint64(0)
|
|
||||||
)
|
|
||||||
|
|
||||||
// Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#shl-shift-left
|
// Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#shl-shift-left
|
||||||
tests := []struct {
|
tests := []twoOperandTest{
|
||||||
x string
|
|
||||||
y string
|
|
||||||
expected string
|
|
||||||
}{
|
|
||||||
{"0000000000000000000000000000000000000000000000000000000000000001", "00", "0000000000000000000000000000000000000000000000000000000000000001"},
|
{"0000000000000000000000000000000000000000000000000000000000000001", "00", "0000000000000000000000000000000000000000000000000000000000000001"},
|
||||||
{"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000002"},
|
{"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000002"},
|
||||||
{"0000000000000000000000000000000000000000000000000000000000000001", "ff", "8000000000000000000000000000000000000000000000000000000000000000"},
|
{"0000000000000000000000000000000000000000000000000000000000000001", "ff", "8000000000000000000000000000000000000000000000000000000000000000"},
|
||||||
|
|
@ -82,34 +98,12 @@ func TestSHL(t *testing.T) {
|
||||||
{"0000000000000000000000000000000000000000000000000000000000000000", "01", "0000000000000000000000000000000000000000000000000000000000000000"},
|
{"0000000000000000000000000000000000000000000000000000000000000000", "01", "0000000000000000000000000000000000000000000000000000000000000000"},
|
||||||
{"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "01", "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},
|
{"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "01", "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},
|
||||||
}
|
}
|
||||||
|
testTwoOperandOp(t, tests, opSHL)
|
||||||
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)
|
|
||||||
opSHL(&pc, env, nil, nil, stack)
|
|
||||||
actual := stack.pop()
|
|
||||||
if actual.Cmp(expected) != 0 {
|
|
||||||
t.Errorf("Testcase %d, expected %v, got %v", i, expected, actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSHR(t *testing.T) {
|
func TestSHR(t *testing.T) {
|
||||||
var (
|
|
||||||
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{EnableJit: false, ForceJit: false})
|
|
||||||
stack = newstack()
|
|
||||||
pc = uint64(0)
|
|
||||||
)
|
|
||||||
|
|
||||||
// Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#shr-logical-shift-right
|
// Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#shr-logical-shift-right
|
||||||
tests := []struct {
|
tests := []twoOperandTest{
|
||||||
x string
|
|
||||||
y string
|
|
||||||
expected string
|
|
||||||
}{
|
|
||||||
{"0000000000000000000000000000000000000000000000000000000000000001", "00", "0000000000000000000000000000000000000000000000000000000000000001"},
|
{"0000000000000000000000000000000000000000000000000000000000000001", "00", "0000000000000000000000000000000000000000000000000000000000000001"},
|
||||||
{"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000000"},
|
{"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000000"},
|
||||||
{"8000000000000000000000000000000000000000000000000000000000000000", "01", "4000000000000000000000000000000000000000000000000000000000000000"},
|
{"8000000000000000000000000000000000000000000000000000000000000000", "01", "4000000000000000000000000000000000000000000000000000000000000000"},
|
||||||
|
|
@ -122,34 +116,12 @@ func TestSHR(t *testing.T) {
|
||||||
{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0100", "0000000000000000000000000000000000000000000000000000000000000000"},
|
{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0100", "0000000000000000000000000000000000000000000000000000000000000000"},
|
||||||
{"0000000000000000000000000000000000000000000000000000000000000000", "01", "0000000000000000000000000000000000000000000000000000000000000000"},
|
{"0000000000000000000000000000000000000000000000000000000000000000", "01", "0000000000000000000000000000000000000000000000000000000000000000"},
|
||||||
}
|
}
|
||||||
|
testTwoOperandOp(t, tests, opSHR)
|
||||||
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)
|
|
||||||
opSHR(&pc, env, nil, nil, stack)
|
|
||||||
actual := stack.pop()
|
|
||||||
if actual.Cmp(expected) != 0 {
|
|
||||||
t.Fatalf("Testcase %d, expected %v, got %v", i, expected, actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSAR(t *testing.T) {
|
func TestSAR(t *testing.T) {
|
||||||
var (
|
|
||||||
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{EnableJit: false, ForceJit: false})
|
|
||||||
stack = newstack()
|
|
||||||
pc = uint64(0)
|
|
||||||
)
|
|
||||||
|
|
||||||
// Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#sar-arithmetic-shift-right
|
// Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#sar-arithmetic-shift-right
|
||||||
tests := []struct {
|
tests := []twoOperandTest{
|
||||||
x string
|
|
||||||
y string
|
|
||||||
expected string
|
|
||||||
}{
|
|
||||||
{"0000000000000000000000000000000000000000000000000000000000000001", "00", "0000000000000000000000000000000000000000000000000000000000000001"},
|
{"0000000000000000000000000000000000000000000000000000000000000001", "00", "0000000000000000000000000000000000000000000000000000000000000001"},
|
||||||
{"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000000"},
|
{"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000000"},
|
||||||
{"8000000000000000000000000000000000000000000000000000000000000000", "01", "c000000000000000000000000000000000000000000000000000000000000000"},
|
{"8000000000000000000000000000000000000000000000000000000000000000", "01", "c000000000000000000000000000000000000000000000000000000000000000"},
|
||||||
|
|
@ -168,19 +140,41 @@ func TestSAR(t *testing.T) {
|
||||||
{"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0100", "0000000000000000000000000000000000000000000000000000000000000000"},
|
{"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0100", "0000000000000000000000000000000000000000000000000000000000000000"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, test := range tests {
|
testTwoOperandOp(t, tests, opSAR)
|
||||||
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)
|
|
||||||
opSAR(&pc, env, nil, nil, stack)
|
|
||||||
actual := stack.pop()
|
|
||||||
if actual.Cmp(expected) != 0 {
|
|
||||||
t.Fatalf("Testcase %d, expected %X, got %X", i, expected, actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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})
|
||||||
|
|
@ -401,4 +395,4 @@ func BenchmarkOpSAR(b *testing.B) {
|
||||||
y := "ff"
|
y := "ff"
|
||||||
|
|
||||||
opBenchmark(b, opSAR, x, y)
|
opBenchmark(b, opSAR, x, y)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue