diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go index e36ef521a..55133c3e2 100644 --- a/pkg/vm/vm.go +++ b/pkg/vm/vm.go @@ -53,7 +53,6 @@ const ( MaxStackSize = 2 * 1024 maxSHLArg = MaxBigIntegerSizeBits - minSHLArg = -MaxBigIntegerSizeBits ) // VM represents the virtual machine. @@ -797,23 +796,14 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro b := v.estack.Pop().BigInt().Int64() if b == 0 { return - } else if b < minSHLArg || b > maxSHLArg { - panic(fmt.Sprintf("operand must be between %d and %d", minSHLArg, maxSHLArg)) + } else if b < 0 || b > maxSHLArg { + panic(fmt.Sprintf("operand must be between %d and %d", 0, maxSHLArg)) } a := v.estack.Pop().BigInt() v.checkBigIntSize(a) - newOp := op - if b < 0 { - b = -b - if op == opcode.SHR { - newOp = opcode.SHL - } else { - newOp = opcode.SHR - } - } var item big.Int - if newOp == opcode.SHL { + if op == opcode.SHL { item.Lsh(a, uint(b)) } else { item.Rsh(a, uint(b)) diff --git a/pkg/vm/vm_test.go b/pkg/vm/vm_test.go index dc847bef5..24e77eea0 100644 --- a/pkg/vm/vm_test.go +++ b/pkg/vm/vm_test.go @@ -884,16 +884,12 @@ func TestArithNegativeArguments(t *testing.T) { t.Run("SHR", func(t *testing.T) { t.Run("positive/positive", runCase(opcode.SHR, 5, 2, 1)) - t.Run("positive/negative", runCase(opcode.SHR, 5, -2, 20)) t.Run("negative/positive", runCase(opcode.SHR, -5, 2, -2)) - t.Run("negative/negative", runCase(opcode.SHR, -5, -2, -20)) }) t.Run("SHL", func(t *testing.T) { t.Run("positive/positive", runCase(opcode.SHL, 5, 2, 20)) - t.Run("positive/negative", runCase(opcode.SHL, 5, -2, 1)) t.Run("negative/positive", runCase(opcode.SHL, -5, 2, -20)) - t.Run("negative/negative", runCase(opcode.SHL, -5, -2, -2)) }) } @@ -934,11 +930,11 @@ func TestSHRZero(t *testing.T) { assert.Equal(t, makeStackItem([]byte{0, 1}), vm.estack.Pop().value) } -func TestSHRSmallValue(t *testing.T) { +func TestSHRNegative(t *testing.T) { prog := makeProgram(opcode.SHR) vm := load(prog) vm.estack.PushVal(5) - vm.estack.PushVal(minSHLArg - 1) + vm.estack.PushVal(-1) checkVMFailed(t, vm) }