diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go index 71793c0fc..1a62206a5 100644 --- a/pkg/vm/vm.go +++ b/pkg/vm/vm.go @@ -388,13 +388,11 @@ func (v *VM) execute(ctx *Context, op Instruction) { v.estack.InsertAt(a, n) case ROT: - c := v.estack.Pop() - b := v.estack.Pop() - a := v.estack.Pop() - - v.estack.Push(b) - v.estack.Push(c) - v.estack.Push(a) + e := v.estack.RemoveAt(2) + if e == nil { + panic("no top-level element found") + } + v.estack.Push(e) case DEPTH: v.estack.PushVal(v.estack.Len()) diff --git a/pkg/vm/vm_test.go b/pkg/vm/vm_test.go index 1628c95b7..e402887eb 100644 --- a/pkg/vm/vm_test.go +++ b/pkg/vm/vm_test.go @@ -659,6 +659,29 @@ func TestPICKgood(t *testing.T) { assert.Equal(t, int64(result), vm.estack.Pop().BigInt().Int64()) } +func TestROTBad(t *testing.T) { + prog := makeProgram(ROT) + vm := load(prog) + vm.estack.PushVal(1) + vm.estack.PushVal(2) + vm.Run() + assert.Equal(t, true, vm.state.HasFlag(faultState)) +} + +func TestROTGood(t *testing.T) { + prog := makeProgram(ROT) + vm := load(prog) + vm.estack.PushVal(1) + vm.estack.PushVal(2) + vm.estack.PushVal(3) + vm.Run() + assert.Equal(t, false, vm.state.HasFlag(faultState)) + assert.Equal(t, 3, vm.estack.Len()) + assert.Equal(t, makeStackItem(1), vm.estack.Pop().value) + assert.Equal(t, makeStackItem(3), vm.estack.Pop().value) + assert.Equal(t, makeStackItem(2), vm.estack.Pop().value) +} + func TestXTUCKbadNoitem(t *testing.T) { prog := makeProgram(XTUCK) vm := load(prog)