diff --git a/src/Neo/SmartContract/ApplicationEngine.OpCodePrices.cs b/src/Neo/SmartContract/ApplicationEngine.OpCodePrices.cs index 395b5c7e4c..bd4836bfdb 100644 --- a/src/Neo/SmartContract/ApplicationEngine.OpCodePrices.cs +++ b/src/Neo/SmartContract/ApplicationEngine.OpCodePrices.cs @@ -10,6 +10,8 @@ // modifications are permitted. using Neo.VM; +using System; +using System.Collections.Generic; namespace Neo.SmartContract { @@ -18,209 +20,220 @@ partial class ApplicationEngine /// /// The prices of all the opcodes. /// - public static readonly long[] OpCodePrices = new long[byte.MaxValue]; + [Obsolete] + public static readonly IReadOnlyDictionary OpCodePrices = new Dictionary + { + [OpCode.PUSHINT8] = 1 << 0, + [OpCode.PUSHINT16] = 1 << 0, + [OpCode.PUSHINT32] = 1 << 0, + [OpCode.PUSHINT64] = 1 << 0, + [OpCode.PUSHINT128] = 1 << 2, + [OpCode.PUSHINT256] = 1 << 2, + [OpCode.PUSHT] = 1 << 0, + [OpCode.PUSHF] = 1 << 0, + [OpCode.PUSHA] = 1 << 2, + [OpCode.PUSHNULL] = 1 << 0, + [OpCode.PUSHDATA1] = 1 << 3, + [OpCode.PUSHDATA2] = 1 << 9, + [OpCode.PUSHDATA4] = 1 << 12, + [OpCode.PUSHM1] = 1 << 0, + [OpCode.PUSH0] = 1 << 0, + [OpCode.PUSH1] = 1 << 0, + [OpCode.PUSH2] = 1 << 0, + [OpCode.PUSH3] = 1 << 0, + [OpCode.PUSH4] = 1 << 0, + [OpCode.PUSH5] = 1 << 0, + [OpCode.PUSH6] = 1 << 0, + [OpCode.PUSH7] = 1 << 0, + [OpCode.PUSH8] = 1 << 0, + [OpCode.PUSH9] = 1 << 0, + [OpCode.PUSH10] = 1 << 0, + [OpCode.PUSH11] = 1 << 0, + [OpCode.PUSH12] = 1 << 0, + [OpCode.PUSH13] = 1 << 0, + [OpCode.PUSH14] = 1 << 0, + [OpCode.PUSH15] = 1 << 0, + [OpCode.PUSH16] = 1 << 0, + [OpCode.NOP] = 1 << 0, + [OpCode.JMP] = 1 << 1, + [OpCode.JMP_L] = 1 << 1, + [OpCode.JMPIF] = 1 << 1, + [OpCode.JMPIF_L] = 1 << 1, + [OpCode.JMPIFNOT] = 1 << 1, + [OpCode.JMPIFNOT_L] = 1 << 1, + [OpCode.JMPEQ] = 1 << 1, + [OpCode.JMPEQ_L] = 1 << 1, + [OpCode.JMPNE] = 1 << 1, + [OpCode.JMPNE_L] = 1 << 1, + [OpCode.JMPGT] = 1 << 1, + [OpCode.JMPGT_L] = 1 << 1, + [OpCode.JMPGE] = 1 << 1, + [OpCode.JMPGE_L] = 1 << 1, + [OpCode.JMPLT] = 1 << 1, + [OpCode.JMPLT_L] = 1 << 1, + [OpCode.JMPLE] = 1 << 1, + [OpCode.JMPLE_L] = 1 << 1, + [OpCode.CALL] = 1 << 9, + [OpCode.CALL_L] = 1 << 9, + [OpCode.CALLA] = 1 << 9, + [OpCode.CALLT] = 1 << 15, + [OpCode.ABORT] = 0, + [OpCode.ABORTMSG] = 0, + [OpCode.ASSERT] = 1 << 0, + [OpCode.ASSERTMSG] = 1 << 0, + [OpCode.THROW] = 1 << 9, + [OpCode.TRY] = 1 << 2, + [OpCode.TRY_L] = 1 << 2, + [OpCode.ENDTRY] = 1 << 2, + [OpCode.ENDTRY_L] = 1 << 2, + [OpCode.ENDFINALLY] = 1 << 2, + [OpCode.RET] = 0, + [OpCode.SYSCALL] = 0, + [OpCode.DEPTH] = 1 << 1, + [OpCode.DROP] = 1 << 1, + [OpCode.NIP] = 1 << 1, + [OpCode.XDROP] = 1 << 4, + [OpCode.CLEAR] = 1 << 4, + [OpCode.DUP] = 1 << 1, + [OpCode.OVER] = 1 << 1, + [OpCode.PICK] = 1 << 1, + [OpCode.TUCK] = 1 << 1, + [OpCode.SWAP] = 1 << 1, + [OpCode.ROT] = 1 << 1, + [OpCode.ROLL] = 1 << 4, + [OpCode.REVERSE3] = 1 << 1, + [OpCode.REVERSE4] = 1 << 1, + [OpCode.REVERSEN] = 1 << 4, + [OpCode.INITSSLOT] = 1 << 4, + [OpCode.INITSLOT] = 1 << 6, + [OpCode.LDSFLD0] = 1 << 1, + [OpCode.LDSFLD1] = 1 << 1, + [OpCode.LDSFLD2] = 1 << 1, + [OpCode.LDSFLD3] = 1 << 1, + [OpCode.LDSFLD4] = 1 << 1, + [OpCode.LDSFLD5] = 1 << 1, + [OpCode.LDSFLD6] = 1 << 1, + [OpCode.LDSFLD] = 1 << 1, + [OpCode.STSFLD0] = 1 << 1, + [OpCode.STSFLD1] = 1 << 1, + [OpCode.STSFLD2] = 1 << 1, + [OpCode.STSFLD3] = 1 << 1, + [OpCode.STSFLD4] = 1 << 1, + [OpCode.STSFLD5] = 1 << 1, + [OpCode.STSFLD6] = 1 << 1, + [OpCode.STSFLD] = 1 << 1, + [OpCode.LDLOC0] = 1 << 1, + [OpCode.LDLOC1] = 1 << 1, + [OpCode.LDLOC2] = 1 << 1, + [OpCode.LDLOC3] = 1 << 1, + [OpCode.LDLOC4] = 1 << 1, + [OpCode.LDLOC5] = 1 << 1, + [OpCode.LDLOC6] = 1 << 1, + [OpCode.LDLOC] = 1 << 1, + [OpCode.STLOC0] = 1 << 1, + [OpCode.STLOC1] = 1 << 1, + [OpCode.STLOC2] = 1 << 1, + [OpCode.STLOC3] = 1 << 1, + [OpCode.STLOC4] = 1 << 1, + [OpCode.STLOC5] = 1 << 1, + [OpCode.STLOC6] = 1 << 1, + [OpCode.STLOC] = 1 << 1, + [OpCode.LDARG0] = 1 << 1, + [OpCode.LDARG1] = 1 << 1, + [OpCode.LDARG2] = 1 << 1, + [OpCode.LDARG3] = 1 << 1, + [OpCode.LDARG4] = 1 << 1, + [OpCode.LDARG5] = 1 << 1, + [OpCode.LDARG6] = 1 << 1, + [OpCode.LDARG] = 1 << 1, + [OpCode.STARG0] = 1 << 1, + [OpCode.STARG1] = 1 << 1, + [OpCode.STARG2] = 1 << 1, + [OpCode.STARG3] = 1 << 1, + [OpCode.STARG4] = 1 << 1, + [OpCode.STARG5] = 1 << 1, + [OpCode.STARG6] = 1 << 1, + [OpCode.STARG] = 1 << 1, + [OpCode.NEWBUFFER] = 1 << 8, + [OpCode.MEMCPY] = 1 << 11, + [OpCode.CAT] = 1 << 11, + [OpCode.SUBSTR] = 1 << 11, + [OpCode.LEFT] = 1 << 11, + [OpCode.RIGHT] = 1 << 11, + [OpCode.INVERT] = 1 << 2, + [OpCode.AND] = 1 << 3, + [OpCode.OR] = 1 << 3, + [OpCode.XOR] = 1 << 3, + [OpCode.EQUAL] = 1 << 5, + [OpCode.NOTEQUAL] = 1 << 5, + [OpCode.SIGN] = 1 << 2, + [OpCode.ABS] = 1 << 2, + [OpCode.NEGATE] = 1 << 2, + [OpCode.INC] = 1 << 2, + [OpCode.DEC] = 1 << 2, + [OpCode.ADD] = 1 << 3, + [OpCode.SUB] = 1 << 3, + [OpCode.MUL] = 1 << 3, + [OpCode.DIV] = 1 << 3, + [OpCode.MOD] = 1 << 3, + [OpCode.POW] = 1 << 6, + [OpCode.SQRT] = 1 << 6, + [OpCode.MODMUL] = 1 << 5, + [OpCode.MODPOW] = 1 << 11, + [OpCode.SHL] = 1 << 3, + [OpCode.SHR] = 1 << 3, + [OpCode.NOT] = 1 << 2, + [OpCode.BOOLAND] = 1 << 3, + [OpCode.BOOLOR] = 1 << 3, + [OpCode.NZ] = 1 << 2, + [OpCode.NUMEQUAL] = 1 << 3, + [OpCode.NUMNOTEQUAL] = 1 << 3, + [OpCode.LT] = 1 << 3, + [OpCode.LE] = 1 << 3, + [OpCode.GT] = 1 << 3, + [OpCode.GE] = 1 << 3, + [OpCode.MIN] = 1 << 3, + [OpCode.MAX] = 1 << 3, + [OpCode.WITHIN] = 1 << 3, + [OpCode.PACKMAP] = 1 << 11, + [OpCode.PACKSTRUCT] = 1 << 11, + [OpCode.PACK] = 1 << 11, + [OpCode.UNPACK] = 1 << 11, + [OpCode.NEWARRAY0] = 1 << 4, + [OpCode.NEWARRAY] = 1 << 9, + [OpCode.NEWARRAY_T] = 1 << 9, + [OpCode.NEWSTRUCT0] = 1 << 4, + [OpCode.NEWSTRUCT] = 1 << 9, + [OpCode.NEWMAP] = 1 << 3, + [OpCode.SIZE] = 1 << 2, + [OpCode.HASKEY] = 1 << 6, + [OpCode.KEYS] = 1 << 4, + [OpCode.VALUES] = 1 << 13, + [OpCode.PICKITEM] = 1 << 6, + [OpCode.APPEND] = 1 << 13, + [OpCode.SETITEM] = 1 << 13, + [OpCode.REVERSEITEMS] = 1 << 13, + [OpCode.REMOVE] = 1 << 4, + [OpCode.CLEARITEMS] = 1 << 4, + [OpCode.POPITEM] = 1 << 4, + [OpCode.ISNULL] = 1 << 1, + [OpCode.ISTYPE] = 1 << 1, + [OpCode.CONVERT] = 1 << 13, + }; + + public static readonly long[] OpCodePriceTable = new long[byte.MaxValue]; /// /// Init OpCodePrices /// static ApplicationEngine() { - OpCodePrices[(byte)OpCode.PUSHINT8] = 1 << 0; - OpCodePrices[(byte)OpCode.PUSHINT16] = 1 << 0; - OpCodePrices[(byte)OpCode.PUSHINT32] = 1 << 0; - OpCodePrices[(byte)OpCode.PUSHINT64] = 1 << 0; - OpCodePrices[(byte)OpCode.PUSHINT128] = 1 << 2; - OpCodePrices[(byte)OpCode.PUSHINT256] = 1 << 2; - OpCodePrices[(byte)OpCode.PUSHT] = 1 << 0; - OpCodePrices[(byte)OpCode.PUSHF] = 1 << 0; - OpCodePrices[(byte)OpCode.PUSHA] = 1 << 2; - OpCodePrices[(byte)OpCode.PUSHNULL] = 1 << 0; - OpCodePrices[(byte)OpCode.PUSHDATA1] = 1 << 3; - OpCodePrices[(byte)OpCode.PUSHDATA2] = 1 << 9; - OpCodePrices[(byte)OpCode.PUSHDATA4] = 1 << 12; - OpCodePrices[(byte)OpCode.PUSHM1] = 1 << 0; - OpCodePrices[(byte)OpCode.PUSH0] = 1 << 0; - OpCodePrices[(byte)OpCode.PUSH1] = 1 << 0; - OpCodePrices[(byte)OpCode.PUSH2] = 1 << 0; - OpCodePrices[(byte)OpCode.PUSH3] = 1 << 0; - OpCodePrices[(byte)OpCode.PUSH4] = 1 << 0; - OpCodePrices[(byte)OpCode.PUSH5] = 1 << 0; - OpCodePrices[(byte)OpCode.PUSH6] = 1 << 0; - OpCodePrices[(byte)OpCode.PUSH7] = 1 << 0; - OpCodePrices[(byte)OpCode.PUSH8] = 1 << 0; - OpCodePrices[(byte)OpCode.PUSH9] = 1 << 0; - OpCodePrices[(byte)OpCode.PUSH10] = 1 << 0; - OpCodePrices[(byte)OpCode.PUSH11] = 1 << 0; - OpCodePrices[(byte)OpCode.PUSH12] = 1 << 0; - OpCodePrices[(byte)OpCode.PUSH13] = 1 << 0; - OpCodePrices[(byte)OpCode.PUSH14] = 1 << 0; - OpCodePrices[(byte)OpCode.PUSH15] = 1 << 0; - OpCodePrices[(byte)OpCode.PUSH16] = 1 << 0; - OpCodePrices[(byte)OpCode.NOP] = 1 << 0; - OpCodePrices[(byte)OpCode.JMP] = 1 << 1; - OpCodePrices[(byte)OpCode.JMP_L] = 1 << 1; - OpCodePrices[(byte)OpCode.JMPIF] = 1 << 1; - OpCodePrices[(byte)OpCode.JMPIF_L] = 1 << 1; - OpCodePrices[(byte)OpCode.JMPIFNOT] = 1 << 1; - OpCodePrices[(byte)OpCode.JMPIFNOT_L] = 1 << 1; - OpCodePrices[(byte)OpCode.JMPEQ] = 1 << 1; - OpCodePrices[(byte)OpCode.JMPEQ_L] = 1 << 1; - OpCodePrices[(byte)OpCode.JMPNE] = 1 << 1; - OpCodePrices[(byte)OpCode.JMPNE_L] = 1 << 1; - OpCodePrices[(byte)OpCode.JMPGT] = 1 << 1; - OpCodePrices[(byte)OpCode.JMPGT_L] = 1 << 1; - OpCodePrices[(byte)OpCode.JMPGE] = 1 << 1; - OpCodePrices[(byte)OpCode.JMPGE_L] = 1 << 1; - OpCodePrices[(byte)OpCode.JMPLT] = 1 << 1; - OpCodePrices[(byte)OpCode.JMPLT_L] = 1 << 1; - OpCodePrices[(byte)OpCode.JMPLE] = 1 << 1; - OpCodePrices[(byte)OpCode.JMPLE_L] = 1 << 1; - OpCodePrices[(byte)OpCode.CALL] = 1 << 9; - OpCodePrices[(byte)OpCode.CALL_L] = 1 << 9; - OpCodePrices[(byte)OpCode.CALLA] = 1 << 9; - OpCodePrices[(byte)OpCode.CALLT] = 1 << 15; - OpCodePrices[(byte)OpCode.ABORT] = 0; - OpCodePrices[(byte)OpCode.ABORTMSG] = 0; - OpCodePrices[(byte)OpCode.ASSERT] = 1 << 0; - OpCodePrices[(byte)OpCode.ASSERTMSG] = 1 << 0; - OpCodePrices[(byte)OpCode.THROW] = 1 << 9; - OpCodePrices[(byte)OpCode.TRY] = 1 << 2; - OpCodePrices[(byte)OpCode.TRY_L] = 1 << 2; - OpCodePrices[(byte)OpCode.ENDTRY] = 1 << 2; - OpCodePrices[(byte)OpCode.ENDTRY_L] = 1 << 2; - OpCodePrices[(byte)OpCode.ENDFINALLY] = 1 << 2; - OpCodePrices[(byte)OpCode.RET] = 0; - OpCodePrices[(byte)OpCode.SYSCALL] = 0; - OpCodePrices[(byte)OpCode.DEPTH] = 1 << 1; - OpCodePrices[(byte)OpCode.DROP] = 1 << 1; - OpCodePrices[(byte)OpCode.NIP] = 1 << 1; - OpCodePrices[(byte)OpCode.XDROP] = 1 << 4; - OpCodePrices[(byte)OpCode.CLEAR] = 1 << 4; - OpCodePrices[(byte)OpCode.DUP] = 1 << 1; - OpCodePrices[(byte)OpCode.OVER] = 1 << 1; - OpCodePrices[(byte)OpCode.PICK] = 1 << 1; - OpCodePrices[(byte)OpCode.TUCK] = 1 << 1; - OpCodePrices[(byte)OpCode.SWAP] = 1 << 1; - OpCodePrices[(byte)OpCode.ROT] = 1 << 1; - OpCodePrices[(byte)OpCode.ROLL] = 1 << 4; - OpCodePrices[(byte)OpCode.REVERSE3] = 1 << 1; - OpCodePrices[(byte)OpCode.REVERSE4] = 1 << 1; - OpCodePrices[(byte)OpCode.REVERSEN] = 1 << 4; - OpCodePrices[(byte)OpCode.INITSSLOT] = 1 << 4; - OpCodePrices[(byte)OpCode.INITSLOT] = 1 << 6; - OpCodePrices[(byte)OpCode.LDSFLD0] = 1 << 1; - OpCodePrices[(byte)OpCode.LDSFLD1] = 1 << 1; - OpCodePrices[(byte)OpCode.LDSFLD2] = 1 << 1; - OpCodePrices[(byte)OpCode.LDSFLD3] = 1 << 1; - OpCodePrices[(byte)OpCode.LDSFLD4] = 1 << 1; - OpCodePrices[(byte)OpCode.LDSFLD5] = 1 << 1; - OpCodePrices[(byte)OpCode.LDSFLD6] = 1 << 1; - OpCodePrices[(byte)OpCode.LDSFLD] = 1 << 1; - OpCodePrices[(byte)OpCode.STSFLD0] = 1 << 1; - OpCodePrices[(byte)OpCode.STSFLD1] = 1 << 1; - OpCodePrices[(byte)OpCode.STSFLD2] = 1 << 1; - OpCodePrices[(byte)OpCode.STSFLD3] = 1 << 1; - OpCodePrices[(byte)OpCode.STSFLD4] = 1 << 1; - OpCodePrices[(byte)OpCode.STSFLD5] = 1 << 1; - OpCodePrices[(byte)OpCode.STSFLD6] = 1 << 1; - OpCodePrices[(byte)OpCode.STSFLD] = 1 << 1; - OpCodePrices[(byte)OpCode.LDLOC0] = 1 << 1; - OpCodePrices[(byte)OpCode.LDLOC1] = 1 << 1; - OpCodePrices[(byte)OpCode.LDLOC2] = 1 << 1; - OpCodePrices[(byte)OpCode.LDLOC3] = 1 << 1; - OpCodePrices[(byte)OpCode.LDLOC4] = 1 << 1; - OpCodePrices[(byte)OpCode.LDLOC5] = 1 << 1; - OpCodePrices[(byte)OpCode.LDLOC6] = 1 << 1; - OpCodePrices[(byte)OpCode.LDLOC] = 1 << 1; - OpCodePrices[(byte)OpCode.STLOC0] = 1 << 1; - OpCodePrices[(byte)OpCode.STLOC1] = 1 << 1; - OpCodePrices[(byte)OpCode.STLOC2] = 1 << 1; - OpCodePrices[(byte)OpCode.STLOC3] = 1 << 1; - OpCodePrices[(byte)OpCode.STLOC4] = 1 << 1; - OpCodePrices[(byte)OpCode.STLOC5] = 1 << 1; - OpCodePrices[(byte)OpCode.STLOC6] = 1 << 1; - OpCodePrices[(byte)OpCode.STLOC] = 1 << 1; - OpCodePrices[(byte)OpCode.LDARG0] = 1 << 1; - OpCodePrices[(byte)OpCode.LDARG1] = 1 << 1; - OpCodePrices[(byte)OpCode.LDARG2] = 1 << 1; - OpCodePrices[(byte)OpCode.LDARG3] = 1 << 1; - OpCodePrices[(byte)OpCode.LDARG4] = 1 << 1; - OpCodePrices[(byte)OpCode.LDARG5] = 1 << 1; - OpCodePrices[(byte)OpCode.LDARG6] = 1 << 1; - OpCodePrices[(byte)OpCode.LDARG] = 1 << 1; - OpCodePrices[(byte)OpCode.STARG0] = 1 << 1; - OpCodePrices[(byte)OpCode.STARG1] = 1 << 1; - OpCodePrices[(byte)OpCode.STARG2] = 1 << 1; - OpCodePrices[(byte)OpCode.STARG3] = 1 << 1; - OpCodePrices[(byte)OpCode.STARG4] = 1 << 1; - OpCodePrices[(byte)OpCode.STARG5] = 1 << 1; - OpCodePrices[(byte)OpCode.STARG6] = 1 << 1; - OpCodePrices[(byte)OpCode.STARG] = 1 << 1; - OpCodePrices[(byte)OpCode.NEWBUFFER] = 1 << 8; - OpCodePrices[(byte)OpCode.MEMCPY] = 1 << 11; - OpCodePrices[(byte)OpCode.CAT] = 1 << 11; - OpCodePrices[(byte)OpCode.SUBSTR] = 1 << 11; - OpCodePrices[(byte)OpCode.LEFT] = 1 << 11; - OpCodePrices[(byte)OpCode.RIGHT] = 1 << 11; - OpCodePrices[(byte)OpCode.INVERT] = 1 << 2; - OpCodePrices[(byte)OpCode.AND] = 1 << 3; - OpCodePrices[(byte)OpCode.OR] = 1 << 3; - OpCodePrices[(byte)OpCode.XOR] = 1 << 3; - OpCodePrices[(byte)OpCode.EQUAL] = 1 << 5; - OpCodePrices[(byte)OpCode.NOTEQUAL] = 1 << 5; - OpCodePrices[(byte)OpCode.SIGN] = 1 << 2; - OpCodePrices[(byte)OpCode.ABS] = 1 << 2; - OpCodePrices[(byte)OpCode.NEGATE] = 1 << 2; - OpCodePrices[(byte)OpCode.INC] = 1 << 2; - OpCodePrices[(byte)OpCode.DEC] = 1 << 2; - OpCodePrices[(byte)OpCode.ADD] = 1 << 3; - OpCodePrices[(byte)OpCode.SUB] = 1 << 3; - OpCodePrices[(byte)OpCode.MUL] = 1 << 3; - OpCodePrices[(byte)OpCode.DIV] = 1 << 3; - OpCodePrices[(byte)OpCode.MOD] = 1 << 3; - OpCodePrices[(byte)OpCode.POW] = 1 << 6; - OpCodePrices[(byte)OpCode.SQRT] = 1 << 6; - OpCodePrices[(byte)OpCode.MODMUL] = 1 << 5; - OpCodePrices[(byte)OpCode.MODPOW] = 1 << 11; - OpCodePrices[(byte)OpCode.SHL] = 1 << 3; - OpCodePrices[(byte)OpCode.SHR] = 1 << 3; - OpCodePrices[(byte)OpCode.NOT] = 1 << 2; - OpCodePrices[(byte)OpCode.BOOLAND] = 1 << 3; - OpCodePrices[(byte)OpCode.BOOLOR] = 1 << 3; - OpCodePrices[(byte)OpCode.NZ] = 1 << 2; - OpCodePrices[(byte)OpCode.NUMEQUAL] = 1 << 3; - OpCodePrices[(byte)OpCode.NUMNOTEQUAL] = 1 << 3; - OpCodePrices[(byte)OpCode.LT] = 1 << 3; - OpCodePrices[(byte)OpCode.LE] = 1 << 3; - OpCodePrices[(byte)OpCode.GT] = 1 << 3; - OpCodePrices[(byte)OpCode.GE] = 1 << 3; - OpCodePrices[(byte)OpCode.MIN] = 1 << 3; - OpCodePrices[(byte)OpCode.MAX] = 1 << 3; - OpCodePrices[(byte)OpCode.WITHIN] = 1 << 3; - OpCodePrices[(byte)OpCode.PACKMAP] = 1 << 11; - OpCodePrices[(byte)OpCode.PACKSTRUCT] = 1 << 11; - OpCodePrices[(byte)OpCode.PACK] = 1 << 11; - OpCodePrices[(byte)OpCode.UNPACK] = 1 << 11; - OpCodePrices[(byte)OpCode.NEWARRAY0] = 1 << 4; - OpCodePrices[(byte)OpCode.NEWARRAY] = 1 << 9; - OpCodePrices[(byte)OpCode.NEWARRAY_T] = 1 << 9; - OpCodePrices[(byte)OpCode.NEWSTRUCT0] = 1 << 4; - OpCodePrices[(byte)OpCode.NEWSTRUCT] = 1 << 9; - OpCodePrices[(byte)OpCode.NEWMAP] = 1 << 3; - OpCodePrices[(byte)OpCode.SIZE] = 1 << 2; - OpCodePrices[(byte)OpCode.HASKEY] = 1 << 6; - OpCodePrices[(byte)OpCode.KEYS] = 1 << 4; - OpCodePrices[(byte)OpCode.VALUES] = 1 << 13; - OpCodePrices[(byte)OpCode.PICKITEM] = 1 << 6; - OpCodePrices[(byte)OpCode.APPEND] = 1 << 13; - OpCodePrices[(byte)OpCode.SETITEM] = 1 << 13; - OpCodePrices[(byte)OpCode.REVERSEITEMS] = 1 << 13; - OpCodePrices[(byte)OpCode.REMOVE] = 1 << 4; - OpCodePrices[(byte)OpCode.CLEARITEMS] = 1 << 4; - OpCodePrices[(byte)OpCode.POPITEM] = 1 << 4; - OpCodePrices[(byte)OpCode.ISNULL] = 1 << 1; - OpCodePrices[(byte)OpCode.ISTYPE] = 1 << 1; - OpCodePrices[(byte)OpCode.CONVERT] = 1 << 13; +#pragma warning disable CS0612 // Type or member is obsolete + foreach (var entry in OpCodePrices) +#pragma warning restore CS0612 // Type or member is obsolete + { + OpCodePriceTable[(byte)entry.Key] = entry.Value; + } } } } diff --git a/src/Neo/SmartContract/ApplicationEngine.cs b/src/Neo/SmartContract/ApplicationEngine.cs index b98284adb2..341e077ec3 100644 --- a/src/Neo/SmartContract/ApplicationEngine.cs +++ b/src/Neo/SmartContract/ApplicationEngine.cs @@ -529,7 +529,7 @@ protected virtual void OnSysCall(InteropDescriptor descriptor) protected override void PreExecuteInstruction(Instruction instruction) { Diagnostic?.PreExecuteInstruction(instruction); - AddGas(ExecFeeFactor * OpCodePrices[(byte)instruction.OpCode]); + AddGas(ExecFeeFactor * OpCodePriceTable[(byte)instruction.OpCode]); } protected override void PostExecuteInstruction(Instruction instruction) diff --git a/src/Neo/SmartContract/Helper.cs b/src/Neo/SmartContract/Helper.cs index b3fd03e333..333ef77d7b 100644 --- a/src/Neo/SmartContract/Helper.cs +++ b/src/Neo/SmartContract/Helper.cs @@ -39,8 +39,8 @@ public static class Helper /// /// The calculated cost. public static long SignatureContractCost() => - ApplicationEngine.OpCodePrices[(byte)OpCode.PUSHDATA1] * 2 + - ApplicationEngine.OpCodePrices[(byte)OpCode.SYSCALL] + + ApplicationEngine.OpCodePriceTable[(byte)OpCode.PUSHDATA1] * 2 + + ApplicationEngine.OpCodePriceTable[(byte)OpCode.SYSCALL] + ApplicationEngine.CheckSigPrice; /// @@ -51,12 +51,12 @@ public static long SignatureContractCost() => /// The calculated cost. public static long MultiSignatureContractCost(int m, int n) { - long fee = ApplicationEngine.OpCodePrices[(byte)OpCode.PUSHDATA1] * (m + n); + long fee = ApplicationEngine.OpCodePriceTable[(byte)OpCode.PUSHDATA1] * (m + n); using (ScriptBuilder sb = new()) - fee += ApplicationEngine.OpCodePrices[(byte)(OpCode)sb.EmitPush(m).ToArray()[0]]; + fee += ApplicationEngine.OpCodePriceTable[(byte)(OpCode)sb.EmitPush(m).ToArray()[0]]; using (ScriptBuilder sb = new()) - fee += ApplicationEngine.OpCodePrices[(byte)(OpCode)sb.EmitPush(n).ToArray()[0]]; - fee += ApplicationEngine.OpCodePrices[(byte)OpCode.SYSCALL]; + fee += ApplicationEngine.OpCodePriceTable[(byte)(OpCode)sb.EmitPush(n).ToArray()[0]]; + fee += ApplicationEngine.OpCodePriceTable[(byte)OpCode.SYSCALL]; fee += ApplicationEngine.CheckSigPrice * n; return fee; } diff --git a/tests/Neo.UnitTests/SmartContract/UT_Contract.cs b/tests/Neo.UnitTests/SmartContract/UT_Contract.cs index d5a5727b65..a263779282 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_Contract.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_Contract.cs @@ -164,7 +164,7 @@ public void TestSignatureRedeemScriptFee() byte[] verification = Contract.CreateSignatureRedeemScript(key.PublicKey); byte[] invocation = new ScriptBuilder().EmitPush(UInt160.Zero).ToArray(); - var fee = PolicyContract.DefaultExecFeeFactor * (ApplicationEngine.OpCodePrices[(byte)OpCode.PUSHDATA1] * 2 + ApplicationEngine.OpCodePrices[(byte)OpCode.SYSCALL] + ApplicationEngine.CheckSigPrice); + var fee = PolicyContract.DefaultExecFeeFactor * (ApplicationEngine.OpCodePriceTable[(byte)OpCode.PUSHDATA1] * 2 + ApplicationEngine.OpCodePriceTable[(byte)OpCode.SYSCALL] + ApplicationEngine.CheckSigPrice); using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, new Transaction { Signers = Array.Empty(), Attributes = Array.Empty() }, null, settings: TestBlockchain.TheNeoSystem.Settings)) { @@ -192,7 +192,7 @@ public void TestCreateMultiSigRedeemScriptFee() byte[] verification = Contract.CreateMultiSigRedeemScript(2, publicKeys); byte[] invocation = new ScriptBuilder().EmitPush(UInt160.Zero).EmitPush(UInt160.Zero).ToArray(); - long fee = PolicyContract.DefaultExecFeeFactor * (ApplicationEngine.OpCodePrices[(byte)OpCode.PUSHDATA1] * (2 + 2) + ApplicationEngine.OpCodePrices[(byte)OpCode.PUSHINT8] * 2 + ApplicationEngine.OpCodePrices[(byte)OpCode.SYSCALL] + ApplicationEngine.CheckSigPrice * 2); + long fee = PolicyContract.DefaultExecFeeFactor * (ApplicationEngine.OpCodePriceTable[(byte)OpCode.PUSHDATA1] * (2 + 2) + ApplicationEngine.OpCodePriceTable[(byte)OpCode.PUSHINT8] * 2 + ApplicationEngine.OpCodePriceTable[(byte)OpCode.SYSCALL] + ApplicationEngine.CheckSigPrice * 2); using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, new Transaction { Signers = Array.Empty(), Attributes = Array.Empty() }, null, settings: TestBlockchain.TheNeoSystem.Settings)) { diff --git a/tests/Neo.UnitTests/SmartContract/UT_OpCodePrices.cs b/tests/Neo.UnitTests/SmartContract/UT_OpCodePrices.cs index 6d1bfa9dd4..1e4ef6069d 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_OpCodePrices.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_OpCodePrices.cs @@ -23,7 +23,19 @@ public class UT_OpCodePrices public void AllOpcodePriceAreSet() { foreach (OpCode opcode in Enum.GetValues(typeof(OpCode))) - Assert.AreNotEqual(0, ApplicationEngine.OpCodePrices[(byte)opcode]); + { +#pragma warning disable CS0612 // Type or member is obsolete + Assert.IsTrue(ApplicationEngine.OpCodePrices.ContainsKey(opcode), opcode.ToString(), $"{opcode} without price"); +#pragma warning restore CS0612 // Type or member is obsolete + + if (opcode == OpCode.RET || + opcode == OpCode.SYSCALL || + opcode == OpCode.ABORT || + opcode == OpCode.ABORTMSG) + continue; + + Assert.AreNotEqual(0, ApplicationEngine.OpCodePriceTable[(byte)opcode], $"{opcode} without price"); + } } } }