diff --git a/pkg/core/fee/opcode.go b/pkg/core/fee/opcode.go index ba9e9a558..0a668a0df 100644 --- a/pkg/core/fee/opcode.go +++ b/pkg/core/fee/opcode.go @@ -70,6 +70,8 @@ var coefficients = [256]uint16{ opcode.CALLT: 1 << 15, opcode.ABORT: 0, opcode.ASSERT: 1 << 0, + opcode.ABORTMSG: 0, // TODO + opcode.ASSERTMSG: 1 << 0, // TODO opcode.THROW: 1 << 9, opcode.TRY: 1 << 2, opcode.TRYL: 1 << 2, diff --git a/pkg/vm/opcode/opcode.go b/pkg/vm/opcode/opcode.go index 847e5c400..3cb5c4664 100644 --- a/pkg/vm/opcode/opcode.go +++ b/pkg/vm/opcode/opcode.go @@ -225,6 +225,10 @@ const ( ISNULL Opcode = 0xD8 ISTYPE Opcode = 0xD9 CONVERT Opcode = 0xDB + + // Extensions. + ABORTMSG Opcode = 0xE0 + ASSERTMSG Opcode = 0xE1 ) var validCodes [256]bool diff --git a/pkg/vm/opcode/opcode_string.go b/pkg/vm/opcode/opcode_string.go index ee4e7e2e5..1c9456b93 100644 --- a/pkg/vm/opcode/opcode_string.go +++ b/pkg/vm/opcode/opcode_string.go @@ -202,9 +202,11 @@ func _() { _ = x[ISNULL-216] _ = x[ISTYPE-217] _ = x[CONVERT-219] + _ = x[ABORTMSG-224] + _ = x[ASSERTMSG-225] } -const _Opcode_name = "PUSHINT8PUSHINT16PUSHINT32PUSHINT64PUSHINT128PUSHINT256PUSHTPUSHFPUSHAPUSHNULLPUSHDATA1PUSHDATA2PUSHDATA4PUSHM1PUSH0PUSH1PUSH2PUSH3PUSH4PUSH5PUSH6PUSH7PUSH8PUSH9PUSH10PUSH11PUSH12PUSH13PUSH14PUSH15PUSH16NOPJMPJMP_LJMPIFJMPIF_LJMPIFNOTJMPIFNOT_LJMPEQJMPEQ_LJMPNEJMPNE_LJMPGTJMPGT_LJMPGEJMPGE_LJMPLTJMPLT_LJMPLEJMPLE_LCALLCALL_LCALLACALLTABORTASSERTTHROWTRYTRY_LENDTRYENDTRY_LENDFINALLYRETSYSCALLDEPTHDROPNIPXDROPCLEARDUPOVERPICKTUCKSWAPROTROLLREVERSE3REVERSE4REVERSENINITSSLOTINITSLOTLDSFLD0LDSFLD1LDSFLD2LDSFLD3LDSFLD4LDSFLD5LDSFLD6LDSFLDSTSFLD0STSFLD1STSFLD2STSFLD3STSFLD4STSFLD5STSFLD6STSFLDLDLOC0LDLOC1LDLOC2LDLOC3LDLOC4LDLOC5LDLOC6LDLOCSTLOC0STLOC1STLOC2STLOC3STLOC4STLOC5STLOC6STLOCLDARG0LDARG1LDARG2LDARG3LDARG4LDARG5LDARG6LDARGSTARG0STARG1STARG2STARG3STARG4STARG5STARG6STARGNEWBUFFERMEMCPYCATSUBSTRLEFTRIGHTINVERTANDORXOREQUALNOTEQUALSIGNABSNEGATEINCDECADDSUBMULDIVMODPOWSQRTMODMULMODPOWSHLSHRNOTBOOLANDBOOLORNZNUMEQUALNUMNOTEQUALLTLEGTGEMINMAXWITHINPACKMAPPACKSTRUCTPACKUNPACKNEWARRAY0NEWARRAYNEWARRAY_TNEWSTRUCT0NEWSTRUCTNEWMAPSIZEHASKEYKEYSVALUESPICKITEMAPPENDSETITEMREVERSEITEMSREMOVECLEARITEMSPOPITEMISNULLISTYPECONVERT" +const _Opcode_name = "PUSHINT8PUSHINT16PUSHINT32PUSHINT64PUSHINT128PUSHINT256PUSHTPUSHFPUSHAPUSHNULLPUSHDATA1PUSHDATA2PUSHDATA4PUSHM1PUSH0PUSH1PUSH2PUSH3PUSH4PUSH5PUSH6PUSH7PUSH8PUSH9PUSH10PUSH11PUSH12PUSH13PUSH14PUSH15PUSH16NOPJMPJMP_LJMPIFJMPIF_LJMPIFNOTJMPIFNOT_LJMPEQJMPEQ_LJMPNEJMPNE_LJMPGTJMPGT_LJMPGEJMPGE_LJMPLTJMPLT_LJMPLEJMPLE_LCALLCALL_LCALLACALLTABORTASSERTTHROWTRYTRY_LENDTRYENDTRY_LENDFINALLYRETSYSCALLDEPTHDROPNIPXDROPCLEARDUPOVERPICKTUCKSWAPROTROLLREVERSE3REVERSE4REVERSENINITSSLOTINITSLOTLDSFLD0LDSFLD1LDSFLD2LDSFLD3LDSFLD4LDSFLD5LDSFLD6LDSFLDSTSFLD0STSFLD1STSFLD2STSFLD3STSFLD4STSFLD5STSFLD6STSFLDLDLOC0LDLOC1LDLOC2LDLOC3LDLOC4LDLOC5LDLOC6LDLOCSTLOC0STLOC1STLOC2STLOC3STLOC4STLOC5STLOC6STLOCLDARG0LDARG1LDARG2LDARG3LDARG4LDARG5LDARG6LDARGSTARG0STARG1STARG2STARG3STARG4STARG5STARG6STARGNEWBUFFERMEMCPYCATSUBSTRLEFTRIGHTINVERTANDORXOREQUALNOTEQUALSIGNABSNEGATEINCDECADDSUBMULDIVMODPOWSQRTMODMULMODPOWSHLSHRNOTBOOLANDBOOLORNZNUMEQUALNUMNOTEQUALLTLEGTGEMINMAXWITHINPACKMAPPACKSTRUCTPACKUNPACKNEWARRAY0NEWARRAYNEWARRAY_TNEWSTRUCT0NEWSTRUCTNEWMAPSIZEHASKEYKEYSVALUESPICKITEMAPPENDSETITEMREVERSEITEMSREMOVECLEARITEMSPOPITEMISNULLISTYPECONVERTABORTMSGASSERTMSG" var _Opcode_map = map[Opcode]string{ 0: _Opcode_name[0:8], @@ -401,6 +403,8 @@ var _Opcode_map = map[Opcode]string{ 216: _Opcode_name[1112:1118], 217: _Opcode_name[1118:1124], 219: _Opcode_name[1124:1131], + 224: _Opcode_name[1131:1139], + 225: _Opcode_name[1139:1148], } func (i Opcode) String() string { diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go index 8c1af0df8..32f8c8210 100644 --- a/pkg/vm/vm.go +++ b/pkg/vm/vm.go @@ -1587,11 +1587,21 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro case opcode.ABORT: panic("ABORT") + case opcode.ABORTMSG: + msg := v.estack.Pop().Bytes() + panic(fmt.Sprintf("%s is executed. Reason: %s", op, string(msg))) + case opcode.ASSERT: if !v.estack.Pop().Bool() { panic("ASSERT failed") } + case opcode.ASSERTMSG: + msg := v.estack.Pop().Bytes() + if !v.estack.Pop().Bool() { + panic(fmt.Sprintf("%s is executed with false result. Reason: %s", op, msg)) + } + case opcode.TRY, opcode.TRYL: catchP, finallyP := getTryParams(op, parameter) if ctx.tryStack.Len() >= MaxTryNestingDepth { diff --git a/pkg/vm/vm_test.go b/pkg/vm/vm_test.go index d19b42e6e..2107f749b 100644 --- a/pkg/vm/vm_test.go +++ b/pkg/vm/vm_test.go @@ -1097,6 +1097,7 @@ func TestTRY(t *testing.T) { t.Run("Simple", getTRYTestFunc(1, push1, add5, nil)) t.Run("Throw", getTRYTestFunc(18, throw, add5, nil)) t.Run("Abort", getTRYTestFunc(nil, []byte{byte(opcode.ABORT)}, push1, nil)) + t.Run("AbortMSG", getTRYTestFunc(nil, []byte{byte(opcode.PUSH1), byte(opcode.ABORTMSG)}, push1, nil)) t.Run("ThrowInCatch", getTRYTestFunc(nil, throw, throw, nil)) }) t.Run("WithFinally", func(t *testing.T) {