From 97a4417e5503fe819530a3001630f4f37fb474a2 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Mon, 29 Jul 2024 14:59:03 +0800 Subject: [PATCH 1/3] [Neo Core VM] complete opcode comments (#3437) * complete opcode comments * Apply suggestions from code review * Update src/Neo.VM/OpCode.cs --------- Co-authored-by: Shargon --- src/Neo.VM/JumpTable/JumpTable.Compound.cs | 3 +- src/Neo.VM/JumpTable/JumpTable.Numeric.cs | 6 +- src/Neo.VM/JumpTable/JumpTable.Splice.cs | 1 + src/Neo.VM/JumpTable/JumpTable.Stack.cs | 4 +- src/Neo.VM/OpCode.cs | 1215 +++++++++++++++++++- 5 files changed, 1215 insertions(+), 14 deletions(-) diff --git a/src/Neo.VM/JumpTable/JumpTable.Compound.cs b/src/Neo.VM/JumpTable/JumpTable.Compound.cs index aeb2047825..197cc1952a 100644 --- a/src/Neo.VM/JumpTable/JumpTable.Compound.cs +++ b/src/Neo.VM/JumpTable/JumpTable.Compound.cs @@ -239,6 +239,7 @@ public virtual void NewMap(ExecutionEngine engine, Instruction instruction) [MethodImpl(MethodImplOptions.AggressiveInlining)] public virtual void Size(ExecutionEngine engine, Instruction instruction) { + // TODO: we should be able to optimize by using peek instead of dup and pop var x = engine.Pop(); switch (x) { @@ -410,7 +411,7 @@ public virtual void PickItem(ExecutionEngine engine, Instruction instruction) /// /// The execution engine. /// The instruction being executed. - /// Pop 1, Push 1 + /// Pop 2, Push 0 [MethodImpl(MethodImplOptions.AggressiveInlining)] public virtual void Append(ExecutionEngine engine, Instruction instruction) { diff --git a/src/Neo.VM/JumpTable/JumpTable.Numeric.cs b/src/Neo.VM/JumpTable/JumpTable.Numeric.cs index 989991a07c..06533e293a 100644 --- a/src/Neo.VM/JumpTable/JumpTable.Numeric.cs +++ b/src/Neo.VM/JumpTable/JumpTable.Numeric.cs @@ -155,7 +155,7 @@ public virtual void Div(ExecutionEngine engine, Instruction instruction) } /// - /// Computes the result of raising a number to the specified power. + /// Computes the remainder after dividing a by b. /// /// /// The execution engine. @@ -170,7 +170,7 @@ public virtual void Mod(ExecutionEngine engine, Instruction instruction) } /// - /// Computes the square root of the specified integer. + /// Computes the result of raising a number to the specified power. /// /// /// The execution engine. @@ -186,7 +186,7 @@ public virtual void Pow(ExecutionEngine engine, Instruction instruction) } /// - /// + /// Returns the square root of a specified number. /// /// /// The execution engine. diff --git a/src/Neo.VM/JumpTable/JumpTable.Splice.cs b/src/Neo.VM/JumpTable/JumpTable.Splice.cs index 2f49ea0107..f04d045988 100644 --- a/src/Neo.VM/JumpTable/JumpTable.Splice.cs +++ b/src/Neo.VM/JumpTable/JumpTable.Splice.cs @@ -59,6 +59,7 @@ public virtual void Memcpy(ExecutionEngine engine, Instruction instruction) Types.Buffer dst = engine.Pop(); if (checked(di + count) > dst.Size) throw new InvalidOperationException($"The value {count} is out of range."); + // TODO: check if we can optimize the memcpy by using peek instead of dup then pop src.Slice(si, count).CopyTo(dst.InnerBuffer.Span[di..]); } diff --git a/src/Neo.VM/JumpTable/JumpTable.Stack.cs b/src/Neo.VM/JumpTable/JumpTable.Stack.cs index 45ee5565a7..68094470fe 100644 --- a/src/Neo.VM/JumpTable/JumpTable.Stack.cs +++ b/src/Neo.VM/JumpTable/JumpTable.Stack.cs @@ -47,7 +47,7 @@ public virtual void Drop(ExecutionEngine engine, Instruction instruction) } /// - /// + /// Removes the second-to-top stack item. /// /// /// The execution engine. @@ -59,7 +59,7 @@ public virtual void Nip(ExecutionEngine engine, Instruction instruction) } /// - /// Removes the nth item from the top of the evaluation stack. + /// Removes the n-th item from the top of the evaluation stack. /// /// /// The execution engine. diff --git a/src/Neo.VM/OpCode.cs b/src/Neo.VM/OpCode.cs index dd5f1574ea..8ef5c0e538 100644 --- a/src/Neo.VM/OpCode.cs +++ b/src/Neo.VM/OpCode.cs @@ -22,136 +22,321 @@ public enum OpCode : byte /// /// Pushes a 1-byte signed integer onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// [OperandSize(Size = 1)] PUSHINT8 = 0x00, + /// /// Pushes a 2-bytes signed integer onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// [OperandSize(Size = 2)] PUSHINT16 = 0x01, + /// /// Pushes a 4-bytes signed integer onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// [OperandSize(Size = 4)] PUSHINT32 = 0x02, + /// - /// Pushes a 8-bytes signed integer onto the stack. + /// Pushes an 8-bytes signed integer onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// [OperandSize(Size = 8)] PUSHINT64 = 0x03, + /// /// Pushes a 16-bytes signed integer onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// [OperandSize(Size = 16)] PUSHINT128 = 0x04, + /// /// Pushes a 32-bytes signed integer onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// [OperandSize(Size = 32)] PUSHINT256 = 0x05, + /// /// Pushes the boolean value onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// PUSHT = 0x08, + /// /// Pushes the boolean value onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// PUSHF = 0x09, + /// /// Converts the 4-bytes offset to an , and pushes it onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// [OperandSize(Size = 4)] PUSHA = 0x0A, + /// /// The item is pushed onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// PUSHNULL = 0x0B, + /// /// The next byte contains the number of bytes to be pushed onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// [OperandSize(SizePrefix = 1)] PUSHDATA1 = 0x0C, + /// /// The next two bytes contain the number of bytes to be pushed onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// [OperandSize(SizePrefix = 2)] PUSHDATA2 = 0x0D, + /// /// The next four bytes contain the number of bytes to be pushed onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// [OperandSize(SizePrefix = 4)] PUSHDATA4 = 0x0E, + /// /// The number -1 is pushed onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// PUSHM1 = 0x0F, + /// /// The number 0 is pushed onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// PUSH0 = 0x10, + /// /// The number 1 is pushed onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// PUSH1 = 0x11, + /// /// The number 2 is pushed onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// PUSH2 = 0x12, + /// /// The number 3 is pushed onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// PUSH3 = 0x13, + /// /// The number 4 is pushed onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// PUSH4 = 0x14, + /// /// The number 5 is pushed onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// PUSH5 = 0x15, + /// /// The number 6 is pushed onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// PUSH6 = 0x16, + /// /// The number 7 is pushed onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// PUSH7 = 0x17, + /// /// The number 8 is pushed onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// PUSH8 = 0x18, + /// /// The number 9 is pushed onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// PUSH9 = 0x19, + /// /// The number 10 is pushed onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// PUSH10 = 0x1A, + /// /// The number 11 is pushed onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// PUSH11 = 0x1B, + /// /// The number 12 is pushed onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// PUSH12 = 0x1C, + /// /// The number 13 is pushed onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// PUSH13 = 0x1D, + /// /// The number 14 is pushed onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// PUSH14 = 0x1E, + /// /// The number 15 is pushed onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// PUSH15 = 0x1F, + /// /// The number 16 is pushed onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// PUSH16 = 0x20, @@ -161,157 +346,299 @@ public enum OpCode : byte /// /// The operation does nothing. It is intended to fill in space if opcodes are patched. + /// + /// + /// Push: 0 item(s) + /// Pop: 0 item(s) + /// /// NOP = 0x21, + /// /// Unconditionally transfers control to a target instruction. The target instruction is represented as a 1-byte signed offset from the beginning of the current instruction. + /// + /// + /// Push: 0 item(s) + /// Pop: 0 item(s) + /// /// [OperandSize(Size = 1)] JMP = 0x22, + /// /// Unconditionally transfers control to a target instruction. The target instruction is represented as a 4-bytes signed offset from the beginning of the current instruction. + /// + /// + /// Push: 0 item(s) + /// Pop: 0 item(s) + /// /// [OperandSize(Size = 4)] JMP_L = 0x23, + /// /// Transfers control to a target instruction if the value is , not , or non-zero. The target instruction is represented as a 1-byte signed offset from the beginning of the current instruction. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// [OperandSize(Size = 1)] JMPIF = 0x24, + /// /// Transfers control to a target instruction if the value is , not , or non-zero. The target instruction is represented as a 4-bytes signed offset from the beginning of the current instruction. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// [OperandSize(Size = 4)] JMPIF_L = 0x25, + /// /// Transfers control to a target instruction if the value is , a reference, or zero. The target instruction is represented as a 1-byte signed offset from the beginning of the current instruction. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// [OperandSize(Size = 1)] JMPIFNOT = 0x26, + /// /// Transfers control to a target instruction if the value is , a reference, or zero. The target instruction is represented as a 4-bytes signed offset from the beginning of the current instruction. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// [OperandSize(Size = 4)] JMPIFNOT_L = 0x27, + /// /// Transfers control to a target instruction if two values are equal. The target instruction is represented as a 1-byte signed offset from the beginning of the current instruction. + /// + /// + /// Push: 0 item(s) + /// Pop: 2 item(s) + /// /// [OperandSize(Size = 1)] JMPEQ = 0x28, + /// /// Transfers control to a target instruction if two values are equal. The target instruction is represented as a 4-bytes signed offset from the beginning of the current instruction. + /// + /// + /// Push: 0 item(s) + /// Pop: 2 item(s) + /// /// [OperandSize(Size = 4)] JMPEQ_L = 0x29, + /// /// Transfers control to a target instruction when two values are not equal. The target instruction is represented as a 1-byte signed offset from the beginning of the current instruction. + /// + /// + /// Push: 0 item(s) + /// Pop: 2 item(s) + /// /// [OperandSize(Size = 1)] JMPNE = 0x2A, + /// /// Transfers control to a target instruction when two values are not equal. The target instruction is represented as a 4-bytes signed offset from the beginning of the current instruction. + /// + /// + /// Push: 0 item(s) + /// Pop: 2 item(s) + /// /// [OperandSize(Size = 4)] JMPNE_L = 0x2B, + /// /// Transfers control to a target instruction if the first value is greater than the second value. The target instruction is represented as a 1-byte signed offset from the beginning of the current instruction. + /// + /// + /// Push: 0 item(s) + /// Pop: 2 item(s) + /// /// [OperandSize(Size = 1)] JMPGT = 0x2C, + /// /// Transfers control to a target instruction if the first value is greater than the second value. The target instruction is represented as a 4-bytes signed offset from the beginning of the current instruction. + /// + /// + /// Push: 0 item(s) + /// Pop: 2 item(s) + /// /// [OperandSize(Size = 4)] JMPGT_L = 0x2D, + /// /// Transfers control to a target instruction if the first value is greater than or equal to the second value. The target instruction is represented as a 1-byte signed offset from the beginning of the current instruction. + /// + /// + /// Push: 0 item(s) + /// Pop: 2 item(s) + /// /// [OperandSize(Size = 1)] JMPGE = 0x2E, + /// /// Transfers control to a target instruction if the first value is greater than or equal to the second value. The target instruction is represented as a 4-bytes signed offset from the beginning of the current instruction. + /// + /// + /// Push: 0 item(s) + /// Pop: 2 item(s) + /// /// [OperandSize(Size = 4)] JMPGE_L = 0x2F, + /// /// Transfers control to a target instruction if the first value is less than the second value. The target instruction is represented as a 1-byte signed offset from the beginning of the current instruction. + /// + /// + /// Push: 0 item(s) + /// Pop: 2 item(s) + /// /// [OperandSize(Size = 1)] JMPLT = 0x30, + /// /// Transfers control to a target instruction if the first value is less than the second value. The target instruction is represented as a 4-bytes signed offset from the beginning of the current instruction. + /// + /// + /// Push: 0 item(s) + /// Pop: 2 item(s) + /// /// [OperandSize(Size = 4)] JMPLT_L = 0x31, + /// /// Transfers control to a target instruction if the first value is less than or equal to the second value. The target instruction is represented as a 1-byte signed offset from the beginning of the current instruction. + /// + /// + /// Push: 0 item(s) + /// Pop: 2 item(s) + /// /// [OperandSize(Size = 1)] JMPLE = 0x32, + /// /// Transfers control to a target instruction if the first value is less than or equal to the second value. The target instruction is represented as a 4-bytes signed offset from the beginning of the current instruction. + /// + /// + /// Push: 0 item(s) + /// Pop: 2 item(s) + /// /// [OperandSize(Size = 4)] JMPLE_L = 0x33, + /// /// Calls the function at the target address which is represented as a 1-byte signed offset from the beginning of the current instruction. /// [OperandSize(Size = 1)] CALL = 0x34, + /// /// Calls the function at the target address which is represented as a 4-bytes signed offset from the beginning of the current instruction. /// [OperandSize(Size = 4)] CALL_L = 0x35, + /// /// Pop the address of a function from the stack, and call the function. /// CALLA = 0x36, + /// /// Calls the function which is described by the token. /// [OperandSize(Size = 2)] CALLT = 0x37, + /// /// It turns the vm state to FAULT immediately, and cannot be caught. + /// + /// + /// Push: 0 item(s) + /// Pop: 0 item(s) + /// /// ABORT = 0x38, + /// /// Pop the top value of the stack. If it's false, exit vm execution and set vm state to FAULT. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// ASSERT = 0x39, + /// /// Pop the top value of the stack, and throw it. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// THROW = 0x3A, + /// /// TRY CatchOffset(sbyte) FinallyOffset(sbyte). If there's no catch body, set CatchOffset 0. If there's no finally body, set FinallyOffset 0. /// [OperandSize(Size = 2)] TRY = 0x3B, + /// /// TRY_L CatchOffset(int) FinallyOffset(int). If there's no catch body, set CatchOffset 0. If there's no finally body, set FinallyOffset 0. /// [OperandSize(Size = 8)] TRY_L = 0x3C, + /// /// Ensures that the appropriate surrounding finally blocks are executed. And then unconditionally transfers control to the specific target instruction, represented as a 1-byte signed offset from the beginning of the current instruction. /// [OperandSize(Size = 1)] ENDTRY = 0x3D, + /// /// Ensures that the appropriate surrounding finally blocks are executed. And then unconditionally transfers control to the specific target instruction, represented as a 4-byte signed offset from the beginning of the current instruction. /// [OperandSize(Size = 4)] ENDTRY_L = 0x3E, + /// - /// End finally, If no exception happen or be catched, vm will jump to the target instruction of ENDTRY/ENDTRY_L. Otherwise vm will rethrow the exception to upper layer. + /// End finally, If no exception happen or be catched, vm will jump to the target instruction of ENDTRY/ENDTRY_L. Otherwise, vm will rethrow the exception to upper layer. /// ENDFINALLY = 0x3F, + /// /// Returns from the current method. /// RET = 0x40, + /// /// Calls to an interop service. /// @@ -324,62 +651,164 @@ public enum OpCode : byte /// /// Puts the number of stack items onto the stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// DEPTH = 0x43, + /// /// Removes the top stack item. + /// + /// a b c -> a b + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// DROP = 0x45, + /// /// Removes the second-to-top stack item. + /// + /// a b c -> a c + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// NIP = 0x46, + /// /// The item n back in the main stack is removed. + /// + /// + /// Push: 0 item(s) + /// Pop: n+1 item(s) + /// /// XDROP = 0x48, + /// /// Clear the stack /// CLEAR = 0x49, + /// /// Duplicates the top stack item. + /// + /// a b c -> a b c c + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// DUP = 0x4A, + /// /// Copies the second-to-top stack item to the top. + /// + /// a b c -> a b c b + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// OVER = 0x4B, + /// /// The item n back in the stack is copied to the top. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// PICK = 0x4D, + /// /// The item at the top of the stack is copied and inserted before the second-to-top item. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// TUCK = 0x4E, + /// /// The top two items on the stack are swapped. + /// + /// a b -> b a + /// + /// + /// Push: 0 item(s) + /// Pop: 0 item(s) + /// /// SWAP = 0x50, + /// /// The top three items on the stack are rotated to the left. + /// + /// a b c -> b c a + /// + /// + /// Push: 0 item(s) + /// Pop: 0 item(s) + /// /// ROT = 0x51, + /// /// The item n back in the stack is moved to the top. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// ROLL = 0x52, + /// /// Reverse the order of the top 3 items on the stack. + /// + /// a b c -> c b a + /// + /// + /// Push: 0 item(s) + /// Pop: 0 item(s) + /// /// REVERSE3 = 0x53, + /// /// Reverse the order of the top 4 items on the stack. + /// + /// a b c d -> d c b a + /// + /// + /// + /// Push: 0 item(s) + /// Pop: 0 item(s) + /// /// REVERSE4 = 0x54, + /// /// Pop the number N on the stack, and reverse the order of the top N items on the stack. + /// + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// REVERSEN = 0x55, @@ -389,209 +818,503 @@ public enum OpCode : byte /// /// Initialize the static field list for the current execution context. + /// + /// + /// Push: 0 item(s) + /// Pop: 0 item(s) + /// /// [OperandSize(Size = 1)] INITSSLOT = 0x56, + /// /// Initialize the argument slot and the local variable list for the current execution context. /// [OperandSize(Size = 2)] INITSLOT = 0x57, + /// /// Loads the static field at index 0 onto the evaluation stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// LDSFLD0 = 0x58, + /// /// Loads the static field at index 1 onto the evaluation stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// LDSFLD1 = 0x59, + /// /// Loads the static field at index 2 onto the evaluation stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// LDSFLD2 = 0x5A, + /// /// Loads the static field at index 3 onto the evaluation stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// LDSFLD3 = 0x5B, + /// /// Loads the static field at index 4 onto the evaluation stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// LDSFLD4 = 0x5C, + /// /// Loads the static field at index 5 onto the evaluation stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// LDSFLD5 = 0x5D, + /// /// Loads the static field at index 6 onto the evaluation stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// LDSFLD6 = 0x5E, + /// /// Loads the static field at a specified index onto the evaluation stack. The index is represented as a 1-byte unsigned integer. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// [OperandSize(Size = 1)] LDSFLD = 0x5F, + /// /// Stores the value on top of the evaluation stack in the static field list at index 0. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// STSFLD0 = 0x60, + /// /// Stores the value on top of the evaluation stack in the static field list at index 1. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// STSFLD1 = 0x61, + /// /// Stores the value on top of the evaluation stack in the static field list at index 2. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// STSFLD2 = 0x62, + /// /// Stores the value on top of the evaluation stack in the static field list at index 3. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// STSFLD3 = 0x63, + /// /// Stores the value on top of the evaluation stack in the static field list at index 4. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// STSFLD4 = 0x64, + /// /// Stores the value on top of the evaluation stack in the static field list at index 5. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// STSFLD5 = 0x65, + /// /// Stores the value on top of the evaluation stack in the static field list at index 6. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// STSFLD6 = 0x66, + /// /// Stores the value on top of the evaluation stack in the static field list at a specified index. The index is represented as a 1-byte unsigned integer. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// [OperandSize(Size = 1)] STSFLD = 0x67, + /// /// Loads the local variable at index 0 onto the evaluation stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// LDLOC0 = 0x68, + /// /// Loads the local variable at index 1 onto the evaluation stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// LDLOC1 = 0x69, + /// /// Loads the local variable at index 2 onto the evaluation stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// LDLOC2 = 0x6A, + /// /// Loads the local variable at index 3 onto the evaluation stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// LDLOC3 = 0x6B, + /// /// Loads the local variable at index 4 onto the evaluation stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// LDLOC4 = 0x6C, + /// /// Loads the local variable at index 5 onto the evaluation stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// LDLOC5 = 0x6D, + /// /// Loads the local variable at index 6 onto the evaluation stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// LDLOC6 = 0x6E, + /// /// Loads the local variable at a specified index onto the evaluation stack. The index is represented as a 1-byte unsigned integer. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// [OperandSize(Size = 1)] LDLOC = 0x6F, + /// /// Stores the value on top of the evaluation stack in the local variable list at index 0. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// STLOC0 = 0x70, + /// /// Stores the value on top of the evaluation stack in the local variable list at index 1. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// STLOC1 = 0x71, + /// /// Stores the value on top of the evaluation stack in the local variable list at index 2. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// STLOC2 = 0x72, + /// /// Stores the value on top of the evaluation stack in the local variable list at index 3. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// STLOC3 = 0x73, + /// /// Stores the value on top of the evaluation stack in the local variable list at index 4. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// STLOC4 = 0x74, + /// /// Stores the value on top of the evaluation stack in the local variable list at index 5. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// STLOC5 = 0x75, + /// /// Stores the value on top of the evaluation stack in the local variable list at index 6. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// STLOC6 = 0x76, + /// /// Stores the value on top of the evaluation stack in the local variable list at a specified index. The index is represented as a 1-byte unsigned integer. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// [OperandSize(Size = 1)] STLOC = 0x77, + /// /// Loads the argument at index 0 onto the evaluation stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// LDARG0 = 0x78, + /// /// Loads the argument at index 1 onto the evaluation stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// LDARG1 = 0x79, + /// /// Loads the argument at index 2 onto the evaluation stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// LDARG2 = 0x7A, + /// /// Loads the argument at index 3 onto the evaluation stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// LDARG3 = 0x7B, + /// /// Loads the argument at index 4 onto the evaluation stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// LDARG4 = 0x7C, + /// /// Loads the argument at index 5 onto the evaluation stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// LDARG5 = 0x7D, + /// /// Loads the argument at index 6 onto the evaluation stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// LDARG6 = 0x7E, + /// /// Loads the argument at a specified index onto the evaluation stack. The index is represented as a 1-byte unsigned integer. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// [OperandSize(Size = 1)] LDARG = 0x7F, + /// /// Stores the value on top of the evaluation stack in the argument slot at index 0. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// STARG0 = 0x80, + /// /// Stores the value on top of the evaluation stack in the argument slot at index 1. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// STARG1 = 0x81, + /// /// Stores the value on top of the evaluation stack in the argument slot at index 2. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// STARG2 = 0x82, + /// /// Stores the value on top of the evaluation stack in the argument slot at index 3. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// STARG3 = 0x83, + /// /// Stores the value on top of the evaluation stack in the argument slot at index 4. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// STARG4 = 0x84, + /// /// Stores the value on top of the evaluation stack in the argument slot at index 5. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// STARG5 = 0x85, + /// /// Stores the value on top of the evaluation stack in the argument slot at index 6. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// STARG6 = 0x86, + /// /// Stores the value on top of the evaluation stack in the argument slot at a specified index. The index is represented as a 1-byte unsigned integer. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// [OperandSize(Size = 1)] STARG = 0x87, @@ -602,26 +1325,74 @@ public enum OpCode : byte /// /// Creates a new and pushes it onto the stack. + /// + /// new Buffer(a) + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// NEWBUFFER = 0x88, + /// /// Copies a range of bytes from one to another. + /// Using this opcode will require to dup the destination buffer. + /// + /// c.Slice(d, e).CopyTo(a.InnerBuffer.Span[b..]); + /// + /// + /// Push: 0 item(s) + /// Pop: 5 item(s) + /// /// MEMCPY = 0x89, + /// /// Concatenates two strings. + /// + /// a.concat(b) + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// CAT = 0x8B, + /// /// Returns a section of a string. + /// + /// a.Slice(b, c) + /// + /// + /// Push: 1 item(s) + /// Pop: 3 item(s) + /// /// SUBSTR = 0x8C, + /// /// Keeps only characters left of the specified point in a string. + /// + /// a[..b] + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// LEFT = 0x8D, + /// /// Keeps only characters right of the specified point in a string. + /// + /// a[^b..^0] + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// RIGHT = 0x8E, @@ -630,27 +1401,74 @@ public enum OpCode : byte #region Bitwise logic /// - /// Flips all of the bits in the input. + /// Flips all the bits in the input. + /// + /// ~a + /// + /// + /// Push: 1 item(s) + /// Pop: 1 item(s) + /// /// INVERT = 0x90, + /// /// Boolean and between each bit in the inputs. + /// + /// a&b + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// AND = 0x91, + /// /// Boolean or between each bit in the inputs. + /// + /// a|b + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// OR = 0x92, + /// /// Boolean exclusive or between each bit in the inputs. + /// + /// a^b + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// XOR = 0x93, + /// /// Returns 1 if the inputs are exactly equal, 0 otherwise. + /// + /// a.Equals(b) + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// EQUAL = 0x97, + /// /// Returns 1 if the inputs are not equal, 0 otherwise. + /// + /// !a.Equals(b) + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// NOTEQUAL = 0x98, @@ -660,118 +1478,339 @@ public enum OpCode : byte /// /// Puts the sign of top stack item on top of the main stack. If value is negative, put -1; if positive, put 1; if value is zero, put 0. + /// + /// a.Sign + /// + /// + /// Push: 1 item(s) + /// Pop: 1 item(s) + /// /// SIGN = 0x99, + /// /// The input is made positive. + /// + /// abs(a) + /// + /// + /// Push: 1 item(s) + /// Pop: 1 item(s) + /// /// ABS = 0x9A, + /// /// The sign of the input is flipped. + /// + /// -a + /// + /// + /// Push: 1 item(s) + /// Pop: 1 item(s) + /// /// NEGATE = 0x9B, + /// /// 1 is added to the input. + /// + /// a+1 + /// + /// + /// Push: 1 item(s) + /// Pop: 1 item(s) + /// /// INC = 0x9C, + /// /// 1 is subtracted from the input. + /// + /// a-1 + /// + /// + /// Push: 1 item(s) + /// Pop: 1 item(s) + /// /// DEC = 0x9D, + /// /// a is added to b. + /// + /// a+b + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// ADD = 0x9E, + /// /// b is subtracted from a. + /// + /// a-b + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// SUB = 0x9F, + /// /// a is multiplied by b. + /// + /// a*b + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// MUL = 0xA0, + /// /// a is divided by b. + /// + /// a/b + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// DIV = 0xA1, + /// /// Returns the remainder after dividing a by b. + /// + /// a%b + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// MOD = 0xA2, + /// /// The result of raising value to the exponent power. + /// + /// a^b + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// POW = 0xA3, + /// /// Returns the square root of a specified number. + /// + /// sqrt(a) + /// + /// + /// Push: 1 item(s) + /// Pop: 1 item(s) + /// /// SQRT = 0xA4, + /// /// Performs modulus division on a number multiplied by another number. + /// + /// a*b%c + /// + /// + /// Push: 1 item(s) + /// Pop: 3 item(s) + /// /// MODMUL = 0xA5, + /// /// Performs modulus division on a number raised to the power of another number. If the exponent is -1, it will have the calculation of the modular inverse. + /// + /// modpow(a, b, c) + /// + /// + /// Push: 1 item(s) + /// Pop: 3 item(s) + /// /// MODPOW = 0xA6, + /// /// Shifts a left b bits, preserving sign. + /// + /// a<<b + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// SHL = 0xA8, + /// /// Shifts a right b bits, preserving sign. + /// + /// a>>b + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// SHR = 0xA9, + /// - /// If the input is 0 or 1, it is flipped. Otherwise the output will be 0. + /// If the input is 0 or 1, it is flipped. Otherwise, the output will be 0. + /// + /// !a + /// + /// + /// Push: 1 item(s) + /// Pop: 1 item(s) + /// /// NOT = 0xAA, + /// - /// If both a and b are not 0, the output is 1. Otherwise 0. + /// If both a and b are not 0, the output is 1. Otherwise, 0. + /// + /// b && a + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// BOOLAND = 0xAB, + /// - /// If a or b is not 0, the output is 1. Otherwise 0. + /// If a or b is not 0, the output is 1. Otherwise, 0. + /// + /// b || a + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// BOOLOR = 0xAC, + /// /// Returns 0 if the input is 0. 1 otherwise. + /// + /// a != 0 + /// + /// + /// Push: 1 item(s) + /// Pop: 1 item(s) + /// /// NZ = 0xB1, + /// /// Returns 1 if the numbers are equal, 0 otherwise. + /// + /// b == a + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// NUMEQUAL = 0xB3, + /// /// Returns 1 if the numbers are not equal, 0 otherwise. + /// + /// b != a + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// NUMNOTEQUAL = 0xB4, + /// /// Returns 1 if a is less than b, 0 otherwise. + /// + /// b>a + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// LT = 0xB5, + /// /// Returns 1 if a is less than or equal to b, 0 otherwise. + /// + /// b>=a + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// LE = 0xB6, + /// /// Returns 1 if a is greater than b, 0 otherwise. + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// GT = 0xB7, + /// /// Returns 1 if a is greater than or equal to b, 0 otherwise. + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// GE = 0xB8, + /// - /// Returns the smaller of a and b. + /// Returns the smallest of a and b. + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// MIN = 0xB9, + /// - /// Returns the larger of a and b. + /// Returns the largest of a and b. + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// MAX = 0xBA, + /// /// Returns 1 if x is within the specified range (left-inclusive), 0 otherwise. + /// + /// + /// Push: 1 item(s) + /// Pop: 3 item(s) + /// /// WITHIN = 0xBB, @@ -781,87 +1820,217 @@ public enum OpCode : byte /// /// A value n is taken from top of main stack. The next n*2 items on main stack are removed, put inside n-sized map and this map is put on top of the main stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 2n+1 item(s) + /// /// PACKMAP = 0xBE, + /// /// A value n is taken from top of main stack. The next n items on main stack are removed, put inside n-sized struct and this struct is put on top of the main stack. + /// + /// + /// Push: 1 item(s) + /// Pop: n+1 item(s) + /// /// PACKSTRUCT = 0xBF, + /// /// A value n is taken from top of main stack. The next n items on main stack are removed, put inside n-sized array and this array is put on top of the main stack. + /// + /// + /// Push: 1 item(s) + /// Pop: n+1 item(s) + /// /// PACK = 0xC0, + /// /// A collection is removed from top of the main stack. Its elements are put on top of the main stack (in reverse order) and the collection size is also put on main stack. + /// + /// + /// Push: 2n+1 or n+1 item(s) + /// Pop: 1 item(s) + /// /// UNPACK = 0xC1, + /// /// An empty array (with size 0) is put on top of the main stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// NEWARRAY0 = 0xC2, + /// /// A value n is taken from top of main stack. A null-filled array with size n is put on top of the main stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 1 item(s) + /// /// NEWARRAY = 0xC3, + /// /// A value n is taken from top of main stack. An array of type T with size n is put on top of the main stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 1 item(s) + /// /// [OperandSize(Size = 1)] NEWARRAY_T = 0xC4, + /// /// An empty struct (with size 0) is put on top of the main stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// NEWSTRUCT0 = 0xC5, + /// /// A value n is taken from top of main stack. A zero-filled struct with size n is put on top of the main stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 1 item(s) + /// /// NEWSTRUCT = 0xC6, + /// /// A Map is created and put on top of the main stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 0 item(s) + /// /// NEWMAP = 0xC8, + /// /// An array is removed from top of the main stack. Its size is put on top of the main stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 1 item(s) + /// /// SIZE = 0xCA, + /// /// An input index n (or key) and an array (or map) are removed from the top of the main stack. Puts True on top of main stack if array[n] (or map[n]) exist, and False otherwise. + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// HASKEY = 0xCB, + /// /// A map is taken from top of the main stack. The keys of this map are put on top of the main stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 1 item(s) + /// /// KEYS = 0xCC, + /// /// A map is taken from top of the main stack. The values of this map are put on top of the main stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 1 item(s) + /// /// VALUES = 0xCD, + /// /// An input index n (or key) and an array (or map) are taken from main stack. Element array[n] (or map[n]) is put on top of the main stack. + /// + /// + /// Push: 1 item(s) + /// Pop: 2 item(s) + /// /// PICKITEM = 0xCE, + /// /// The item on top of main stack is removed and appended to the second item on top of the main stack. + /// When we use this opcode, we should dup the second item on top of the main stack before using it. + /// + /// a a b -> a.concat(b) + /// + /// + /// Push: 0 item(s) + /// Pop: 2 item(s) + /// /// APPEND = 0xCF, + /// /// A value v, index n (or key) and an array (or map) are taken from main stack. Attribution array[n]=v (or map[n]=v) is performed. + /// + /// + /// Push: 1 item(s) + /// Pop: 3 item(s) + /// /// SETITEM = 0xD0, + /// /// An array is removed from the top of the main stack and its elements are reversed. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// REVERSEITEMS = 0xD1, + /// /// An input index n (or key) and an array (or map) are removed from the top of the main stack. Element array[n] (or map[n]) is removed. + /// + /// + /// Push: 0 item(s) + /// Pop: 2 item(s) + /// /// REMOVE = 0xD2, + /// /// Remove all the items from the compound-type. + /// Using this opcode will need to dup the compound-type before using it. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// CLEARITEMS = 0xD3, + /// /// Remove the last element from an array, and push it onto the stack. + /// Using this opcode will need to dup the array before using it. + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// POPITEM = 0xD4, @@ -872,16 +2041,33 @@ public enum OpCode : byte /// /// Returns if the input is ; /// otherwise. + /// + /// + /// Push: 1 item(s) + /// Pop: 1 item(s) + /// /// ISNULL = 0xD8, + /// /// Returns if the top item of the stack is of the specified type; /// otherwise. + /// + /// + /// Push: 1 item(s) + /// Pop: 1 item(s) + /// /// [OperandSize(Size = 1)] ISTYPE = 0xD9, + /// /// Converts the top item of the stack to the specified type. + /// + /// + /// Push: 1 item(s) + /// Pop: 1 item(s) + /// /// [OperandSize(Size = 1)] CONVERT = 0xDB, @@ -893,11 +2079,24 @@ public enum OpCode : byte /// /// Pops the top stack item. Then, turns the vm state to FAULT immediately, and cannot be caught. The top stack /// value is used as reason. + /// + /// new Exception(a) + /// + /// + /// Push: 0 item(s) + /// Pop: 1 item(s) + /// /// ABORTMSG = 0xE0, + /// /// Pops the top two stack items. If the second-to-top stack value is false, exits the vm execution and sets the /// vm state to FAULT. In this case, the top stack value is used as reason for the exit. Otherwise, it is ignored. + /// + /// + /// Push: 0 item(s) + /// Pop: 2 item(s) + /// /// ASSERTMSG = 0xE1 From eb167b34c1a9f83e18175ad1f46d70e91845b51f Mon Sep 17 00:00:00 2001 From: Jimmy Date: Mon, 29 Jul 2024 15:46:55 +0800 Subject: [PATCH 2/3] [Neo Core] Obsolete applicationengine snapshot (#3436) * Obsolete applicationengine snapshot * fix UT names * fix executioncontextstate --------- Co-authored-by: Shargon Co-authored-by: NGD Admin <154295625+NGDAdmin@users.noreply.github.com> --- .../Conditions/CalledByGroupCondition.cs | 2 +- .../P2P/Payloads/Conditions/GroupCondition.cs | 2 +- .../ApplicationEngine.Contract.cs | 4 +- .../ApplicationEngine.Runtime.cs | 6 +- .../ApplicationEngine.Storage.cs | 14 +- src/Neo/SmartContract/ApplicationEngine.cs | 30 +- .../ContractParametersContext.cs | 21 +- .../SmartContract/ExecutionContextState.cs | 6 +- .../Native/ContractManagement.cs | 38 +- src/Neo/SmartContract/Native/FungibleToken.cs | 18 +- src/Neo/SmartContract/Native/GasToken.cs | 2 +- .../SmartContract/Native/LedgerContract.cs | 42 +- .../SmartContract/Native/NativeContract.cs | 6 +- src/Neo/SmartContract/Native/NeoToken.cs | 58 +-- .../SmartContract/Native/OracleContract.cs | 32 +- .../SmartContract/Native/PolicyContract.cs | 20 +- .../SmartContract/Native/RoleManagement.cs | 4 +- src/Neo/Wallets/Wallet.cs | 2 +- .../RpcServer/RpcServer.SmartContract.cs | 2 +- .../UT_OracleService.cs | 12 +- .../Neo.UnitTests/IO/Caching/UT_CloneCache.cs | 8 +- tests/Neo.UnitTests/Ledger/UT_Blockchain.cs | 4 +- tests/Neo.UnitTests/Ledger/UT_MemoryPool.cs | 58 +-- .../UT_TransactionVerificationContext.cs | 40 +- tests/Neo.UnitTests/Ledger/UT_TrimmedBlock.cs | 8 +- .../Network/P2P/Payloads/UT_Block.cs | 6 +- .../Network/P2P/Payloads/UT_Conflicts.cs | 16 +- .../Network/P2P/Payloads/UT_Header.cs | 6 +- .../P2P/Payloads/UT_HighPriorityAttribute.cs | 8 +- .../Network/P2P/Payloads/UT_NotValidBefore.cs | 8 +- .../Network/P2P/Payloads/UT_Transaction.cs | 155 +++--- .../Network/P2P/Payloads/UT_Witness.cs | 4 +- .../SmartContract/Native/UT_CryptoLib.cs | 52 +- .../SmartContract/Native/UT_FungibleToken.cs | 4 +- .../SmartContract/Native/UT_GasToken.cs | 22 +- .../SmartContract/Native/UT_NativeContract.cs | 8 +- .../SmartContract/Native/UT_NeoToken.cs | 486 +++++++++--------- .../SmartContract/Native/UT_PolicyContract.cs | 20 +- .../SmartContract/Native/UT_RoleManagement.cs | 8 +- .../SmartContract/Native/UT_StdLib.cs | 56 +- .../SmartContract/UT_ApplicationEngine.cs | 18 +- .../UT_ApplicationEngineProvider.cs | 4 +- .../UT_ContractParameterContext.cs | 42 +- .../SmartContract/UT_InteropPrices.cs | 32 +- .../SmartContract/UT_InteropService.NEO.cs | 56 +- .../SmartContract/UT_InteropService.cs | 136 ++--- .../SmartContract/UT_SmartContractHelper.cs | 30 +- .../SmartContract/UT_Syscalls.cs | 44 +- tests/Neo.UnitTests/UT_DataCache.cs | 8 +- .../Wallets/UT_AssetDescriptor.cs | 12 +- tests/Neo.UnitTests/Wallets/UT_Wallet.cs | 50 +- 51 files changed, 875 insertions(+), 855 deletions(-) diff --git a/src/Neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs index 82dab60fcf..d28cd9f8bf 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs @@ -39,7 +39,7 @@ protected override void DeserializeWithoutType(ref MemoryReader reader, int maxN public override bool Match(ApplicationEngine engine) { engine.ValidateCallFlags(CallFlags.ReadStates); - ContractState contract = NativeContract.ContractManagement.GetContract(engine.Snapshot, engine.CallingScriptHash); + ContractState contract = NativeContract.ContractManagement.GetContract(engine.SnapshotCache, engine.CallingScriptHash); return contract is not null && contract.Manifest.Groups.Any(p => p.PubKey.Equals(Group)); } diff --git a/src/Neo/Network/P2P/Payloads/Conditions/GroupCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/GroupCondition.cs index ee937aff8b..3187b62988 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/GroupCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/GroupCondition.cs @@ -39,7 +39,7 @@ protected override void DeserializeWithoutType(ref MemoryReader reader, int maxN public override bool Match(ApplicationEngine engine) { engine.ValidateCallFlags(CallFlags.ReadStates); - ContractState contract = NativeContract.ContractManagement.GetContract(engine.Snapshot, engine.CurrentScriptHash); + ContractState contract = NativeContract.ContractManagement.GetContract(engine.SnapshotCache, engine.CurrentScriptHash); return contract is not null && contract.Manifest.Groups.Any(p => p.PubKey.Equals(Group)); } diff --git a/src/Neo/SmartContract/ApplicationEngine.Contract.cs b/src/Neo/SmartContract/ApplicationEngine.Contract.cs index e5c1c762a7..889ec0e07d 100644 --- a/src/Neo/SmartContract/ApplicationEngine.Contract.cs +++ b/src/Neo/SmartContract/ApplicationEngine.Contract.cs @@ -76,7 +76,7 @@ protected internal void CallContract(UInt160 contractHash, string method, CallFl if ((callFlags & ~CallFlags.All) != 0) throw new ArgumentOutOfRangeException(nameof(callFlags)); - ContractState contract = NativeContract.ContractManagement.GetContract(Snapshot, contractHash); + ContractState contract = NativeContract.ContractManagement.GetContract(SnapshotCache, contractHash); if (contract is null) throw new InvalidOperationException($"Called Contract Does Not Exist: {contractHash}.{method}"); ContractMethodDescriptor md = contract.Manifest.Abi.GetMethod(method, args.Count); if (md is null) throw new InvalidOperationException($"Method \"{method}\" with {args.Count} parameter(s) doesn't exist in the contract {contractHash}."); @@ -96,7 +96,7 @@ protected internal void CallNativeContract(byte version) NativeContract contract = NativeContract.GetContract(CurrentScriptHash); if (contract is null) throw new InvalidOperationException("It is not allowed to use \"System.Contract.CallNative\" directly."); - if (!contract.IsActive(ProtocolSettings, NativeContract.Ledger.CurrentIndex(Snapshot))) + if (!contract.IsActive(ProtocolSettings, NativeContract.Ledger.CurrentIndex(SnapshotCache))) throw new InvalidOperationException($"The native contract {contract.Name} is not active."); contract.Invoke(this, version); } diff --git a/src/Neo/SmartContract/ApplicationEngine.Runtime.cs b/src/Neo/SmartContract/ApplicationEngine.Runtime.cs index e54529f6d1..3771278839 100644 --- a/src/Neo/SmartContract/ApplicationEngine.Runtime.cs +++ b/src/Neo/SmartContract/ApplicationEngine.Runtime.cs @@ -260,8 +260,8 @@ protected internal bool CheckWitnessInternal(UInt160 hash) } else { - OracleRequest request = NativeContract.Oracle.GetRequest(Snapshot, response.Id); - signers = NativeContract.Ledger.GetTransaction(Snapshot, request.OriginalTxid).Signers; + OracleRequest request = NativeContract.Oracle.GetRequest(SnapshotCache, response.Id); + signers = NativeContract.Ledger.GetTransaction(SnapshotCache, request.OriginalTxid).Signers; } Signer signer = signers.FirstOrDefault(p => p.Account.Equals(hash)); if (signer is null) return false; @@ -280,7 +280,7 @@ protected internal bool CheckWitnessInternal(UInt160 hash) ValidateCallFlags(CallFlags.ReadStates); // only for non-Transaction types (Block, etc) - return ScriptContainer.GetScriptHashesForVerifying(Snapshot).Contains(hash); + return ScriptContainer.GetScriptHashesForVerifying(SnapshotCache).Contains(hash); } /// diff --git a/src/Neo/SmartContract/ApplicationEngine.Storage.cs b/src/Neo/SmartContract/ApplicationEngine.Storage.cs index fbd452d6cc..5550835975 100644 --- a/src/Neo/SmartContract/ApplicationEngine.Storage.cs +++ b/src/Neo/SmartContract/ApplicationEngine.Storage.cs @@ -77,7 +77,7 @@ partial class ApplicationEngine /// The storage context for the current contract. protected internal StorageContext GetStorageContext() { - ContractState contract = NativeContract.ContractManagement.GetContract(Snapshot, CurrentScriptHash); + ContractState contract = NativeContract.ContractManagement.GetContract(SnapshotCache, CurrentScriptHash); return new StorageContext { Id = contract.Id, @@ -92,7 +92,7 @@ protected internal StorageContext GetStorageContext() /// The storage context for the current contract. protected internal StorageContext GetReadOnlyContext() { - ContractState contract = NativeContract.ContractManagement.GetContract(Snapshot, CurrentScriptHash); + ContractState contract = NativeContract.ContractManagement.GetContract(SnapshotCache, CurrentScriptHash); return new StorageContext { Id = contract.Id, @@ -126,7 +126,7 @@ protected internal static StorageContext AsReadOnly(StorageContext context) /// The value of the entry. Or if the entry doesn't exist. protected internal ReadOnlyMemory? Get(StorageContext context, byte[] key) { - return Snapshot.TryGet(new StorageKey + return SnapshotCache.TryGet(new StorageKey { Id = context.Id, Key = key @@ -155,7 +155,7 @@ protected internal IIterator Find(StorageContext context, byte[] prefix, FindOpt throw new ArgumentException(null, nameof(options)); byte[] prefix_key = StorageKey.CreateSearchPrefix(context.Id, prefix); SeekDirection direction = options.HasFlag(FindOptions.Backwards) ? SeekDirection.Backward : SeekDirection.Forward; - return new StorageIterator(Snapshot.Find(prefix_key, direction).GetEnumerator(), prefix.Length, options); + return new StorageIterator(SnapshotCache.Find(prefix_key, direction).GetEnumerator(), prefix.Length, options); } /// @@ -177,11 +177,11 @@ protected internal void Put(StorageContext context, byte[] key, byte[] value) Id = context.Id, Key = key }; - StorageItem item = Snapshot.GetAndChange(skey); + StorageItem item = SnapshotCache.GetAndChange(skey); if (item is null) { newDataSize = key.Length + value.Length; - Snapshot.Add(skey, item = new StorageItem()); + SnapshotCache.Add(skey, item = new StorageItem()); } else { @@ -208,7 +208,7 @@ protected internal void Put(StorageContext context, byte[] key, byte[] value) protected internal void Delete(StorageContext context, byte[] key) { if (context.IsReadOnly) throw new ArgumentException(null, nameof(context)); - Snapshot.Delete(new StorageKey + SnapshotCache.Delete(new StorageKey { Id = context.Id, Key = key diff --git a/src/Neo/SmartContract/ApplicationEngine.cs b/src/Neo/SmartContract/ApplicationEngine.cs index 6fd69439ab..38430f3632 100644 --- a/src/Neo/SmartContract/ApplicationEngine.cs +++ b/src/Neo/SmartContract/ApplicationEngine.cs @@ -55,7 +55,7 @@ public partial class ApplicationEngine : ExecutionEngine // In the unit of datoshi, 1 datoshi = 1e-8 GAS, 1 GAS = 1e8 datoshi private readonly long _feeAmount; private Dictionary states; - private readonly DataCache originalSnapshot; + private readonly DataCache originalSnapshotCache; private List notifications; private List disposables; private readonly Dictionary invocationCounter = new(); @@ -95,7 +95,13 @@ public partial class ApplicationEngine : ExecutionEngine /// /// The snapshot used to read or write data. /// - public DataCache Snapshot => CurrentContext?.GetState().Snapshot ?? originalSnapshot; + [Obsolete("This property is deprecated. Use SnapshotCache instead.")] + public DataCache Snapshot => CurrentContext?.GetState().SnapshotCache ?? originalSnapshotCache; + + /// + /// The snapshotcache used to read or write data. + /// + public DataCache SnapshotCache => CurrentContext?.GetState().SnapshotCache ?? originalSnapshotCache; /// /// The block being persisted. This field could be if the is . @@ -164,26 +170,26 @@ public virtual UInt160 CallingScriptHash /// /// The trigger of the execution. /// The container of the script. - /// The snapshot used by the engine during execution. + /// The snapshot used by the engine during execution. /// The block being persisted. It should be if the is . /// The used by the engine. /// The maximum gas, in the unit of datoshi, used in this execution. The execution will fail when the gas is exhausted. /// The diagnostic to be used by the . /// The jump table to be used by the . protected unsafe ApplicationEngine( - TriggerType trigger, IVerifiable container, DataCache snapshot, Block persistingBlock, + TriggerType trigger, IVerifiable container, DataCache snapshotCache, Block persistingBlock, ProtocolSettings settings, long gas, IDiagnostic diagnostic, JumpTable jumpTable = null) : base(jumpTable ?? DefaultJumpTable) { Trigger = trigger; ScriptContainer = container; - originalSnapshot = snapshot; + originalSnapshotCache = snapshotCache; PersistingBlock = persistingBlock; ProtocolSettings = settings; _feeAmount = gas; Diagnostic = diagnostic; - ExecFeeFactor = snapshot is null || persistingBlock?.Index == 0 ? PolicyContract.DefaultExecFeeFactor : NativeContract.Policy.GetExecFeeFactor(snapshot); - StoragePrice = snapshot is null || persistingBlock?.Index == 0 ? PolicyContract.DefaultStoragePrice : NativeContract.Policy.GetStoragePrice(snapshot); + ExecFeeFactor = snapshotCache is null || persistingBlock?.Index == 0 ? PolicyContract.DefaultExecFeeFactor : NativeContract.Policy.GetExecFeeFactor(snapshotCache); + StoragePrice = snapshotCache is null || persistingBlock?.Index == 0 ? PolicyContract.DefaultStoragePrice : NativeContract.Policy.GetStoragePrice(snapshotCache); nonceData = container is Transaction tx ? tx.Hash.ToArray()[..16] : new byte[16]; if (persistingBlock is not null) { @@ -274,7 +280,7 @@ internal void Throw(Exception ex) private ExecutionContext CallContractInternal(UInt160 contractHash, string method, CallFlags flags, bool hasReturnValue, StackItem[] args) { - ContractState contract = NativeContract.ContractManagement.GetContract(Snapshot, contractHash); + ContractState contract = NativeContract.ContractManagement.GetContract(SnapshotCache, contractHash); if (contract is null) throw new InvalidOperationException($"Called Contract Does Not Exist: {contractHash}"); ContractMethodDescriptor md = contract.Manifest.Abi.GetMethod(method, args.Length); if (md is null) throw new InvalidOperationException($"Method \"{method}\" with {args.Length} parameter(s) doesn't exist in the contract {contractHash}."); @@ -283,7 +289,7 @@ private ExecutionContext CallContractInternal(UInt160 contractHash, string metho private ExecutionContext CallContractInternal(ContractState contract, ContractMethodDescriptor method, CallFlags flags, bool hasReturnValue, IReadOnlyList args) { - if (NativeContract.Policy.IsBlocked(Snapshot, contract.Hash)) + if (NativeContract.Policy.IsBlocked(SnapshotCache, contract.Hash)) throw new InvalidOperationException($"The contract {contract.Hash} has been blocked."); ExecutionContext currentContext = CurrentContext; @@ -296,7 +302,7 @@ private ExecutionContext CallContractInternal(ContractState contract, ContractMe { var executingContract = IsHardforkEnabled(Hardfork.HF_Domovoi) ? state.Contract // use executing contract state to avoid possible contract update/destroy side-effects, ref. https://github.com/neo-project/neo/pull/3290. - : NativeContract.ContractManagement.GetContract(Snapshot, CurrentScriptHash); + : NativeContract.ContractManagement.GetContract(SnapshotCache, CurrentScriptHash); if (executingContract?.CanCall(contract, method.Name) == false) throw new InvalidOperationException($"Cannot Call Method {method.Name} Of Contract {contract.Hash} From Contract {CurrentScriptHash}"); } @@ -352,7 +358,7 @@ internal override void UnloadContext(ExecutionContext context) ExecutionContextState state = context.GetState(); if (UncaughtException is null) { - state.Snapshot?.Commit(); + state.SnapshotCache?.Commit(); if (CurrentContext != null) { ExecutionContextState contextState = CurrentContext.GetState(); @@ -460,7 +466,7 @@ public ExecutionContext LoadScript(Script script, int rvcount = -1, int initialP // Create and configure context ExecutionContext context = CreateContext(script, rvcount, initialPosition); ExecutionContextState state = context.GetState(); - state.Snapshot = Snapshot?.CloneCache(); + state.SnapshotCache = SnapshotCache?.CloneCache(); configureState?.Invoke(state); // Load context diff --git a/src/Neo/SmartContract/ContractParametersContext.cs b/src/Neo/SmartContract/ContractParametersContext.cs index e8bf3ceec9..c4129f0ad1 100644 --- a/src/Neo/SmartContract/ContractParametersContext.cs +++ b/src/Neo/SmartContract/ContractParametersContext.cs @@ -73,7 +73,18 @@ public JObject ToJson() /// /// The snapshot used to read data. /// - public readonly DataCache Snapshot; + [Obsolete("Use SnapshotCache instead")] + public DataCache Snapshot => SnapshotCache; + + /// + /// The snapshotcache used to read data. + /// + public readonly DataCache SnapshotCache; + + // /// + // /// The snapshot used to read data. + // /// + // public readonly DataCache Snapshot; /// /// The magic number of the network. @@ -99,18 +110,18 @@ public bool Completed /// /// Gets the script hashes to be verified for the . /// - public IReadOnlyList ScriptHashes => _ScriptHashes ??= Verifiable.GetScriptHashesForVerifying(Snapshot); + public IReadOnlyList ScriptHashes => _ScriptHashes ??= Verifiable.GetScriptHashesForVerifying(SnapshotCache); /// /// Initializes a new instance of the class. /// - /// The snapshot used to read data. + /// The snapshot used to read data. /// The to add witnesses. /// The magic number of the network. - public ContractParametersContext(DataCache snapshot, IVerifiable verifiable, uint network) + public ContractParametersContext(DataCache snapshotCache, IVerifiable verifiable, uint network) { Verifiable = verifiable; - Snapshot = snapshot; + SnapshotCache = snapshotCache; ContextItems = new Dictionary(); Network = network; } diff --git a/src/Neo/SmartContract/ExecutionContextState.cs b/src/Neo/SmartContract/ExecutionContextState.cs index 8b61ff1197..993015df13 100644 --- a/src/Neo/SmartContract/ExecutionContextState.cs +++ b/src/Neo/SmartContract/ExecutionContextState.cs @@ -11,6 +11,7 @@ using Neo.Persistence; using Neo.VM; +using System; namespace Neo.SmartContract { @@ -44,7 +45,10 @@ public class ExecutionContextState /// public CallFlags CallFlags { get; set; } = CallFlags.All; - public DataCache Snapshot { get; set; } + [Obsolete("Use SnapshotCache instead")] + public DataCache Snapshot => SnapshotCache; + + public DataCache SnapshotCache { get; set; } public int NotificationCount { get; set; } diff --git a/src/Neo/SmartContract/Native/ContractManagement.cs b/src/Neo/SmartContract/Native/ContractManagement.cs index c533f029a6..6fefd2d05f 100644 --- a/src/Neo/SmartContract/Native/ContractManagement.cs +++ b/src/Neo/SmartContract/Native/ContractManagement.cs @@ -52,8 +52,8 @@ internal override ContractTask InitializeAsync(ApplicationEngine engine, Hardfor { if (hardfork == ActiveIn) { - engine.Snapshot.Add(CreateStorageKey(Prefix_MinimumDeploymentFee), new StorageItem(10_00000000)); - engine.Snapshot.Add(CreateStorageKey(Prefix_NextAvailableId), new StorageItem(1)); + engine.SnapshotCache.Add(CreateStorageKey(Prefix_MinimumDeploymentFee), new StorageItem(10_00000000)); + engine.SnapshotCache.Add(CreateStorageKey(Prefix_NextAvailableId), new StorageItem(1)); } return ContractTask.CompletedTask; } @@ -73,13 +73,13 @@ internal override async ContractTask OnPersistAsync(ApplicationEngine engine) if (contract.IsInitializeBlock(engine.ProtocolSettings, engine.PersistingBlock.Index, out var hfs)) { ContractState contractState = contract.GetContractState(engine.ProtocolSettings, engine.PersistingBlock.Index); - StorageItem state = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_Contract).Add(contract.Hash)); + StorageItem state = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_Contract).Add(contract.Hash)); if (state is null) { // Create the contract state - engine.Snapshot.Add(CreateStorageKey(Prefix_Contract).Add(contract.Hash), new StorageItem(contractState)); - engine.Snapshot.Add(CreateStorageKey(Prefix_ContractHash).AddBigEndian(contract.Id), new StorageItem(contract.Hash.ToArray())); + engine.SnapshotCache.Add(CreateStorageKey(Prefix_Contract).Add(contract.Hash), new StorageItem(contractState)); + engine.SnapshotCache.Add(CreateStorageKey(Prefix_ContractHash).AddBigEndian(contract.Id), new StorageItem(contract.Hash.ToArray())); // Initialize the native smart contract if it's active starting from the genesis. // If it's not the case, then hardfork-based initialization will be performed down below. @@ -127,7 +127,7 @@ private void SetMinimumDeploymentFee(ApplicationEngine engine, BigInteger value/ { if (value < 0) throw new ArgumentOutOfRangeException(nameof(value)); if (!CheckCommittee(engine)) throw new InvalidOperationException(); - engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_MinimumDeploymentFee)).Set(value); + engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_MinimumDeploymentFee)).Set(value); } /// @@ -221,7 +221,7 @@ private async ContractTask Deploy(ApplicationEngine engine, byte[ engine.AddFee(Math.Max( engine.StoragePrice * (nefFile.Length + manifest.Length), - GetMinimumDeploymentFee(engine.Snapshot) + GetMinimumDeploymentFee(engine.SnapshotCache) )); NefFile nef = nefFile.AsSerializable(); @@ -229,15 +229,15 @@ private async ContractTask Deploy(ApplicationEngine engine, byte[ Helper.Check(new VM.Script(nef.Script, engine.IsHardforkEnabled(Hardfork.HF_Basilisk)), parsedManifest.Abi); UInt160 hash = Helper.GetContractHash(tx.Sender, nef.CheckSum, parsedManifest.Name); - if (Policy.IsBlocked(engine.Snapshot, hash)) + if (Policy.IsBlocked(engine.SnapshotCache, hash)) throw new InvalidOperationException($"The contract {hash} has been blocked."); StorageKey key = CreateStorageKey(Prefix_Contract).Add(hash); - if (engine.Snapshot.Contains(key)) + if (engine.SnapshotCache.Contains(key)) throw new InvalidOperationException($"Contract Already Exists: {hash}"); ContractState contract = new() { - Id = GetNextAvailableId(engine.Snapshot), + Id = GetNextAvailableId(engine.SnapshotCache), UpdateCounter = 0, Nef = nef, Hash = hash, @@ -246,8 +246,8 @@ private async ContractTask Deploy(ApplicationEngine engine, byte[ if (!contract.Manifest.IsValid(engine.Limits, hash)) throw new InvalidOperationException($"Invalid Manifest: {hash}"); - engine.Snapshot.Add(key, new StorageItem(contract)); - engine.Snapshot.Add(CreateStorageKey(Prefix_ContractHash).AddBigEndian(contract.Id), new StorageItem(hash.ToArray())); + engine.SnapshotCache.Add(key, new StorageItem(contract)); + engine.SnapshotCache.Add(CreateStorageKey(Prefix_ContractHash).AddBigEndian(contract.Id), new StorageItem(hash.ToArray())); await OnDeployAsync(engine, contract, data, false); @@ -267,7 +267,7 @@ private ContractTask Update(ApplicationEngine engine, byte[] nefFile, byte[] man engine.AddFee(engine.StoragePrice * ((nefFile?.Length ?? 0) + (manifest?.Length ?? 0))); - var contract = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_Contract).Add(engine.CallingScriptHash))?.GetInteroperable(false); + var contract = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_Contract).Add(engine.CallingScriptHash))?.GetInteroperable(false); if (contract is null) throw new InvalidOperationException($"Updating Contract Does Not Exist: {engine.CallingScriptHash}"); if (contract.UpdateCounter == ushort.MaxValue) throw new InvalidOperationException($"The contract reached the maximum number of updates."); @@ -300,14 +300,14 @@ private void Destroy(ApplicationEngine engine) { UInt160 hash = engine.CallingScriptHash; StorageKey ckey = CreateStorageKey(Prefix_Contract).Add(hash); - ContractState contract = engine.Snapshot.TryGet(ckey)?.GetInteroperable(false); + ContractState contract = engine.SnapshotCache.TryGet(ckey)?.GetInteroperable(false); if (contract is null) return; - engine.Snapshot.Delete(ckey); - engine.Snapshot.Delete(CreateStorageKey(Prefix_ContractHash).AddBigEndian(contract.Id)); - foreach (var (key, _) in engine.Snapshot.Find(StorageKey.CreateSearchPrefix(contract.Id, ReadOnlySpan.Empty))) - engine.Snapshot.Delete(key); + engine.SnapshotCache.Delete(ckey); + engine.SnapshotCache.Delete(CreateStorageKey(Prefix_ContractHash).AddBigEndian(contract.Id)); + foreach (var (key, _) in engine.SnapshotCache.Find(StorageKey.CreateSearchPrefix(contract.Id, ReadOnlySpan.Empty))) + engine.SnapshotCache.Delete(key); // lock contract - Policy.BlockAccount(engine.Snapshot, hash); + Policy.BlockAccount(engine.SnapshotCache, hash); // emit event engine.SendNotification(Hash, "Destroy", new VM.Types.Array(engine.ReferenceCounter) { hash.ToArray() }); } diff --git a/src/Neo/SmartContract/Native/FungibleToken.cs b/src/Neo/SmartContract/Native/FungibleToken.cs index 4ab0f01589..21de0a5644 100644 --- a/src/Neo/SmartContract/Native/FungibleToken.cs +++ b/src/Neo/SmartContract/Native/FungibleToken.cs @@ -74,11 +74,11 @@ internal async ContractTask Mint(ApplicationEngine engine, UInt160 account, BigI { if (amount.Sign < 0) throw new ArgumentOutOfRangeException(nameof(amount)); if (amount.IsZero) return; - StorageItem storage = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_Account).Add(account), () => new StorageItem(new TState())); + StorageItem storage = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_Account).Add(account), () => new StorageItem(new TState())); TState state = storage.GetInteroperable(); OnBalanceChanging(engine, account, state, amount); state.Balance += amount; - storage = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_TotalSupply), () => new StorageItem(BigInteger.Zero)); + storage = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_TotalSupply), () => new StorageItem(BigInteger.Zero)); storage.Add(amount); await PostTransferAsync(engine, null, account, amount, StackItem.Null, callOnPayment); } @@ -88,15 +88,15 @@ internal async ContractTask Burn(ApplicationEngine engine, UInt160 account, BigI if (amount.Sign < 0) throw new ArgumentOutOfRangeException(nameof(amount)); if (amount.IsZero) return; StorageKey key = CreateStorageKey(Prefix_Account).Add(account); - StorageItem storage = engine.Snapshot.GetAndChange(key); + StorageItem storage = engine.SnapshotCache.GetAndChange(key); TState state = storage.GetInteroperable(); if (state.Balance < amount) throw new InvalidOperationException(); OnBalanceChanging(engine, account, state, -amount); if (state.Balance == amount) - engine.Snapshot.Delete(key); + engine.SnapshotCache.Delete(key); else state.Balance -= amount; - storage = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_TotalSupply)); + storage = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_TotalSupply)); storage.Add(-amount); await PostTransferAsync(engine, account, null, amount, StackItem.Null, false); } @@ -137,7 +137,7 @@ private protected async ContractTask Transfer(ApplicationEngine engine, UI if (!from.Equals(engine.CallingScriptHash) && !engine.CheckWitnessInternal(from)) return false; StorageKey key_from = CreateStorageKey(Prefix_Account).Add(from); - StorageItem storage_from = engine.Snapshot.GetAndChange(key_from); + StorageItem storage_from = engine.SnapshotCache.GetAndChange(key_from); if (amount.IsZero) { if (storage_from != null) @@ -159,11 +159,11 @@ private protected async ContractTask Transfer(ApplicationEngine engine, UI { OnBalanceChanging(engine, from, state_from, -amount); if (state_from.Balance == amount) - engine.Snapshot.Delete(key_from); + engine.SnapshotCache.Delete(key_from); else state_from.Balance -= amount; StorageKey key_to = CreateStorageKey(Prefix_Account).Add(to); - StorageItem storage_to = engine.Snapshot.GetAndChange(key_to, () => new StorageItem(new TState())); + StorageItem storage_to = engine.SnapshotCache.GetAndChange(key_to, () => new StorageItem(new TState())); TState state_to = storage_to.GetInteroperable(); OnBalanceChanging(engine, to, state_to, amount); state_to.Balance += amount; @@ -186,7 +186,7 @@ private protected virtual async ContractTask PostTransferAsync(ApplicationEngine // Check if it's a wallet or smart contract - if (!callOnPayment || to is null || ContractManagement.GetContract(engine.Snapshot, to) is null) return; + if (!callOnPayment || to is null || ContractManagement.GetContract(engine.SnapshotCache, to) is null) return; // Call onNEP17Payment method diff --git a/src/Neo/SmartContract/Native/GasToken.cs b/src/Neo/SmartContract/Native/GasToken.cs index b8a185b6f1..42eb16c1e5 100644 --- a/src/Neo/SmartContract/Native/GasToken.cs +++ b/src/Neo/SmartContract/Native/GasToken.cs @@ -44,7 +44,7 @@ internal override async ContractTask OnPersistAsync(ApplicationEngine engine) await Burn(engine, tx.Sender, tx.SystemFee + tx.NetworkFee); totalNetworkFee += tx.NetworkFee; } - ECPoint[] validators = NEO.GetNextBlockValidators(engine.Snapshot, engine.ProtocolSettings.ValidatorsCount); + ECPoint[] validators = NEO.GetNextBlockValidators(engine.SnapshotCache, engine.ProtocolSettings.ValidatorsCount); UInt160 primary = Contract.CreateSignatureRedeemScript(validators[engine.PersistingBlock.PrimaryIndex]).ToScriptHash(); await Mint(engine, primary, totalNetworkFee, false); } diff --git a/src/Neo/SmartContract/Native/LedgerContract.cs b/src/Neo/SmartContract/Native/LedgerContract.cs index ea757ba348..329e0565d5 100644 --- a/src/Neo/SmartContract/Native/LedgerContract.cs +++ b/src/Neo/SmartContract/Native/LedgerContract.cs @@ -42,22 +42,22 @@ internal override ContractTask OnPersistAsync(ApplicationEngine engine) Transaction = p, State = VMState.NONE }).ToArray(); - engine.Snapshot.Add(CreateStorageKey(Prefix_BlockHash).AddBigEndian(engine.PersistingBlock.Index), new StorageItem(engine.PersistingBlock.Hash.ToArray())); - engine.Snapshot.Add(CreateStorageKey(Prefix_Block).Add(engine.PersistingBlock.Hash), new StorageItem(Trim(engine.PersistingBlock).ToArray())); + engine.SnapshotCache.Add(CreateStorageKey(Prefix_BlockHash).AddBigEndian(engine.PersistingBlock.Index), new StorageItem(engine.PersistingBlock.Hash.ToArray())); + engine.SnapshotCache.Add(CreateStorageKey(Prefix_Block).Add(engine.PersistingBlock.Hash), new StorageItem(Trim(engine.PersistingBlock).ToArray())); foreach (TransactionState tx in transactions) { // It's possible that there are previously saved malicious conflict records for this transaction. // If so, then remove it and store the relevant transaction itself. - engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_Transaction).Add(tx.Transaction.Hash), () => new StorageItem(new TransactionState())).FromReplica(new StorageItem(tx)); + engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_Transaction).Add(tx.Transaction.Hash), () => new StorageItem(new TransactionState())).FromReplica(new StorageItem(tx)); // Store transaction's conflicits. var conflictingSigners = tx.Transaction.Signers.Select(s => s.Account); foreach (var attr in tx.Transaction.GetAttributes()) { - engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_Transaction).Add(attr.Hash), () => new StorageItem(new TransactionState())).FromReplica(new StorageItem(new TransactionState() { BlockIndex = engine.PersistingBlock.Index })); + engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_Transaction).Add(attr.Hash), () => new StorageItem(new TransactionState())).FromReplica(new StorageItem(new TransactionState() { BlockIndex = engine.PersistingBlock.Index })); foreach (var signer in conflictingSigners) { - engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_Transaction).Add(attr.Hash).Add(signer), () => new StorageItem(new TransactionState())).FromReplica(new StorageItem(new TransactionState() { BlockIndex = engine.PersistingBlock.Index })); + engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_Transaction).Add(attr.Hash).Add(signer), () => new StorageItem(new TransactionState())).FromReplica(new StorageItem(new TransactionState() { BlockIndex = engine.PersistingBlock.Index })); } } } @@ -67,7 +67,7 @@ internal override ContractTask OnPersistAsync(ApplicationEngine engine) internal override ContractTask PostPersistAsync(ApplicationEngine engine) { - HashIndexState state = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_CurrentBlock), () => new StorageItem(new HashIndexState())).GetInteroperable(); + HashIndexState state = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_CurrentBlock), () => new StorageItem(new HashIndexState())).GetInteroperable(); state.Hash = engine.PersistingBlock.Hash; state.Index = engine.PersistingBlock.Index; return ContractTask.CompletedTask; @@ -188,14 +188,14 @@ private TrimmedBlock GetBlock(ApplicationEngine engine, byte[] indexOrHash) { UInt256 hash; if (indexOrHash.Length < UInt256.Length) - hash = GetBlockHash(engine.Snapshot, (uint)new BigInteger(indexOrHash)); + hash = GetBlockHash(engine.SnapshotCache, (uint)new BigInteger(indexOrHash)); else if (indexOrHash.Length == UInt256.Length) hash = new UInt256(indexOrHash); else throw new ArgumentException(null, nameof(indexOrHash)); if (hash is null) return null; - TrimmedBlock block = GetTrimmedBlock(engine.Snapshot, hash); - if (block is null || !IsTraceableBlock(engine.Snapshot, block.Index, engine.ProtocolSettings.MaxTraceableBlocks)) return null; + TrimmedBlock block = GetTrimmedBlock(engine.SnapshotCache, hash); + if (block is null || !IsTraceableBlock(engine.SnapshotCache, block.Index, engine.ProtocolSettings.MaxTraceableBlocks)) return null; return block; } @@ -280,32 +280,32 @@ public Transaction GetTransaction(DataCache snapshot, UInt256 hash) [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates, Name = "getTransaction")] private Transaction GetTransactionForContract(ApplicationEngine engine, UInt256 hash) { - TransactionState state = GetTransactionState(engine.Snapshot, hash); - if (state is null || !IsTraceableBlock(engine.Snapshot, state.BlockIndex, engine.ProtocolSettings.MaxTraceableBlocks)) return null; + TransactionState state = GetTransactionState(engine.SnapshotCache, hash); + if (state is null || !IsTraceableBlock(engine.SnapshotCache, state.BlockIndex, engine.ProtocolSettings.MaxTraceableBlocks)) return null; return state.Transaction; } [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)] private Signer[] GetTransactionSigners(ApplicationEngine engine, UInt256 hash) { - TransactionState state = GetTransactionState(engine.Snapshot, hash); - if (state is null || !IsTraceableBlock(engine.Snapshot, state.BlockIndex, engine.ProtocolSettings.MaxTraceableBlocks)) return null; + TransactionState state = GetTransactionState(engine.SnapshotCache, hash); + if (state is null || !IsTraceableBlock(engine.SnapshotCache, state.BlockIndex, engine.ProtocolSettings.MaxTraceableBlocks)) return null; return state.Transaction.Signers; } [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)] private VMState GetTransactionVMState(ApplicationEngine engine, UInt256 hash) { - TransactionState state = GetTransactionState(engine.Snapshot, hash); - if (state is null || !IsTraceableBlock(engine.Snapshot, state.BlockIndex, engine.ProtocolSettings.MaxTraceableBlocks)) return VMState.NONE; + TransactionState state = GetTransactionState(engine.SnapshotCache, hash); + if (state is null || !IsTraceableBlock(engine.SnapshotCache, state.BlockIndex, engine.ProtocolSettings.MaxTraceableBlocks)) return VMState.NONE; return state.State; } [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)] private int GetTransactionHeight(ApplicationEngine engine, UInt256 hash) { - TransactionState state = GetTransactionState(engine.Snapshot, hash); - if (state is null || !IsTraceableBlock(engine.Snapshot, state.BlockIndex, engine.ProtocolSettings.MaxTraceableBlocks)) return -1; + TransactionState state = GetTransactionState(engine.SnapshotCache, hash); + if (state is null || !IsTraceableBlock(engine.SnapshotCache, state.BlockIndex, engine.ProtocolSettings.MaxTraceableBlocks)) return -1; return (int)state.BlockIndex; } @@ -314,17 +314,17 @@ private Transaction GetTransactionFromBlock(ApplicationEngine engine, byte[] blo { UInt256 hash; if (blockIndexOrHash.Length < UInt256.Length) - hash = GetBlockHash(engine.Snapshot, (uint)new BigInteger(blockIndexOrHash)); + hash = GetBlockHash(engine.SnapshotCache, (uint)new BigInteger(blockIndexOrHash)); else if (blockIndexOrHash.Length == UInt256.Length) hash = new UInt256(blockIndexOrHash); else throw new ArgumentException(null, nameof(blockIndexOrHash)); if (hash is null) return null; - TrimmedBlock block = GetTrimmedBlock(engine.Snapshot, hash); - if (block is null || !IsTraceableBlock(engine.Snapshot, block.Index, engine.ProtocolSettings.MaxTraceableBlocks)) return null; + TrimmedBlock block = GetTrimmedBlock(engine.SnapshotCache, hash); + if (block is null || !IsTraceableBlock(engine.SnapshotCache, block.Index, engine.ProtocolSettings.MaxTraceableBlocks)) return null; if (txIndex < 0 || txIndex >= block.Hashes.Length) throw new ArgumentOutOfRangeException(nameof(txIndex)); - return GetTransaction(engine.Snapshot, block.Hashes[txIndex]); + return GetTransaction(engine.SnapshotCache, block.Hashes[txIndex]); } private static TrimmedBlock Trim(Block block) diff --git a/src/Neo/SmartContract/Native/NativeContract.cs b/src/Neo/SmartContract/Native/NativeContract.cs index b030f06c9b..97bb0ab69a 100644 --- a/src/Neo/SmartContract/Native/NativeContract.cs +++ b/src/Neo/SmartContract/Native/NativeContract.cs @@ -41,7 +41,7 @@ public CacheEntry GetAllowedMethods(NativeContract native, ApplicationEngine eng { if (NativeContracts.TryGetValue(native.Id, out var value)) return value; - uint index = engine.PersistingBlock is null ? Ledger.CurrentIndex(engine.Snapshot) : engine.PersistingBlock.Index; + uint index = engine.PersistingBlock is null ? Ledger.CurrentIndex(engine.SnapshotCache) : engine.PersistingBlock.Index; CacheEntry methods = native.GetAllowedMethods(engine.ProtocolSettings.IsHardforkEnabled, index); NativeContracts[native.Id] = methods; return methods; @@ -343,7 +343,7 @@ internal bool IsActive(ProtocolSettings settings, uint blockHeight) /// if the committee has witnessed the current transaction; otherwise, . protected static bool CheckCommittee(ApplicationEngine engine) { - UInt160 committeeMultiSigAddr = NEO.GetCommitteeAddress(engine.Snapshot); + UInt160 committeeMultiSigAddr = NEO.GetCommitteeAddress(engine.SnapshotCache); return engine.CheckWitnessInternal(committeeMultiSigAddr); } @@ -386,7 +386,7 @@ internal async void Invoke(ApplicationEngine engine, byte version) engine.AddFee(method.CpuFee * engine.ExecFeeFactor + method.StorageFee * engine.StoragePrice); List parameters = new(); if (method.NeedApplicationEngine) parameters.Add(engine); - if (method.NeedSnapshot) parameters.Add(engine.Snapshot); + if (method.NeedSnapshot) parameters.Add(engine.SnapshotCache); for (int i = 0; i < method.Parameters.Length; i++) parameters.Add(engine.Convert(context.EvaluationStack.Peek(i), method.Parameters[i])); object returnValue = method.Handler.Invoke(this, parameters.ToArray()); diff --git a/src/Neo/SmartContract/Native/NeoToken.cs b/src/Neo/SmartContract/Native/NeoToken.cs index f43a0d6079..40f63355df 100644 --- a/src/Neo/SmartContract/Native/NeoToken.cs +++ b/src/Neo/SmartContract/Native/NeoToken.cs @@ -86,11 +86,11 @@ internal override void OnBalanceChanging(ApplicationEngine engine, UInt160 accou } if (amount.IsZero) return; if (state.VoteTo is null) return; - engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_VotersCount)).Add(amount); + engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_VotersCount)).Add(amount); StorageKey key = CreateStorageKey(Prefix_Candidate).Add(state.VoteTo); - CandidateState candidate = engine.Snapshot.GetAndChange(key).GetInteroperable(); + CandidateState candidate = engine.SnapshotCache.GetAndChange(key).GetInteroperable(); candidate.Votes += amount; - CheckCandidate(engine.Snapshot, state.VoteTo, candidate); + CheckCandidate(engine.SnapshotCache, state.VoteTo, candidate); } private protected override async ContractTask PostTransferAsync(ApplicationEngine engine, UInt160 from, UInt160 to, BigInteger amount, StackItem data, bool callOnPayment) @@ -107,12 +107,12 @@ private GasDistribution DistributeGas(ApplicationEngine engine, UInt160 account, if (engine.PersistingBlock is null) return null; // In the unit of datoshi, 1 datoshi = 1e-8 GAS - BigInteger datoshi = CalculateBonus(engine.Snapshot, state, engine.PersistingBlock.Index); + BigInteger datoshi = CalculateBonus(engine.SnapshotCache, state, engine.PersistingBlock.Index); state.BalanceHeight = engine.PersistingBlock.Index; if (state.VoteTo is not null) { var keyLastest = CreateStorageKey(Prefix_VoterRewardPerCommittee).Add(state.VoteTo); - var latestGasPerVote = engine.Snapshot.TryGet(keyLastest) ?? BigInteger.Zero; + var latestGasPerVote = engine.SnapshotCache.TryGet(keyLastest) ?? BigInteger.Zero; state.LastGasPerVote = latestGasPerVote; } if (datoshi == 0) return null; @@ -184,10 +184,10 @@ internal override ContractTask InitializeAsync(ApplicationEngine engine, Hardfor if (hardfork == ActiveIn) { var cachedCommittee = new CachedCommittee(engine.ProtocolSettings.StandbyCommittee.Select(p => (p, BigInteger.Zero))); - engine.Snapshot.Add(CreateStorageKey(Prefix_Committee), new StorageItem(cachedCommittee)); - engine.Snapshot.Add(CreateStorageKey(Prefix_VotersCount), new StorageItem(System.Array.Empty())); - engine.Snapshot.Add(CreateStorageKey(Prefix_GasPerBlock).AddBigEndian(0u), new StorageItem(5 * GAS.Factor)); - engine.Snapshot.Add(CreateStorageKey(Prefix_RegisterPrice), new StorageItem(1000 * GAS.Factor)); + engine.SnapshotCache.Add(CreateStorageKey(Prefix_Committee), new StorageItem(cachedCommittee)); + engine.SnapshotCache.Add(CreateStorageKey(Prefix_VotersCount), new StorageItem(System.Array.Empty())); + engine.SnapshotCache.Add(CreateStorageKey(Prefix_GasPerBlock).AddBigEndian(0u), new StorageItem(5 * GAS.Factor)); + engine.SnapshotCache.Add(CreateStorageKey(Prefix_RegisterPrice), new StorageItem(1000 * GAS.Factor)); return Mint(engine, Contract.GetBFTAddress(engine.ProtocolSettings.StandbyValidators), TotalAmount, false); } return ContractTask.CompletedTask; @@ -198,17 +198,17 @@ internal override ContractTask OnPersistAsync(ApplicationEngine engine) // Set next committee if (ShouldRefreshCommittee(engine.PersistingBlock.Index, engine.ProtocolSettings.CommitteeMembersCount)) { - var storageItem = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_Committee)); + var storageItem = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_Committee)); var cachedCommittee = storageItem.GetInteroperable(); var prevCommittee = cachedCommittee.Select(u => u.PublicKey).ToArray(); cachedCommittee.Clear(); - cachedCommittee.AddRange(ComputeCommitteeMembers(engine.Snapshot, engine.ProtocolSettings)); + cachedCommittee.AddRange(ComputeCommitteeMembers(engine.SnapshotCache, engine.ProtocolSettings)); // Hardfork check for https://github.com/neo-project/neo/pull/3158 // New notification will case 3.7.0 and 3.6.0 have different behavior - var index = engine.PersistingBlock?.Index ?? Ledger.CurrentIndex(engine.Snapshot); + var index = engine.PersistingBlock?.Index ?? Ledger.CurrentIndex(engine.SnapshotCache); if (engine.ProtocolSettings.IsHardforkEnabled(Hardfork.HF_Cockatrice, index)) { var newCommittee = cachedCommittee.Select(u => u.PublicKey).ToArray(); @@ -232,8 +232,8 @@ internal override async ContractTask PostPersistAsync(ApplicationEngine engine) int m = engine.ProtocolSettings.CommitteeMembersCount; int n = engine.ProtocolSettings.ValidatorsCount; int index = (int)(engine.PersistingBlock.Index % (uint)m); - var gasPerBlock = GetGasPerBlock(engine.Snapshot); - var committee = GetCommitteeFromCache(engine.Snapshot); + var gasPerBlock = GetGasPerBlock(engine.SnapshotCache); + var committee = GetCommitteeFromCache(engine.SnapshotCache); var pubkey = committee[index].PublicKey; var account = Contract.CreateSignatureRedeemScript(pubkey).ToScriptHash(); await GAS.Mint(engine, account, gasPerBlock * CommitteeRewardRatio / 100, false); @@ -251,7 +251,7 @@ internal override async ContractTask PostPersistAsync(ApplicationEngine engine) { BigInteger voterSumRewardPerNEO = factor * voterRewardOfEachCommittee / Votes; StorageKey voterRewardKey = CreateStorageKey(Prefix_VoterRewardPerCommittee).Add(PublicKey); - StorageItem lastRewardPerNeo = engine.Snapshot.GetAndChange(voterRewardKey, () => new StorageItem(BigInteger.Zero)); + StorageItem lastRewardPerNeo = engine.SnapshotCache.GetAndChange(voterRewardKey, () => new StorageItem(BigInteger.Zero)); lastRewardPerNeo.Add(voterSumRewardPerNEO); } } @@ -266,7 +266,7 @@ private void SetGasPerBlock(ApplicationEngine engine, BigInteger gasPerBlock) if (!CheckCommittee(engine)) throw new InvalidOperationException(); uint index = engine.PersistingBlock.Index + 1; - StorageItem entry = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_GasPerBlock).AddBigEndian(index), () => new StorageItem(gasPerBlock)); + StorageItem entry = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_GasPerBlock).AddBigEndian(index), () => new StorageItem(gasPerBlock)); entry.Set(gasPerBlock); } @@ -287,7 +287,7 @@ private void SetRegisterPrice(ApplicationEngine engine, long registerPrice) if (registerPrice <= 0) throw new ArgumentOutOfRangeException(nameof(registerPrice)); if (!CheckCommittee(engine)) throw new InvalidOperationException(); - engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_RegisterPrice)).Set(registerPrice); + engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_RegisterPrice)).Set(registerPrice); } /// @@ -332,9 +332,9 @@ private bool RegisterCandidate(ApplicationEngine engine, ECPoint pubkey) if (!engine.CheckWitnessInternal(Contract.CreateSignatureRedeemScript(pubkey).ToScriptHash())) return false; // In the unit of datoshi, 1 datoshi = 1e-8 GAS - engine.AddFee(GetRegisterPrice(engine.Snapshot)); + engine.AddFee(GetRegisterPrice(engine.SnapshotCache)); StorageKey key = CreateStorageKey(Prefix_Candidate).Add(pubkey); - StorageItem item = engine.Snapshot.GetAndChange(key, () => new StorageItem(new CandidateState())); + StorageItem item = engine.SnapshotCache.GetAndChange(key, () => new StorageItem(new CandidateState())); CandidateState state = item.GetInteroperable(); if (state.Registered) return true; state.Registered = true; @@ -349,12 +349,12 @@ private bool UnregisterCandidate(ApplicationEngine engine, ECPoint pubkey) if (!engine.CheckWitnessInternal(Contract.CreateSignatureRedeemScript(pubkey).ToScriptHash())) return false; StorageKey key = CreateStorageKey(Prefix_Candidate).Add(pubkey); - if (engine.Snapshot.TryGet(key) is null) return true; - StorageItem item = engine.Snapshot.GetAndChange(key); + if (engine.SnapshotCache.TryGet(key) is null) return true; + StorageItem item = engine.SnapshotCache.GetAndChange(key); CandidateState state = item.GetInteroperable(); if (!state.Registered) return true; state.Registered = false; - CheckCandidate(engine.Snapshot, pubkey, state); + CheckCandidate(engine.SnapshotCache, pubkey, state); engine.SendNotification(Hash, "CandidateStateChanged", new VM.Types.Array(engine.ReferenceCounter) { pubkey.ToArray(), false, state.Votes }); return true; @@ -364,19 +364,19 @@ private bool UnregisterCandidate(ApplicationEngine engine, ECPoint pubkey) private async ContractTask Vote(ApplicationEngine engine, UInt160 account, ECPoint voteTo) { if (!engine.CheckWitnessInternal(account)) return false; - NeoAccountState state_account = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_Account).Add(account))?.GetInteroperable(); + NeoAccountState state_account = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_Account).Add(account))?.GetInteroperable(); if (state_account is null) return false; if (state_account.Balance == 0) return false; CandidateState validator_new = null; if (voteTo != null) { - validator_new = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_Candidate).Add(voteTo))?.GetInteroperable(); + validator_new = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_Candidate).Add(voteTo))?.GetInteroperable(); if (validator_new is null) return false; if (!validator_new.Registered) return false; } if (state_account.VoteTo is null ^ voteTo is null) { - StorageItem item = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_VotersCount)); + StorageItem item = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_VotersCount)); if (state_account.VoteTo is null) item.Add(state_account.Balance); else @@ -386,15 +386,15 @@ private async ContractTask Vote(ApplicationEngine engine, UInt160 account, if (state_account.VoteTo != null) { StorageKey key = CreateStorageKey(Prefix_Candidate).Add(state_account.VoteTo); - StorageItem storage_validator = engine.Snapshot.GetAndChange(key); + StorageItem storage_validator = engine.SnapshotCache.GetAndChange(key); CandidateState state_validator = storage_validator.GetInteroperable(); state_validator.Votes -= state_account.Balance; - CheckCandidate(engine.Snapshot, state_account.VoteTo, state_validator); + CheckCandidate(engine.SnapshotCache, state_account.VoteTo, state_validator); } if (voteTo != null && voteTo != state_account.VoteTo) { StorageKey voterRewardKey = CreateStorageKey(Prefix_VoterRewardPerCommittee).Add(voteTo); - var latestGasPerVote = engine.Snapshot.TryGet(voterRewardKey) ?? BigInteger.Zero; + var latestGasPerVote = engine.SnapshotCache.TryGet(voterRewardKey) ?? BigInteger.Zero; state_account.LastGasPerVote = latestGasPerVote; } ECPoint from = state_account.VoteTo; @@ -536,7 +536,7 @@ public ECPoint[] ComputeNextBlockValidators(DataCache snapshot, ProtocolSettings [ContractMethod(CpuFee = 1 << 16, RequiredCallFlags = CallFlags.ReadStates)] private ECPoint[] GetNextBlockValidators(ApplicationEngine engine) { - return GetNextBlockValidators(engine.Snapshot, engine.ProtocolSettings.ValidatorsCount); + return GetNextBlockValidators(engine.SnapshotCache, engine.ProtocolSettings.ValidatorsCount); } /// diff --git a/src/Neo/SmartContract/Native/OracleContract.cs b/src/Neo/SmartContract/Native/OracleContract.cs index 13a7264660..be4765581a 100644 --- a/src/Neo/SmartContract/Native/OracleContract.cs +++ b/src/Neo/SmartContract/Native/OracleContract.cs @@ -56,7 +56,7 @@ private void SetPrice(ApplicationEngine engine, long price) if (price <= 0) throw new ArgumentOutOfRangeException(nameof(price)); if (!CheckCommittee(engine)) throw new InvalidOperationException(); - engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_Price)).Set(price); + engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_Price)).Set(price); } /// @@ -78,7 +78,7 @@ private ContractTask Finish(ApplicationEngine engine) Transaction tx = (Transaction)engine.ScriptContainer; OracleResponse response = tx.GetAttribute(); if (response == null) throw new ArgumentException("Oracle response was not found"); - OracleRequest request = GetRequest(engine.Snapshot, response.Id); + OracleRequest request = GetRequest(engine.SnapshotCache, response.Id); if (request == null) throw new ArgumentException("Oracle request was not found"); engine.SendNotification(Hash, "OracleResponse", new VM.Types.Array(engine.ReferenceCounter) { response.Id, request.OriginalTxid.ToArray() }); StackItem userData = BinarySerializer.Deserialize(request.UserData, engine.Limits, engine.ReferenceCounter); @@ -90,7 +90,7 @@ private UInt256 GetOriginalTxid(ApplicationEngine engine) Transaction tx = (Transaction)engine.ScriptContainer; OracleResponse response = tx.GetAttribute(); if (response is null) return tx.Hash; - OracleRequest request = GetRequest(engine.Snapshot, response.Id); + OracleRequest request = GetRequest(engine.SnapshotCache, response.Id); return request.OriginalTxid; } @@ -138,8 +138,8 @@ internal override ContractTask InitializeAsync(ApplicationEngine engine, Hardfor { if (hardfork == ActiveIn) { - engine.Snapshot.Add(CreateStorageKey(Prefix_RequestId), new StorageItem(BigInteger.Zero)); - engine.Snapshot.Add(CreateStorageKey(Prefix_Price), new StorageItem(0_50000000)); + engine.SnapshotCache.Add(CreateStorageKey(Prefix_RequestId), new StorageItem(BigInteger.Zero)); + engine.SnapshotCache.Add(CreateStorageKey(Prefix_Price), new StorageItem(0_50000000)); } return ContractTask.CompletedTask; } @@ -155,22 +155,22 @@ internal override async ContractTask PostPersistAsync(ApplicationEngine engine) //Remove the request from storage StorageKey key = CreateStorageKey(Prefix_Request).AddBigEndian(response.Id); - OracleRequest request = engine.Snapshot.TryGet(key)?.GetInteroperable(); + OracleRequest request = engine.SnapshotCache.TryGet(key)?.GetInteroperable(); if (request == null) continue; - engine.Snapshot.Delete(key); + engine.SnapshotCache.Delete(key); //Remove the id from IdList key = CreateStorageKey(Prefix_IdList).Add(GetUrlHash(request.Url)); - IdList list = engine.Snapshot.GetAndChange(key).GetInteroperable(); + IdList list = engine.SnapshotCache.GetAndChange(key).GetInteroperable(); if (!list.Remove(response.Id)) throw new InvalidOperationException(); - if (list.Count == 0) engine.Snapshot.Delete(key); + if (list.Count == 0) engine.SnapshotCache.Delete(key); //Mint GAS for oracle nodes - nodes ??= RoleManagement.GetDesignatedByRole(engine.Snapshot, Role.Oracle, engine.PersistingBlock.Index).Select(p => (Contract.CreateSignatureRedeemScript(p).ToScriptHash(), BigInteger.Zero)).ToArray(); + nodes ??= RoleManagement.GetDesignatedByRole(engine.SnapshotCache, Role.Oracle, engine.PersistingBlock.Index).Select(p => (Contract.CreateSignatureRedeemScript(p).ToScriptHash(), BigInteger.Zero)).ToArray(); if (nodes.Length > 0) { int index = (int)(response.Id % (ulong)nodes.Length); - nodes[index].GAS += GetPrice(engine.Snapshot); + nodes[index].GAS += GetPrice(engine.SnapshotCache); } } if (nodes != null) @@ -193,21 +193,21 @@ private async ContractTask Request(ApplicationEngine engine, string url, string || gasForResponse < 0_10000000) throw new ArgumentException(); - engine.AddFee(GetPrice(engine.Snapshot)); + engine.AddFee(GetPrice(engine.SnapshotCache)); //Mint gas for the response engine.AddFee(gasForResponse); await GAS.Mint(engine, Hash, gasForResponse, false); //Increase the request id - StorageItem item_id = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_RequestId)); + StorageItem item_id = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_RequestId)); ulong id = (ulong)(BigInteger)item_id; item_id.Add(1); //Put the request to storage - if (ContractManagement.GetContract(engine.Snapshot, engine.CallingScriptHash) is null) + if (ContractManagement.GetContract(engine.SnapshotCache, engine.CallingScriptHash) is null) throw new InvalidOperationException(); - engine.Snapshot.Add(CreateStorageKey(Prefix_Request).AddBigEndian(id), new StorageItem(new OracleRequest + engine.SnapshotCache.Add(CreateStorageKey(Prefix_Request).AddBigEndian(id), new StorageItem(new OracleRequest { OriginalTxid = GetOriginalTxid(engine), GasForResponse = gasForResponse, @@ -219,7 +219,7 @@ private async ContractTask Request(ApplicationEngine engine, string url, string })); //Add the id to the IdList - var list = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_IdList).Add(GetUrlHash(url)), () => new StorageItem(new IdList())).GetInteroperable(); + var list = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_IdList).Add(GetUrlHash(url)), () => new StorageItem(new IdList())).GetInteroperable(); if (list.Count >= 256) throw new InvalidOperationException("There are too many pending responses for this url"); list.Add(id); diff --git a/src/Neo/SmartContract/Native/PolicyContract.cs b/src/Neo/SmartContract/Native/PolicyContract.cs index 2da6255094..744b7b3ab6 100644 --- a/src/Neo/SmartContract/Native/PolicyContract.cs +++ b/src/Neo/SmartContract/Native/PolicyContract.cs @@ -71,9 +71,9 @@ internal override ContractTask InitializeAsync(ApplicationEngine engine, Hardfor { if (hardfork == ActiveIn) { - engine.Snapshot.Add(CreateStorageKey(Prefix_FeePerByte), new StorageItem(DefaultFeePerByte)); - engine.Snapshot.Add(CreateStorageKey(Prefix_ExecFeeFactor), new StorageItem(DefaultExecFeeFactor)); - engine.Snapshot.Add(CreateStorageKey(Prefix_StoragePrice), new StorageItem(DefaultStoragePrice)); + engine.SnapshotCache.Add(CreateStorageKey(Prefix_FeePerByte), new StorageItem(DefaultFeePerByte)); + engine.SnapshotCache.Add(CreateStorageKey(Prefix_ExecFeeFactor), new StorageItem(DefaultExecFeeFactor)); + engine.SnapshotCache.Add(CreateStorageKey(Prefix_StoragePrice), new StorageItem(DefaultStoragePrice)); } return ContractTask.CompletedTask; } @@ -146,7 +146,7 @@ private void SetAttributeFee(ApplicationEngine engine, byte attributeType, uint if (value > MaxAttributeFee) throw new ArgumentOutOfRangeException(nameof(value)); if (!CheckCommittee(engine)) throw new InvalidOperationException(); - engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_AttributeFee).Add(attributeType), () => new StorageItem(DefaultAttributeFee)).Set(value); + engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_AttributeFee).Add(attributeType), () => new StorageItem(DefaultAttributeFee)).Set(value); } [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.States)] @@ -154,7 +154,7 @@ private void SetFeePerByte(ApplicationEngine engine, long value) { if (value < 0 || value > 1_00000000) throw new ArgumentOutOfRangeException(nameof(value)); if (!CheckCommittee(engine)) throw new InvalidOperationException(); - engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_FeePerByte)).Set(value); + engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_FeePerByte)).Set(value); } [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.States)] @@ -162,7 +162,7 @@ private void SetExecFeeFactor(ApplicationEngine engine, uint value) { if (value == 0 || value > MaxExecFeeFactor) throw new ArgumentOutOfRangeException(nameof(value)); if (!CheckCommittee(engine)) throw new InvalidOperationException(); - engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_ExecFeeFactor)).Set(value); + engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_ExecFeeFactor)).Set(value); } [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.States)] @@ -170,14 +170,14 @@ private void SetStoragePrice(ApplicationEngine engine, uint value) { if (value == 0 || value > MaxStoragePrice) throw new ArgumentOutOfRangeException(nameof(value)); if (!CheckCommittee(engine)) throw new InvalidOperationException(); - engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_StoragePrice)).Set(value); + engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_StoragePrice)).Set(value); } [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.States)] private bool BlockAccount(ApplicationEngine engine, UInt160 account) { if (!CheckCommittee(engine)) throw new InvalidOperationException(); - return BlockAccount(engine.Snapshot, account); + return BlockAccount(engine.SnapshotCache, account); } internal bool BlockAccount(DataCache snapshot, UInt160 account) @@ -197,9 +197,9 @@ private bool UnblockAccount(ApplicationEngine engine, UInt160 account) if (!CheckCommittee(engine)) throw new InvalidOperationException(); var key = CreateStorageKey(Prefix_BlockedAccount).Add(account); - if (!engine.Snapshot.Contains(key)) return false; + if (!engine.SnapshotCache.Contains(key)) return false; - engine.Snapshot.Delete(key); + engine.SnapshotCache.Delete(key); return true; } } diff --git a/src/Neo/SmartContract/Native/RoleManagement.cs b/src/Neo/SmartContract/Native/RoleManagement.cs index 6e989b78cf..d0437594c9 100644 --- a/src/Neo/SmartContract/Native/RoleManagement.cs +++ b/src/Neo/SmartContract/Native/RoleManagement.cs @@ -63,12 +63,12 @@ private void DesignateAsRole(ApplicationEngine engine, Role role, ECPoint[] node throw new InvalidOperationException(nameof(DesignateAsRole)); uint index = engine.PersistingBlock.Index + 1; var key = CreateStorageKey((byte)role).AddBigEndian(index); - if (engine.Snapshot.Contains(key)) + if (engine.SnapshotCache.Contains(key)) throw new InvalidOperationException(); NodeList list = new(); list.AddRange(nodes); list.Sort(); - engine.Snapshot.Add(key, new StorageItem(list)); + engine.SnapshotCache.Add(key, new StorageItem(list)); engine.SendNotification(Hash, "Designation", new VM.Types.Array(engine.ReferenceCounter, new StackItem[] { (int)role, engine.PersistingBlock.Index })); } diff --git a/src/Neo/Wallets/Wallet.cs b/src/Neo/Wallets/Wallet.cs index d23bdcfb9f..fc71a9135c 100644 --- a/src/Neo/Wallets/Wallet.cs +++ b/src/Neo/Wallets/Wallet.cs @@ -636,7 +636,7 @@ public bool Sign(ContractParametersContext context) // Try Smart contract verification - var contract = NativeContract.ContractManagement.GetContract(context.Snapshot, scriptHash); + var contract = NativeContract.ContractManagement.GetContract(context.SnapshotCache, scriptHash); if (contract != null) { diff --git a/src/Plugins/RpcServer/RpcServer.SmartContract.cs b/src/Plugins/RpcServer/RpcServer.SmartContract.cs index 2fe49d4965..473ae0cb5d 100644 --- a/src/Plugins/RpcServer/RpcServer.SmartContract.cs +++ b/src/Plugins/RpcServer/RpcServer.SmartContract.cs @@ -92,7 +92,7 @@ private JObject GetInvokeResult(byte[] script, Signer[] signers = null, Witness[ json["diagnostics"] = new JObject() { ["invokedcontracts"] = ToJson(diagnostic.InvocationTree.Root), - ["storagechanges"] = ToJson(session.Engine.Snapshot.GetChangeSet()) + ["storagechanges"] = ToJson(session.Engine.SnapshotCache.GetChangeSet()) }; } var stack = new JArray(); diff --git a/tests/Neo.Plugins.OracleService.Tests/UT_OracleService.cs b/tests/Neo.Plugins.OracleService.Tests/UT_OracleService.cs index 79771ee796..33d82c618c 100644 --- a/tests/Neo.Plugins.OracleService.Tests/UT_OracleService.cs +++ b/tests/Neo.Plugins.OracleService.Tests/UT_OracleService.cs @@ -70,11 +70,11 @@ public void TestFilter() [TestMethod] public void TestCreateOracleResponseTx() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); - var executionFactor = NativeContract.Policy.GetExecFeeFactor(snapshot); + var executionFactor = NativeContract.Policy.GetExecFeeFactor(snapshotCache); Assert.AreEqual(executionFactor, (uint)30); - var feePerByte = NativeContract.Policy.GetFeePerByte(snapshot); + var feePerByte = NativeContract.Policy.GetFeePerByte(snapshotCache); Assert.AreEqual(feePerByte, 1000); OracleRequest request = new OracleRequest @@ -88,7 +88,7 @@ public void TestCreateOracleResponseTx() UserData = [] }; byte Prefix_Transaction = 11; - snapshot.Add(NativeContract.Ledger.CreateStorageKey(Prefix_Transaction, request.OriginalTxid), new StorageItem(new TransactionState() + snapshotCache.Add(NativeContract.Ledger.CreateStorageKey(Prefix_Transaction, request.OriginalTxid), new StorageItem(new TransactionState() { BlockIndex = 1, Transaction = new Transaction() @@ -98,7 +98,7 @@ public void TestCreateOracleResponseTx() })); OracleResponse response = new OracleResponse() { Id = 1, Code = OracleResponseCode.Success, Result = new byte[] { 0x00 } }; ECPoint[] oracleNodes = new ECPoint[] { ECCurve.Secp256r1.G }; - var tx = OracleService.CreateResponseTx(snapshot, request, response, oracleNodes, ProtocolSettings.Default); + var tx = OracleService.CreateResponseTx(snapshotCache, request, response, oracleNodes, ProtocolSettings.Default); Assert.AreEqual(166, tx.Size); Assert.AreEqual(2198650, tx.NetworkFee); @@ -108,7 +108,7 @@ public void TestCreateOracleResponseTx() request.GasForResponse = 0_10000000; response.Result = new byte[10250]; - tx = OracleService.CreateResponseTx(snapshot, request, response, oracleNodes, ProtocolSettings.Default); + tx = OracleService.CreateResponseTx(snapshotCache, request, response, oracleNodes, ProtocolSettings.Default); Assert.AreEqual(165, tx.Size); Assert.AreEqual(OracleResponseCode.InsufficientFunds, response.Code); Assert.AreEqual(2197650, tx.NetworkFee); diff --git a/tests/Neo.UnitTests/IO/Caching/UT_CloneCache.cs b/tests/Neo.UnitTests/IO/Caching/UT_CloneCache.cs index 71eeb4ac25..e5fea8130a 100644 --- a/tests/Neo.UnitTests/IO/Caching/UT_CloneCache.cs +++ b/tests/Neo.UnitTests/IO/Caching/UT_CloneCache.cs @@ -155,8 +155,8 @@ public void TestUpdateInternal() [TestMethod] public void TestCacheOverrideIssue2572() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); - var storages = snapshot.CreateSnapshot(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); + var storages = snapshotCache.CreateSnapshot(); storages.Add ( @@ -174,10 +174,10 @@ public void TestCacheOverrideIssue2572() var item = storages.GetAndChange(new StorageKey() { Key = new byte[] { 0x01, 0x01 }, Id = 0 }); item.Value = new byte[] { 0x06 }; - var res = snapshot.TryGet(new StorageKey() { Key = new byte[] { 0x01, 0x01 }, Id = 0 }); + var res = snapshotCache.TryGet(new StorageKey() { Key = new byte[] { 0x01, 0x01 }, Id = 0 }); Assert.AreEqual("05", res.Value.Span.ToHexString()); storages.Commit(); - res = snapshot.TryGet(new StorageKey() { Key = new byte[] { 0x01, 0x01 }, Id = 0 }); + res = snapshotCache.TryGet(new StorageKey() { Key = new byte[] { 0x01, 0x01 }, Id = 0 }); Assert.AreEqual("06", res.Value.Span.ToHexString()); } } diff --git a/tests/Neo.UnitTests/Ledger/UT_Blockchain.cs b/tests/Neo.UnitTests/Ledger/UT_Blockchain.cs index 1ccfabbe92..9ee5dd6929 100644 --- a/tests/Neo.UnitTests/Ledger/UT_Blockchain.cs +++ b/tests/Neo.UnitTests/Ledger/UT_Blockchain.cs @@ -146,7 +146,7 @@ public void TestMaliciousOnChainConflict() { engine2.LoadScript(onPersistScript); if (engine2.Execute() != VMState.HALT) throw engine2.FaultException; - engine2.Snapshot.Commit(); + engine2.SnapshotCache.Commit(); } snapshot.Commit(); @@ -162,7 +162,7 @@ public void TestMaliciousOnChainConflict() { engine2.LoadScript(postPersistScript); if (engine2.Execute() != VMState.HALT) throw engine2.FaultException; - engine2.Snapshot.Commit(); + engine2.SnapshotCache.Commit(); } snapshot.Commit(); diff --git a/tests/Neo.UnitTests/Ledger/UT_MemoryPool.cs b/tests/Neo.UnitTests/Ledger/UT_MemoryPool.cs index 73cbb37dc9..45cdee05c7 100644 --- a/tests/Neo.UnitTests/Ledger/UT_MemoryPool.cs +++ b/tests/Neo.UnitTests/Ledger/UT_MemoryPool.cs @@ -225,7 +225,7 @@ public async Task BlockPersistAndReverificationWillAbandonTxAsBalanceTransfered( _ = NativeContract.GAS.Mint(engine, UInt160.Zero, 70, true); long txFee = 1; - AddTransactionsWithBalanceVerify(70, txFee, engine.Snapshot); + AddTransactionsWithBalanceVerify(70, txFee, engine.SnapshotCache); _unit.SortedTxCount.Should().Be(70); @@ -244,7 +244,7 @@ public async Task BlockPersistAndReverificationWillAbandonTxAsBalanceTransfered( _ = NativeContract.GAS.Mint(applicationEngine, sender, txFee * 30, true); // Set the balance to meet 30 txs only // Persist block and reverify all the txs in mempool, but half of the txs will be discarded - _unit.UpdatePoolForBlockPersisted(block, applicationEngine.Snapshot); + _unit.UpdatePoolForBlockPersisted(block, applicationEngine.SnapshotCache); _unit.SortedTxCount.Should().Be(30); _unit.UnverifiedSortedTxCount.Should().Be(0); @@ -266,30 +266,30 @@ public async Task UpdatePoolForBlockPersisted_RemoveBlockConflicts() _ = NativeContract.GAS.Mint(engine, UInt160.Zero, 7, true); // balance enough for 7 mempooled txs var mp1 = CreateTransactionWithFeeAndBalanceVerify(txFee); // mp1 doesn't conflict with anyone - _unit.TryAdd(mp1, engine.Snapshot).Should().Be(VerifyResult.Succeed); + _unit.TryAdd(mp1, engine.SnapshotCache).Should().Be(VerifyResult.Succeed); var tx1 = CreateTransactionWithFeeAndBalanceVerify(txFee); // but in-block tx1 conflicts with mempooled mp1 => mp1 should be removed from pool after persist tx1.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = mp1.Hash } }; var mp2 = CreateTransactionWithFeeAndBalanceVerify(txFee); // mp1 and mp2 don't conflict with anyone - _unit.TryAdd(mp2, engine.Snapshot); + _unit.TryAdd(mp2, engine.SnapshotCache); var mp3 = CreateTransactionWithFeeAndBalanceVerify(txFee); - _unit.TryAdd(mp3, engine.Snapshot); + _unit.TryAdd(mp3, engine.SnapshotCache); var tx2 = CreateTransactionWithFeeAndBalanceVerify(txFee); // in-block tx2 conflicts with mempooled mp2 and mp3 => mp2 and mp3 should be removed from pool after persist tx2.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = mp2.Hash }, new Conflicts() { Hash = mp3.Hash } }; var tx3 = CreateTransactionWithFeeAndBalanceVerify(txFee); // in-block tx3 doesn't conflict with anyone var mp4 = CreateTransactionWithFeeAndBalanceVerify(txFee); // mp4 conflicts with in-block tx3 => mp4 should be removed from pool after persist mp4.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = tx3.Hash } }; - _unit.TryAdd(mp4, engine.Snapshot); + _unit.TryAdd(mp4, engine.SnapshotCache); var tx4 = CreateTransactionWithFeeAndBalanceVerify(txFee); // in-block tx4 and tx5 don't conflict with anyone var tx5 = CreateTransactionWithFeeAndBalanceVerify(txFee); var mp5 = CreateTransactionWithFeeAndBalanceVerify(txFee); // mp5 conflicts with in-block tx4 and tx5 => mp5 should be removed from pool after persist mp5.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = tx4.Hash }, new Conflicts() { Hash = tx5.Hash } }; - _unit.TryAdd(mp5, engine.Snapshot); + _unit.TryAdd(mp5, engine.SnapshotCache); var mp6 = CreateTransactionWithFeeAndBalanceVerify(txFee); // mp6 doesn't conflict with anyone and noone conflicts with mp6 => mp6 should be left in the pool after persist - _unit.TryAdd(mp6, engine.Snapshot); + _unit.TryAdd(mp6, engine.SnapshotCache); _unit.SortedTxCount.Should().Be(6); _unit.UnverifiedSortedTxCount.Should().Be(0); @@ -298,7 +298,7 @@ public async Task UpdatePoolForBlockPersisted_RemoveBlockConflicts() var tx6 = CreateTransactionWithFeeAndBalanceVerify(txFee); // in-block tx6 conflicts with mp7, but doesn't include sender of mp7 into signers list => even if tx6 is included into block, mp7 shouldn't be removed from the pool tx6.Signers = new Signer[] { new Signer() { Account = new UInt160(Crypto.Hash160(new byte[] { 1, 2, 3 })) }, new Signer() { Account = new UInt160(Crypto.Hash160(new byte[] { 4, 5, 6 })) } }; tx6.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = mp7.Hash } }; - _unit.TryAdd(mp7, engine.Snapshot); + _unit.TryAdd(mp7, engine.SnapshotCache); // Act: persist block and reverify all mempooled txs. var block = new Block @@ -306,7 +306,7 @@ public async Task UpdatePoolForBlockPersisted_RemoveBlockConflicts() Header = new Header(), Transactions = new Transaction[] { tx1, tx2, tx3, tx4, tx5, tx6 }, }; - _unit.UpdatePoolForBlockPersisted(block, engine.Snapshot); + _unit.UpdatePoolForBlockPersisted(block, engine.SnapshotCache); // Assert: conflicting txs should be removed from the pool; the only mp6 that doesn't conflict with anyone should be left. _unit.SortedTxCount.Should().Be(2); @@ -337,14 +337,14 @@ public async Task TryAdd_AddRangeOfConflictingTransactions() var mp2_1 = CreateTransactionWithFeeAndBalanceVerify(txFee); // mp2_1 conflicts with mp1 and has the same network fee mp2_1.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = mp1.Hash } }; - _unit.TryAdd(mp2_1, engine.Snapshot); + _unit.TryAdd(mp2_1, engine.SnapshotCache); var mp2_2 = CreateTransactionWithFeeAndBalanceVerify(txFee); // mp2_2 also conflicts with mp1 and has the same network fee as mp1 and mp2_1 mp2_2.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = mp1.Hash } }; - _unit.TryAdd(mp2_2, engine.Snapshot); + _unit.TryAdd(mp2_2, engine.SnapshotCache); var mp3 = CreateTransactionWithFeeAndBalanceVerify(2 * txFee); // mp3 conflicts with mp1 and has larger network fee mp3.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = mp1.Hash } }; - _unit.TryAdd(mp3, engine.Snapshot); + _unit.TryAdd(mp3, engine.SnapshotCache); var mp4 = CreateTransactionWithFeeAndBalanceVerify(3 * txFee); // mp4 conflicts with mp3 and has larger network fee mp4.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = mp3.Hash } }; @@ -372,44 +372,44 @@ public async Task TryAdd_AddRangeOfConflictingTransactions() _unit.UnverifiedSortedTxCount.Should().Be(0); // Act & Assert: try to add conlflicting transactions to the pool. - _unit.TryAdd(mp1, engine.Snapshot).Should().Be(VerifyResult.HasConflicts); // mp1 conflicts with mp2_1, mp2_2 and mp3 but has lower network fee than mp3 => mp1 fails to be added + _unit.TryAdd(mp1, engine.SnapshotCache).Should().Be(VerifyResult.HasConflicts); // mp1 conflicts with mp2_1, mp2_2 and mp3 but has lower network fee than mp3 => mp1 fails to be added _unit.SortedTxCount.Should().Be(3); _unit.GetVerifiedTransactions().Should().Contain(new List() { mp2_1, mp2_2, mp3 }); - _unit.TryAdd(malicious, engine.Snapshot).Should().Be(VerifyResult.HasConflicts); // malicious conflicts with mp3, has larger network fee but malicious (different) sender => mp3 shoould be left in pool + _unit.TryAdd(malicious, engine.SnapshotCache).Should().Be(VerifyResult.HasConflicts); // malicious conflicts with mp3, has larger network fee but malicious (different) sender => mp3 shoould be left in pool _unit.SortedTxCount.Should().Be(3); _unit.GetVerifiedTransactions().Should().Contain(new List() { mp2_1, mp2_2, mp3 }); - _unit.TryAdd(mp4, engine.Snapshot).Should().Be(VerifyResult.Succeed); // mp4 conflicts with mp3 and has larger network fee => mp3 shoould be removed from pool + _unit.TryAdd(mp4, engine.SnapshotCache).Should().Be(VerifyResult.Succeed); // mp4 conflicts with mp3 and has larger network fee => mp3 shoould be removed from pool _unit.SortedTxCount.Should().Be(3); _unit.GetVerifiedTransactions().Should().Contain(new List() { mp2_1, mp2_2, mp4 }); - _unit.TryAdd(mp1, engine.Snapshot).Should().Be(VerifyResult.HasConflicts); // mp1 conflicts with mp2_1 and mp2_2 and has same network fee => mp2_1 and mp2_2 should be left in pool. + _unit.TryAdd(mp1, engine.SnapshotCache).Should().Be(VerifyResult.HasConflicts); // mp1 conflicts with mp2_1 and mp2_2 and has same network fee => mp2_1 and mp2_2 should be left in pool. _unit.SortedTxCount.Should().Be(3); _unit.GetVerifiedTransactions().Should().Contain(new List() { mp2_1, mp2_2, mp4 }); - _unit.TryAdd(mp6, engine.Snapshot).Should().Be(VerifyResult.Succeed); // mp6 conflicts with mp2_1 and mp2_2 and has larger network fee than the sum of mp2_1 and mp2_2 fees => mp6 should be added. + _unit.TryAdd(mp6, engine.SnapshotCache).Should().Be(VerifyResult.Succeed); // mp6 conflicts with mp2_1 and mp2_2 and has larger network fee than the sum of mp2_1 and mp2_2 fees => mp6 should be added. _unit.SortedTxCount.Should().Be(2); _unit.GetVerifiedTransactions().Should().Contain(new List() { mp6, mp4 }); - _unit.TryAdd(mp1, engine.Snapshot).Should().Be(VerifyResult.Succeed); // mp1 conflicts with mp2_1 and mp2_2, but they are not in the pool now => mp1 should be added. + _unit.TryAdd(mp1, engine.SnapshotCache).Should().Be(VerifyResult.Succeed); // mp1 conflicts with mp2_1 and mp2_2, but they are not in the pool now => mp1 should be added. _unit.SortedTxCount.Should().Be(3); _unit.GetVerifiedTransactions().Should().Contain(new List() { mp1, mp6, mp4 }); - _unit.TryAdd(mp2_1, engine.Snapshot).Should().Be(VerifyResult.HasConflicts); // mp2_1 conflicts with mp1 and has same network fee => mp2_1 shouldn't be added to the pool. + _unit.TryAdd(mp2_1, engine.SnapshotCache).Should().Be(VerifyResult.HasConflicts); // mp2_1 conflicts with mp1 and has same network fee => mp2_1 shouldn't be added to the pool. _unit.SortedTxCount.Should().Be(3); _unit.GetVerifiedTransactions().Should().Contain(new List() { mp1, mp6, mp4 }); - _unit.TryAdd(mp5, engine.Snapshot).Should().Be(VerifyResult.HasConflicts); // mp5 conflicts with mp4 and has smaller network fee => mp5 fails to be added. + _unit.TryAdd(mp5, engine.SnapshotCache).Should().Be(VerifyResult.HasConflicts); // mp5 conflicts with mp4 and has smaller network fee => mp5 fails to be added. _unit.SortedTxCount.Should().Be(3); _unit.GetVerifiedTransactions().Should().Contain(new List() { mp1, mp6, mp4 }); - _unit.TryAdd(mp8, engine.Snapshot).Should().Be(VerifyResult.Succeed); // mp8, mp9 and mp10malicious conflict with mp7, but mo7 is not in the pool yet. - _unit.TryAdd(mp9, engine.Snapshot).Should().Be(VerifyResult.Succeed); - _unit.TryAdd(mp10malicious, engine.Snapshot).Should().Be(VerifyResult.Succeed); + _unit.TryAdd(mp8, engine.SnapshotCache).Should().Be(VerifyResult.Succeed); // mp8, mp9 and mp10malicious conflict with mp7, but mo7 is not in the pool yet. + _unit.TryAdd(mp9, engine.SnapshotCache).Should().Be(VerifyResult.Succeed); + _unit.TryAdd(mp10malicious, engine.SnapshotCache).Should().Be(VerifyResult.Succeed); _unit.SortedTxCount.Should().Be(6); _unit.GetVerifiedTransactions().Should().Contain(new List() { mp1, mp6, mp4, mp8, mp9, mp10malicious }); - _unit.TryAdd(mp7, engine.Snapshot).Should().Be(VerifyResult.Succeed); // mp7 has larger network fee than the sum of mp8 and mp9 fees => should be added to the pool. + _unit.TryAdd(mp7, engine.SnapshotCache).Should().Be(VerifyResult.Succeed); // mp7 has larger network fee than the sum of mp8 and mp9 fees => should be added to the pool. _unit.SortedTxCount.Should().Be(4); _unit.GetVerifiedTransactions().Should().Contain(new List() { mp1, mp6, mp4, mp7 }); @@ -436,18 +436,18 @@ public async Task TryRemoveVerified_RemoveVerifiedTxWithConflicts() var mp2 = CreateTransactionWithFeeAndBalanceVerify(2 * txFee); // mp2 conflicts with mp1 and has larger same network fee mp2.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = mp1.Hash } }; - _unit.TryAdd(mp2, engine.Snapshot); + _unit.TryAdd(mp2, engine.SnapshotCache); _unit.SortedTxCount.Should().Be(1); _unit.UnverifiedSortedTxCount.Should().Be(0); - _unit.TryAdd(mp1, engine.Snapshot).Should().Be(VerifyResult.HasConflicts); // mp1 conflicts with mp2 but has lower network fee + _unit.TryAdd(mp1, engine.SnapshotCache).Should().Be(VerifyResult.HasConflicts); // mp1 conflicts with mp2 but has lower network fee _unit.SortedTxCount.Should().Be(1); _unit.GetVerifiedTransactions().Should().Contain(new List() { mp2 }); // Act & Assert: try to invalidate verified transactions and push conflicting one. _unit.InvalidateVerifiedTransactions(); - _unit.TryAdd(mp1, engine.Snapshot).Should().Be(VerifyResult.Succeed); // mp1 conflicts with mp2 but mp2 is not verified anymore + _unit.TryAdd(mp1, engine.SnapshotCache).Should().Be(VerifyResult.Succeed); // mp1 conflicts with mp2 but mp2 is not verified anymore _unit.SortedTxCount.Should().Be(1); _unit.GetVerifiedTransactions().Should().Contain(new List() { mp1 }); @@ -457,7 +457,7 @@ public async Task TryRemoveVerified_RemoveVerifiedTxWithConflicts() Header = new Header(), Transactions = new Transaction[] { tx1 }, }; - _unit.UpdatePoolForBlockPersisted(block, engine.Snapshot); + _unit.UpdatePoolForBlockPersisted(block, engine.SnapshotCache); _unit.SortedTxCount.Should().Be(1); _unit.GetVerifiedTransactions().Should().Contain(new List() { mp2 }); // after reverificaion mp2 should be back at verified list; mp1 should be completely kicked off } diff --git a/tests/Neo.UnitTests/Ledger/UT_TransactionVerificationContext.cs b/tests/Neo.UnitTests/Ledger/UT_TransactionVerificationContext.cs index 7805da64b1..57cf996acd 100644 --- a/tests/Neo.UnitTests/Ledger/UT_TransactionVerificationContext.cs +++ b/tests/Neo.UnitTests/Ledger/UT_TransactionVerificationContext.cs @@ -61,10 +61,10 @@ private Transaction CreateTransactionWithFee(long networkFee, long systemFee) public async Task TestDuplicateOracle() { // Fake balance - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); - ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings, gas: long.MaxValue); - BigInteger balance = NativeContract.GAS.BalanceOf(snapshot, UInt160.Zero); + ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings, gas: long.MaxValue); + BigInteger balance = NativeContract.GAS.BalanceOf(snapshotCache, UInt160.Zero); await NativeContract.GAS.Burn(engine, UInt160.Zero, balance); _ = NativeContract.GAS.Mint(engine, UInt160.Zero, 8, false); @@ -73,43 +73,43 @@ public async Task TestDuplicateOracle() var tx = CreateTransactionWithFee(1, 2); tx.Attributes = new TransactionAttribute[] { new OracleResponse() { Code = OracleResponseCode.ConsensusUnreachable, Id = 1, Result = Array.Empty() } }; var conflicts = new List(); - verificationContext.CheckTransaction(tx, conflicts, snapshot).Should().BeTrue(); + verificationContext.CheckTransaction(tx, conflicts, snapshotCache).Should().BeTrue(); verificationContext.AddTransaction(tx); tx = CreateTransactionWithFee(2, 1); tx.Attributes = new TransactionAttribute[] { new OracleResponse() { Code = OracleResponseCode.ConsensusUnreachable, Id = 1, Result = Array.Empty() } }; - verificationContext.CheckTransaction(tx, conflicts, snapshot).Should().BeFalse(); + verificationContext.CheckTransaction(tx, conflicts, snapshotCache).Should().BeFalse(); } [TestMethod] public async Task TestTransactionSenderFee() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); - ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings, gas: long.MaxValue); - BigInteger balance = NativeContract.GAS.BalanceOf(snapshot, UInt160.Zero); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); + ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings, gas: long.MaxValue); + BigInteger balance = NativeContract.GAS.BalanceOf(snapshotCache, UInt160.Zero); await NativeContract.GAS.Burn(engine, UInt160.Zero, balance); _ = NativeContract.GAS.Mint(engine, UInt160.Zero, 8, true); TransactionVerificationContext verificationContext = new(); var tx = CreateTransactionWithFee(1, 2); var conflicts = new List(); - verificationContext.CheckTransaction(tx, conflicts, snapshot).Should().BeTrue(); + verificationContext.CheckTransaction(tx, conflicts, snapshotCache).Should().BeTrue(); verificationContext.AddTransaction(tx); - verificationContext.CheckTransaction(tx, conflicts, snapshot).Should().BeTrue(); + verificationContext.CheckTransaction(tx, conflicts, snapshotCache).Should().BeTrue(); verificationContext.AddTransaction(tx); - verificationContext.CheckTransaction(tx, conflicts, snapshot).Should().BeFalse(); + verificationContext.CheckTransaction(tx, conflicts, snapshotCache).Should().BeFalse(); verificationContext.RemoveTransaction(tx); - verificationContext.CheckTransaction(tx, conflicts, snapshot).Should().BeTrue(); + verificationContext.CheckTransaction(tx, conflicts, snapshotCache).Should().BeTrue(); verificationContext.AddTransaction(tx); - verificationContext.CheckTransaction(tx, conflicts, snapshot).Should().BeFalse(); + verificationContext.CheckTransaction(tx, conflicts, snapshotCache).Should().BeFalse(); } [TestMethod] public async Task TestTransactionSenderFeeWithConflicts() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); - ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings, gas: long.MaxValue); - BigInteger balance = NativeContract.GAS.BalanceOf(snapshot, UInt160.Zero); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); + ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings, gas: long.MaxValue); + BigInteger balance = NativeContract.GAS.BalanceOf(snapshotCache, UInt160.Zero); await NativeContract.GAS.Burn(engine, UInt160.Zero, balance); _ = NativeContract.GAS.Mint(engine, UInt160.Zero, 3 + 3 + 1, true); // balance is enough for 2 transactions and 1 GAS is left. @@ -118,14 +118,14 @@ public async Task TestTransactionSenderFeeWithConflicts() var conflictingTx = CreateTransactionWithFee(1, 1); // costs 2 GAS var conflicts = new List(); - verificationContext.CheckTransaction(tx, conflicts, snapshot).Should().BeTrue(); + verificationContext.CheckTransaction(tx, conflicts, snapshotCache).Should().BeTrue(); verificationContext.AddTransaction(tx); - verificationContext.CheckTransaction(tx, conflicts, snapshot).Should().BeTrue(); + verificationContext.CheckTransaction(tx, conflicts, snapshotCache).Should().BeTrue(); verificationContext.AddTransaction(tx); - verificationContext.CheckTransaction(tx, conflicts, snapshot).Should().BeFalse(); + verificationContext.CheckTransaction(tx, conflicts, snapshotCache).Should().BeFalse(); conflicts.Add(conflictingTx); - verificationContext.CheckTransaction(tx, conflicts, snapshot).Should().BeTrue(); // 1 GAS is left on the balance + 2 GAS is free after conflicts removal => enough for one more trasnaction. + verificationContext.CheckTransaction(tx, conflicts, snapshotCache).Should().BeTrue(); // 1 GAS is left on the balance + 2 GAS is free after conflicts removal => enough for one more trasnaction. } } } diff --git a/tests/Neo.UnitTests/Ledger/UT_TrimmedBlock.cs b/tests/Neo.UnitTests/Ledger/UT_TrimmedBlock.cs index 12b56048c8..e65bfba843 100644 --- a/tests/Neo.UnitTests/Ledger/UT_TrimmedBlock.cs +++ b/tests/Neo.UnitTests/Ledger/UT_TrimmedBlock.cs @@ -48,7 +48,7 @@ public static TrimmedBlock GetTrimmedBlockWithNoTransaction() [TestMethod] public void TestGetBlock() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var tx1 = TestUtils.GetTransaction(UInt160.Zero); tx1.Script = new byte[] { 0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01, @@ -69,13 +69,13 @@ public void TestGetBlock() Transaction = tx2, BlockIndex = 1 }; - TestUtils.TransactionAdd(snapshot, state1, state2); + TestUtils.TransactionAdd(snapshotCache, state1, state2); TrimmedBlock tblock = GetTrimmedBlockWithNoTransaction(); tblock.Hashes = new UInt256[] { tx1.Hash, tx2.Hash }; - TestUtils.BlocksAdd(snapshot, tblock.Hash, tblock); + TestUtils.BlocksAdd(snapshotCache, tblock.Hash, tblock); - Block block = NativeContract.Ledger.GetBlock(snapshot, tblock.Hash); + Block block = NativeContract.Ledger.GetBlock(snapshotCache, tblock.Hash); block.Index.Should().Be(1); block.MerkleRoot.Should().Be(UInt256.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff02")); diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Block.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Block.cs index 4a7b0262f6..1c31e3483c 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Block.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Block.cs @@ -27,9 +27,9 @@ public class UT_Block private static ApplicationEngine GetEngine(bool hasContainer = false, bool hasSnapshot = false, bool hasBlock = false, bool addScript = true, long gas = 20_00000000) { var tx = hasContainer ? TestUtils.GetTransaction(UInt160.Zero) : null; - var snapshot = hasSnapshot ? TestBlockchain.GetTestSnapshotCache() : null; + var snapshotCache = hasSnapshot ? TestBlockchain.GetTestSnapshotCache() : null; var block = hasBlock ? new Block { Header = new Header() } : null; - var engine = ApplicationEngine.Create(TriggerType.Application, tx, snapshot, block, TestBlockchain.TheNeoSystem.Settings, gas: gas); + var engine = ApplicationEngine.Create(TriggerType.Application, tx, snapshotCache, block, TestBlockchain.TheNeoSystem.Settings, gas: gas); if (addScript) engine.LoadScript(new byte[] { 0x01 }); return engine; } @@ -155,7 +155,7 @@ public void Equals_SameObj() [TestMethod] public void TestGetHashCode() { - var snapshot = GetEngine(true, true).Snapshot; + var snapshot = GetEngine(true, true).SnapshotCache; NativeContract.Ledger.GetBlock(snapshot, 0).GetHashCode().Should().Be(-626492395); } diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Conflicts.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Conflicts.cs index b024fed808..a0dac53fbe 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Conflicts.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Conflicts.cs @@ -73,28 +73,28 @@ public void DeserializeAndSerialize() public void Verify() { var test = new Conflicts() { Hash = _u }; - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var key = Ledger.UT_MemoryPool.CreateStorageKey(NativeContract.Ledger.Id, Prefix_Transaction, _u.ToArray()); // Conflicting transaction is in the Conflicts attribute of some other on-chain transaction. var conflict = new TransactionState(); - snapshot.Add(key, new StorageItem(conflict)); - Assert.IsTrue(test.Verify(snapshot, new Transaction())); + snapshotCache.Add(key, new StorageItem(conflict)); + Assert.IsTrue(test.Verify(snapshotCache, new Transaction())); // Conflicting transaction is on-chain. - snapshot.Delete(key); + snapshotCache.Delete(key); conflict = new TransactionState { BlockIndex = 123, Transaction = new Transaction(), State = VMState.NONE }; - snapshot.Add(key, new StorageItem(conflict)); - Assert.IsFalse(test.Verify(snapshot, new Transaction())); + snapshotCache.Add(key, new StorageItem(conflict)); + Assert.IsFalse(test.Verify(snapshotCache, new Transaction())); // There's no conflicting transaction at all. - snapshot.Delete(key); - Assert.IsTrue(test.Verify(snapshot, new Transaction())); + snapshotCache.Delete(key); + Assert.IsTrue(test.Verify(snapshotCache, new Transaction())); } } } diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Header.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Header.cs index 0b32ffd656..0291b6f7c6 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Header.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Header.cs @@ -52,11 +52,11 @@ public void GetHashCodeTest() public void TrimTest() { UInt256 val256 = UInt256.Zero; - var snapshot = TestBlockchain.GetTestSnapshotCache().CreateSnapshot(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache().CreateSnapshot(); TestUtils.SetupHeaderWithValues(null, uut, val256, out _, out _, out _, out _, out _, out _); uut.Witness = new Witness() { InvocationScript = Array.Empty(), VerificationScript = Array.Empty() }; - TestUtils.BlocksAdd(snapshot, uut.Hash, new TrimmedBlock() + TestUtils.BlocksAdd(snapshotCache, uut.Hash, new TrimmedBlock() { Header = new Header { @@ -69,7 +69,7 @@ public void TrimTest() Hashes = Array.Empty() }); - var trim = NativeContract.Ledger.GetTrimmedBlock(snapshot, uut.Hash); + var trim = NativeContract.Ledger.GetTrimmedBlock(snapshotCache, uut.Hash); var header = trim.Header; header.Version.Should().Be(uut.Version); diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_HighPriorityAttribute.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_HighPriorityAttribute.cs index e5222e33de..09454d298f 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_HighPriorityAttribute.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_HighPriorityAttribute.cs @@ -74,11 +74,11 @@ public void DeserializeAndSerialize() public void Verify() { var test = new HighPriorityAttribute(); - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); - Assert.IsFalse(test.Verify(snapshot, new Transaction() { Signers = Array.Empty() })); - Assert.IsFalse(test.Verify(snapshot, new Transaction() { Signers = new Signer[] { new Signer() { Account = UInt160.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff01") } } })); - Assert.IsTrue(test.Verify(snapshot, new Transaction() { Signers = new Signer[] { new Signer() { Account = NativeContract.NEO.GetCommitteeAddress(snapshot) } } })); + Assert.IsFalse(test.Verify(snapshotCache, new Transaction() { Signers = Array.Empty() })); + Assert.IsFalse(test.Verify(snapshotCache, new Transaction() { Signers = new Signer[] { new Signer() { Account = UInt160.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff01") } } })); + Assert.IsTrue(test.Verify(snapshotCache, new Transaction() { Signers = new Signer[] { new Signer() { Account = NativeContract.NEO.GetCommitteeAddress(snapshotCache) } } })); } } } diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NotValidBefore.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NotValidBefore.cs index e44d4f3636..bff21a4e5e 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NotValidBefore.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NotValidBefore.cs @@ -77,12 +77,12 @@ public void DeserializeAndSerialize() public void Verify() { var test = new NotValidBefore(); - var snapshot = TestBlockchain.GetTestSnapshotCache(); - test.Height = NativeContract.Ledger.CurrentIndex(snapshot) + 1; + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); + test.Height = NativeContract.Ledger.CurrentIndex(snapshotCache) + 1; - Assert.IsFalse(test.Verify(snapshot, new Transaction())); + Assert.IsFalse(test.Verify(snapshotCache, new Transaction())); test.Height--; - Assert.IsTrue(test.Verify(snapshot, new Transaction())); + Assert.IsTrue(test.Verify(snapshotCache, new Transaction())); } } } diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs index 1739f1b830..a483ecf0d6 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs @@ -11,7 +11,6 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; -using Neo.Cryptography.ECC; using Neo.IO; using Neo.Json; using Neo.Ledger; @@ -122,7 +121,7 @@ public void FeeIsMultiSigContract() { var walletA = TestUtils.GenerateTestWallet("123"); var walletB = TestUtils.GenerateTestWallet("123"); - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var a = walletA.CreateAccount(); var b = walletB.CreateAccount(); @@ -139,15 +138,15 @@ public void FeeIsMultiSigContract() // Fake balance var key = NativeContract.GAS.CreateStorageKey(20, acc.ScriptHash); - var entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); + var entry = snapshotCache.GetAndChange(key, () => new StorageItem(new AccountState())); entry.GetInteroperable().Balance = 10000 * NativeContract.GAS.Factor; - snapshot.Commit(); + snapshotCache.Commit(); // Make transaction - var tx = walletA.MakeTransaction(snapshot, [ + var tx = walletA.MakeTransaction(snapshotCache, [ new TransferOutput { AssetId = NativeContract.GAS.Hash, @@ -160,10 +159,10 @@ public void FeeIsMultiSigContract() // Sign - var wrongData = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network + 1); + var wrongData = new ContractParametersContext(snapshotCache, tx, TestProtocolSettings.Default.Network + 1); Assert.IsFalse(walletA.Sign(wrongData)); - var data = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network); + var data = new ContractParametersContext(snapshotCache, tx, TestProtocolSettings.Default.Network); Assert.IsTrue(walletA.Sign(data)); Assert.IsTrue(walletB.Sign(data)); Assert.IsTrue(data.Completed); @@ -172,14 +171,14 @@ public void FeeIsMultiSigContract() // Fast check - Assert.IsTrue(tx.VerifyWitnesses(TestProtocolSettings.Default, snapshot, tx.NetworkFee)); + Assert.IsTrue(tx.VerifyWitnesses(TestProtocolSettings.Default, snapshotCache, tx.NetworkFee)); // Check long verificationGas = 0; foreach (var witness in tx.Witnesses) { - using ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, settings: TestBlockchain.TheNeoSystem.Settings, gas: tx.NetworkFee); + using ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings, gas: tx.NetworkFee); engine.LoadScript(witness.VerificationScript); engine.LoadScript(witness.InvocationScript); Assert.AreEqual(VMState.HALT, engine.Execute()); @@ -188,7 +187,7 @@ public void FeeIsMultiSigContract() verificationGas += engine.FeeConsumed; } - var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); + var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshotCache); Assert.AreEqual(1967100, verificationGas); Assert.AreEqual(348000, sizeGas); Assert.AreEqual(2315100, tx.NetworkFee); @@ -198,23 +197,23 @@ public void FeeIsMultiSigContract() public void FeeIsSignatureContractDetailed() { var wallet = TestUtils.GenerateTestWallet("123"); - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var acc = wallet.CreateAccount(); // Fake balance var key = NativeContract.GAS.CreateStorageKey(20, acc.ScriptHash); - var entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); + var entry = snapshotCache.GetAndChange(key, () => new StorageItem(new AccountState())); entry.GetInteroperable().Balance = 10000 * NativeContract.GAS.Factor; - snapshot.Commit(); + snapshotCache.Commit(); // Make transaction // self-transfer of 1e-8 GAS - var tx = wallet.MakeTransaction(snapshot, [ + var tx = wallet.MakeTransaction(snapshotCache, [ new TransferOutput { AssetId = NativeContract.GAS.Hash, @@ -233,7 +232,7 @@ public void FeeIsSignatureContractDetailed() // Sign // ---- - var data = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network); + var data = new ContractParametersContext(snapshotCache, tx, TestProtocolSettings.Default.Network); // 'from' is always required as witness // if not included on cosigner with a scope, its scope should be considered 'CalledByEntry' data.ScriptHashes.Count.Should().Be(1); @@ -247,14 +246,14 @@ public void FeeIsSignatureContractDetailed() // Fast check - Assert.IsTrue(tx.VerifyWitnesses(TestProtocolSettings.Default, snapshot, tx.NetworkFee)); + Assert.IsTrue(tx.VerifyWitnesses(TestProtocolSettings.Default, snapshotCache, tx.NetworkFee)); // Check long verificationGas = 0; foreach (var witness in tx.Witnesses) { - using var engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, settings: TestBlockchain.TheNeoSystem.Settings, gas: tx.NetworkFee); + using var engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings, gas: tx.NetworkFee); engine.LoadScript(witness.VerificationScript); engine.LoadScript(witness.InvocationScript); Assert.AreEqual(VMState.HALT, engine.Execute()); @@ -285,8 +284,8 @@ public void FeeIsSignatureContractDetailed() // I + II + III + IV Assert.AreEqual(25 + 22 + 1 + 88 + 109, tx.Size); - Assert.AreEqual(1000, NativeContract.Policy.GetFeePerByte(snapshot)); - var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); + Assert.AreEqual(1000, NativeContract.Policy.GetFeePerByte(snapshotCache)); + var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshotCache); // final check: verification_cost and tx_size Assert.AreEqual(245000, sizeGas); @@ -300,18 +299,18 @@ public void FeeIsSignatureContractDetailed() public void FeeIsSignatureContract_TestScope_Global() { var wallet = TestUtils.GenerateTestWallet(""); - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var acc = wallet.CreateAccount(); // Fake balance var key = NativeContract.GAS.CreateStorageKey(20, acc.ScriptHash); - var entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); + var entry = snapshotCache.GetAndChange(key, () => new StorageItem(new AccountState())); entry.GetInteroperable().Balance = 10000 * NativeContract.GAS.Factor; - snapshot.Commit(); + snapshotCache.Commit(); // Make transaction // Manually creating script @@ -335,7 +334,7 @@ public void FeeIsSignatureContract_TestScope_Global() // using this... - var tx = wallet.MakeTransaction(snapshot, script, acc.ScriptHash, signers); + var tx = wallet.MakeTransaction(snapshotCache, script, acc.ScriptHash, signers); Assert.IsNotNull(tx); Assert.IsNull(tx.Witnesses); @@ -344,7 +343,7 @@ public void FeeIsSignatureContract_TestScope_Global() // Sign // ---- - var data = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network); + var data = new ContractParametersContext(snapshotCache, tx, TestProtocolSettings.Default.Network); bool signed = wallet.Sign(data); Assert.IsTrue(signed); @@ -353,13 +352,13 @@ public void FeeIsSignatureContract_TestScope_Global() tx.Witnesses.Length.Should().Be(1); // Fast check - Assert.IsTrue(tx.VerifyWitnesses(TestProtocolSettings.Default, snapshot, tx.NetworkFee)); + Assert.IsTrue(tx.VerifyWitnesses(TestProtocolSettings.Default, snapshotCache, tx.NetworkFee)); // Check long verificationGas = 0; foreach (var witness in tx.Witnesses) { - using ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, settings: TestBlockchain.TheNeoSystem.Settings, gas: tx.NetworkFee); + using ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings, gas: tx.NetworkFee); engine.LoadScript(witness.VerificationScript); engine.LoadScript(witness.InvocationScript); Assert.AreEqual(VMState.HALT, engine.Execute()); @@ -368,7 +367,7 @@ public void FeeIsSignatureContract_TestScope_Global() verificationGas += engine.FeeConsumed; } // get sizeGas - var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); + var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshotCache); // final check on sum: verification_cost + tx_size Assert.AreEqual(1228520, verificationGas + sizeGas); // final assert @@ -379,18 +378,18 @@ public void FeeIsSignatureContract_TestScope_Global() public void FeeIsSignatureContract_TestScope_CurrentHash_GAS() { var wallet = TestUtils.GenerateTestWallet(""); - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var acc = wallet.CreateAccount(); // Fake balance var key = NativeContract.GAS.CreateStorageKey(20, acc.ScriptHash); - var entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); + var entry = snapshotCache.GetAndChange(key, () => new StorageItem(new AccountState())); entry.GetInteroperable().Balance = 10000 * NativeContract.GAS.Factor; - snapshot.Commit(); + snapshotCache.Commit(); // Make transaction // Manually creating script @@ -415,7 +414,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_GAS() // using this... - var tx = wallet.MakeTransaction(snapshot, script, acc.ScriptHash, signers); + var tx = wallet.MakeTransaction(snapshotCache, script, acc.ScriptHash, signers); Assert.IsNotNull(tx); Assert.IsNull(tx.Witnesses); @@ -424,7 +423,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_GAS() // Sign // ---- - var data = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network); + var data = new ContractParametersContext(snapshotCache, tx, TestProtocolSettings.Default.Network); bool signed = wallet.Sign(data); Assert.IsTrue(signed); @@ -433,13 +432,13 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_GAS() tx.Witnesses.Length.Should().Be(1); // Fast check - Assert.IsTrue(tx.VerifyWitnesses(TestProtocolSettings.Default, snapshot, tx.NetworkFee)); + Assert.IsTrue(tx.VerifyWitnesses(TestProtocolSettings.Default, snapshotCache, tx.NetworkFee)); // Check long verificationGas = 0; foreach (var witness in tx.Witnesses) { - using ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, settings: TestBlockchain.TheNeoSystem.Settings, gas: tx.NetworkFee); + using ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings, gas: tx.NetworkFee); engine.LoadScript(witness.VerificationScript); engine.LoadScript(witness.InvocationScript); Assert.AreEqual(VMState.HALT, engine.Execute()); @@ -448,7 +447,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_GAS() verificationGas += engine.FeeConsumed; } // get sizeGas - var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); + var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshotCache); // final check on sum: verification_cost + tx_size Assert.AreEqual(1249520, verificationGas + sizeGas); // final assert @@ -459,18 +458,18 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_GAS() public void FeeIsSignatureContract_TestScope_CalledByEntry_Plus_GAS() { var wallet = TestUtils.GenerateTestWallet(""); - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var acc = wallet.CreateAccount(); // Fake balance var key = NativeContract.GAS.CreateStorageKey(20, acc.ScriptHash); - var entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); + var entry = snapshotCache.GetAndChange(key, () => new StorageItem(new AccountState())); entry.GetInteroperable().Balance = 10000 * NativeContract.GAS.Factor; - snapshot.Commit(); + snapshotCache.Commit(); // Make transaction // Manually creating script @@ -498,7 +497,7 @@ public void FeeIsSignatureContract_TestScope_CalledByEntry_Plus_GAS() // using this... - var tx = wallet.MakeTransaction(snapshot, script, acc.ScriptHash, signers); + var tx = wallet.MakeTransaction(snapshotCache, script, acc.ScriptHash, signers); Assert.IsNotNull(tx); Assert.IsNull(tx.Witnesses); @@ -507,7 +506,7 @@ public void FeeIsSignatureContract_TestScope_CalledByEntry_Plus_GAS() // Sign // ---- - var data = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network); + var data = new ContractParametersContext(snapshotCache, tx, TestProtocolSettings.Default.Network); bool signed = wallet.Sign(data); Assert.IsTrue(signed); @@ -516,13 +515,13 @@ public void FeeIsSignatureContract_TestScope_CalledByEntry_Plus_GAS() tx.Witnesses.Length.Should().Be(1); // Fast check - Assert.IsTrue(tx.VerifyWitnesses(TestProtocolSettings.Default, snapshot, tx.NetworkFee)); + Assert.IsTrue(tx.VerifyWitnesses(TestProtocolSettings.Default, snapshotCache, tx.NetworkFee)); // Check long verificationGas = 0; foreach (var witness in tx.Witnesses) { - using ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, settings: TestBlockchain.TheNeoSystem.Settings, gas: tx.NetworkFee); + using ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings, gas: tx.NetworkFee); engine.LoadScript(witness.VerificationScript); engine.LoadScript(witness.InvocationScript); Assert.AreEqual(VMState.HALT, engine.Execute()); @@ -531,7 +530,7 @@ public void FeeIsSignatureContract_TestScope_CalledByEntry_Plus_GAS() verificationGas += engine.FeeConsumed; } // get sizeGas - var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); + var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshotCache); // final check on sum: verification_cost + tx_size Assert.AreEqual(1249520, verificationGas + sizeGas); // final assert @@ -542,14 +541,14 @@ public void FeeIsSignatureContract_TestScope_CalledByEntry_Plus_GAS() public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_FAULT() { var wallet = TestUtils.GenerateTestWallet(""); - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var acc = wallet.CreateAccount(); // Fake balance var key = NativeContract.GAS.CreateStorageKey(20, acc.ScriptHash); - var entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); + var entry = snapshotCache.GetAndChange(key, () => new StorageItem(new AccountState())); entry.GetInteroperable().Balance = 10000 * NativeContract.GAS.Factor; @@ -579,7 +578,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_FAULT() // expects FAULT on execution of 'transfer' Application script // due to lack of a valid witness validation Transaction tx = null; - Assert.ThrowsException(() => tx = wallet.MakeTransaction(snapshot, script, acc.ScriptHash, signers)); + Assert.ThrowsException(() => tx = wallet.MakeTransaction(snapshotCache, script, acc.ScriptHash, signers)); Assert.IsNull(tx); } @@ -587,18 +586,18 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_FAULT() public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_GAS() { var wallet = TestUtils.GenerateTestWallet(""); - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var acc = wallet.CreateAccount(); // Fake balance var key = NativeContract.GAS.CreateStorageKey(20, acc.ScriptHash); - var entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); + var entry = snapshotCache.GetAndChange(key, () => new StorageItem(new AccountState())); entry.GetInteroperable().Balance = 10000 * NativeContract.GAS.Factor; - snapshot.Commit(); + snapshotCache.Commit(); // Make transaction // Manually creating script @@ -623,7 +622,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_GAS() // using this... - var tx = wallet.MakeTransaction(snapshot, script, acc.ScriptHash, signers); + var tx = wallet.MakeTransaction(snapshotCache, script, acc.ScriptHash, signers); Assert.IsNotNull(tx); Assert.IsNull(tx.Witnesses); @@ -632,7 +631,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_GAS() // Sign // ---- - var data = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network); + var data = new ContractParametersContext(snapshotCache, tx, TestProtocolSettings.Default.Network); bool signed = wallet.Sign(data); Assert.IsTrue(signed); @@ -646,13 +645,13 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_GAS() tx.Signers.Length.Should().Be(1); // Fast check - Assert.IsTrue(tx.VerifyWitnesses(TestProtocolSettings.Default, snapshot, tx.NetworkFee)); + Assert.IsTrue(tx.VerifyWitnesses(TestProtocolSettings.Default, snapshotCache, tx.NetworkFee)); // Check long verificationGas = 0; foreach (var witness in tx.Witnesses) { - using ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, settings: TestBlockchain.TheNeoSystem.Settings, gas: tx.NetworkFee); + using ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings, gas: tx.NetworkFee); engine.LoadScript(witness.VerificationScript); engine.LoadScript(witness.InvocationScript); Assert.AreEqual(VMState.HALT, engine.Execute()); @@ -661,7 +660,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_GAS() verificationGas += engine.FeeConsumed; } // get sizeGas - var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); + var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshotCache); // final check on sum: verification_cost + tx_size Assert.AreEqual(1269520, verificationGas + sizeGas); // final assert @@ -672,14 +671,14 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_GAS() public void FeeIsSignatureContract_TestScope_NoScopeFAULT() { var wallet = TestUtils.GenerateTestWallet(""); - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var acc = wallet.CreateAccount(); // Fake balance var key = NativeContract.GAS.CreateStorageKey(20, acc.ScriptHash); - var entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); + var entry = snapshotCache.GetAndChange(key, () => new StorageItem(new AccountState())); entry.GetInteroperable().Balance = 10000 * NativeContract.GAS.Factor; @@ -710,7 +709,7 @@ public void FeeIsSignatureContract_TestScope_NoScopeFAULT() // expects FAULT on execution of 'transfer' Application script // due to lack of a valid witness validation Transaction tx = null; - Assert.ThrowsException(() => tx = wallet.MakeTransaction(snapshot, script, acc.ScriptHash, signers, attributes)); + Assert.ThrowsException(() => tx = wallet.MakeTransaction(snapshotCache, script, acc.ScriptHash, signers, attributes)); Assert.IsNull(tx); } @@ -718,18 +717,18 @@ public void FeeIsSignatureContract_TestScope_NoScopeFAULT() public void FeeIsSignatureContract_UnexistingVerificationContractFAULT() { var wallet = TestUtils.GenerateTestWallet(""); - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var acc = wallet.CreateAccount(); // Fake balance var key = NativeContract.GAS.CreateStorageKey(20, acc.ScriptHash); - var entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); + var entry = snapshotCache.GetAndChange(key, () => new StorageItem(new AccountState())); entry.GetInteroperable().Balance = 10000 * NativeContract.GAS.Factor; - snapshot.Commit(); + snapshotCache.Commit(); // Make transaction // Manually creating script @@ -760,14 +759,14 @@ public void FeeIsSignatureContract_UnexistingVerificationContractFAULT() // expects ArgumentException on execution of 'CalculateNetworkFee' due to // null witness_script (no account in the wallet, no corresponding witness // and no verification contract for the signer) - Assert.ThrowsException(() => walletWithoutAcc.MakeTransaction(snapshot, script, acc.ScriptHash, signers)); + Assert.ThrowsException(() => walletWithoutAcc.MakeTransaction(snapshotCache, script, acc.ScriptHash, signers)); Assert.IsNull(tx); } [TestMethod] public void Transaction_Reverify_Hashes_Length_Unequal_To_Witnesses_Length() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); Transaction txSimple = new() { Version = 0x00, @@ -786,9 +785,9 @@ public void Transaction_Reverify_Hashes_Length_Unequal_To_Witnesses_Length() Script = new byte[] { (byte)OpCode.PUSH1 }, Witnesses = Array.Empty() }; - UInt160[] hashes = txSimple.GetScriptHashesForVerifying(snapshot); + UInt160[] hashes = txSimple.GetScriptHashesForVerifying(snapshotCache); Assert.AreEqual(1, hashes.Length); - Assert.AreNotEqual(VerifyResult.Succeed, txSimple.VerifyStateDependent(TestProtocolSettings.Default, snapshot, new TransactionVerificationContext(), new List())); + Assert.AreNotEqual(VerifyResult.Succeed, txSimple.VerifyStateDependent(TestProtocolSettings.Default, snapshotCache, new TransactionVerificationContext(), new List())); } [TestMethod] @@ -982,18 +981,18 @@ public void FeeIsSignatureContract_TestScope_FeeOnly_Default() cosigner.Scopes.Should().Be(WitnessScope.None); var wallet = TestUtils.GenerateTestWallet(""); - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var acc = wallet.CreateAccount(); // Fake balance var key = NativeContract.GAS.CreateStorageKey(20, acc.ScriptHash); - var entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); + var entry = snapshotCache.GetAndChange(key, () => new StorageItem(new AccountState())); entry.GetInteroperable().Balance = 10000 * NativeContract.GAS.Factor; - snapshot.Commit(); + snapshotCache.Commit(); // Make transaction // Manually creating script @@ -1015,12 +1014,12 @@ public void FeeIsSignatureContract_TestScope_FeeOnly_Default() Scopes = WitnessScope.None } }; - Assert.ThrowsException(() => wallet.MakeTransaction(snapshot, script, acc.ScriptHash, signers)); + Assert.ThrowsException(() => wallet.MakeTransaction(snapshotCache, script, acc.ScriptHash, signers)); // change to global scope signers[0].Scopes = WitnessScope.Global; - var tx = wallet.MakeTransaction(snapshot, script, acc.ScriptHash, signers); + var tx = wallet.MakeTransaction(snapshotCache, script, acc.ScriptHash, signers); Assert.IsNotNull(tx); Assert.IsNull(tx.Witnesses); @@ -1029,7 +1028,7 @@ public void FeeIsSignatureContract_TestScope_FeeOnly_Default() // Sign // ---- - var data = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network); + var data = new ContractParametersContext(snapshotCache, tx, TestProtocolSettings.Default.Network); bool signed = wallet.Sign(data); Assert.IsTrue(signed); @@ -1038,13 +1037,13 @@ public void FeeIsSignatureContract_TestScope_FeeOnly_Default() tx.Witnesses.Length.Should().Be(1); // Fast check - Assert.IsTrue(tx.VerifyWitnesses(TestProtocolSettings.Default, snapshot, tx.NetworkFee)); + Assert.IsTrue(tx.VerifyWitnesses(TestProtocolSettings.Default, snapshotCache, tx.NetworkFee)); // Check long verificationGas = 0; foreach (var witness in tx.Witnesses) { - using ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, settings: TestBlockchain.TheNeoSystem.Settings, gas: tx.NetworkFee); + using ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings, gas: tx.NetworkFee); engine.LoadScript(witness.VerificationScript); engine.LoadScript(witness.InvocationScript); Assert.AreEqual(VMState.HALT, engine.Execute()); @@ -1053,7 +1052,7 @@ public void FeeIsSignatureContract_TestScope_FeeOnly_Default() verificationGas += engine.FeeConsumed; } // get sizeGas - var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); + var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshotCache); // final check on sum: verification_cost + tx_size Assert.AreEqual(1228520, verificationGas + sizeGas); // final assert @@ -1140,7 +1139,7 @@ public void Test_VerifyStateIndependent() var walletA = TestUtils.GenerateTestWallet("123"); var walletB = TestUtils.GenerateTestWallet("123"); - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var a = walletA.CreateAccount(); var b = walletB.CreateAccount(); @@ -1157,15 +1156,15 @@ public void Test_VerifyStateIndependent() // Fake balance var key = NativeContract.GAS.CreateStorageKey(20, acc.ScriptHash); - var entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); + var entry = snapshotCache.GetAndChange(key, () => new StorageItem(new AccountState())); entry.GetInteroperable().Balance = 10000 * NativeContract.GAS.Factor; - snapshot.Commit(); + snapshotCache.Commit(); // Make transaction - tx = walletA.MakeTransaction(snapshot, [ + tx = walletA.MakeTransaction(snapshotCache, [ new TransferOutput { AssetId = NativeContract.GAS.Hash, @@ -1176,7 +1175,7 @@ public void Test_VerifyStateIndependent() // Sign - var data = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network); + var data = new ContractParametersContext(snapshotCache, tx, TestProtocolSettings.Default.Network); Assert.IsTrue(walletA.Sign(data)); Assert.IsTrue(walletB.Sign(data)); Assert.IsTrue(data.Completed); diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs index 6c4f066008..cf765365c9 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs @@ -43,7 +43,7 @@ private static Witness PrepareDummyWitness(int pubKeys, int m) { var address = new WalletAccount[pubKeys]; var wallets = new NEP6Wallet[pubKeys]; - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); for (int x = 0; x < pubKeys; x++) { @@ -62,7 +62,7 @@ private static Witness PrepareDummyWitness(int pubKeys, int m) // Sign - var data = new ContractParametersContext(snapshot, new Transaction() + var data = new ContractParametersContext(snapshotCache, new Transaction() { Attributes = Array.Empty(), Signers = new[] {new Signer() diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_CryptoLib.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_CryptoLib.cs index 00ababb416..cdca35a69e 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_CryptoLib.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_CryptoLib.cs @@ -45,11 +45,11 @@ public class UT_CryptoLib [TestMethod] public void TestG1() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); using ScriptBuilder script = new(); script.EmitDynamicCall(NativeContract.CryptoLib.Hash, "bls12381Deserialize", g1); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(VMState.HALT, engine.Execute()); var result = engine.ResultStack.Pop(); @@ -59,11 +59,11 @@ public void TestG1() [TestMethod] public void TestG2() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); using ScriptBuilder script = new(); script.EmitDynamicCall(NativeContract.CryptoLib.Hash, "bls12381Deserialize", g2); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(VMState.HALT, engine.Execute()); var result = engine.ResultStack.Pop(); @@ -73,11 +73,11 @@ public void TestG2() [TestMethod] public void TestNotG1() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); using ScriptBuilder script = new(); script.EmitDynamicCall(NativeContract.CryptoLib.Hash, "bls12381Deserialize", not_g1); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(VMState.FAULT, engine.Execute()); } @@ -85,18 +85,18 @@ public void TestNotG1() [TestMethod] public void TestNotG2() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); using ScriptBuilder script = new(); script.EmitDynamicCall(NativeContract.CryptoLib.Hash, "bls12381Deserialize", not_g2); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(VMState.FAULT, engine.Execute()); } [TestMethod] public void TestBls12381Add() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); using ScriptBuilder script = new(); script.EmitDynamicCall(NativeContract.CryptoLib.Hash, "bls12381Deserialize", gt); script.EmitDynamicCall(NativeContract.CryptoLib.Hash, "bls12381Deserialize", gt); @@ -107,7 +107,7 @@ public void TestBls12381Add() script.EmitPush(NativeContract.CryptoLib.Hash); script.EmitSysCall(ApplicationEngine.System_Contract_Call); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(VMState.HALT, engine.Execute()); var result = engine.ResultStack.Pop(); @@ -119,7 +119,7 @@ public void TestBls12381Mul() { var data = new byte[32]; data[0] = 0x03; - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); using (ScriptBuilder script = new()) { script.EmitPush(false); @@ -132,7 +132,7 @@ public void TestBls12381Mul() script.EmitPush(NativeContract.CryptoLib.Hash); script.EmitSysCall(ApplicationEngine.System_Contract_Call); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(VMState.HALT, engine.Execute()); var result = engine.ResultStack.Pop(); @@ -150,7 +150,7 @@ public void TestBls12381Mul() script.EmitPush(NativeContract.CryptoLib.Hash); script.EmitSysCall(ApplicationEngine.System_Contract_Call); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(VMState.HALT, engine.Execute()); var result = engine.ResultStack.Pop(); @@ -161,7 +161,7 @@ public void TestBls12381Mul() [TestMethod] public void TestBls12381Pairing() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); using ScriptBuilder script = new(); script.EmitDynamicCall(NativeContract.CryptoLib.Hash, "bls12381Deserialize", g2); script.EmitDynamicCall(NativeContract.CryptoLib.Hash, "bls12381Deserialize", g1); @@ -172,7 +172,7 @@ public void TestBls12381Pairing() script.EmitPush(NativeContract.CryptoLib.Hash); script.EmitSysCall(ApplicationEngine.System_Contract_Call); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(VMState.HALT, engine.Execute()); var result = engine.ResultStack.Pop(); @@ -182,7 +182,7 @@ public void TestBls12381Pairing() [TestMethod] public void Bls12381Equal() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); using ScriptBuilder script = new(); script.EmitDynamicCall(NativeContract.CryptoLib.Hash, "bls12381Deserialize", g1); script.EmitDynamicCall(NativeContract.CryptoLib.Hash, "bls12381Deserialize", g1); @@ -193,7 +193,7 @@ public void Bls12381Equal() script.EmitPush(NativeContract.CryptoLib.Hash); script.EmitSysCall(ApplicationEngine.System_Contract_Call); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(VMState.HALT, engine.Execute()); var result = engine.ResultStack.Pop(); @@ -211,7 +211,7 @@ private void CheckBls12381ScalarMul_Compat(string point, string mul, bool negati { var data = new byte[32]; data[0] = 0x03; - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); using (ScriptBuilder script = new()) { script.EmitPush(negative); @@ -224,7 +224,7 @@ private void CheckBls12381ScalarMul_Compat(string point, string mul, bool negati script.EmitPush(NativeContract.CryptoLib.Hash); script.EmitSysCall(ApplicationEngine.System_Contract_Call); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(VMState.HALT, engine.Execute()); var result = engine.ResultStack.Pop(); @@ -506,16 +506,16 @@ public void TestVerifyWithECDsa_CustomTxWitness_SingleSig() tx.VerifyStateIndependent(TestProtocolSettings.Default).Should().Be(VerifyResult.Succeed); - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); // Create fake balance to pay the fees. - ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings, gas: long.MaxValue); + ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings, gas: long.MaxValue); _ = NativeContract.GAS.Mint(engine, acc, 5_0000_0000, false); - snapshot.Commit(); + snapshotCache.Commit(); var txVrfContext = new TransactionVerificationContext(); var conflicts = new List(); - tx.VerifyStateDependent(TestProtocolSettings.Default, snapshot, txVrfContext, conflicts).Should().Be(VerifyResult.Succeed); + tx.VerifyStateDependent(TestProtocolSettings.Default, snapshotCache, txVrfContext, conflicts).Should().Be(VerifyResult.Succeed); // The resulting witness verification cost is 2154270 * 10e-8GAS. // The resulting witness Invocation script (66 bytes length): @@ -747,10 +747,10 @@ public void TestVerifyWithECDsa_CustomTxWitness_MultiSig() tx.VerifyStateIndependent(TestProtocolSettings.Default).Should().Be(VerifyResult.Succeed); - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); // Create fake balance to pay the fees. - var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings, gas: long.MaxValue); + var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings, gas: long.MaxValue); _ = NativeContract.GAS.Mint(engine, acc, 5_0000_0000, false); // We should not use commit here cause once its committed, the value we get from the snapshot can be different @@ -761,7 +761,7 @@ public void TestVerifyWithECDsa_CustomTxWitness_MultiSig() // Check that witness verification passes. var txVrfContext = new TransactionVerificationContext(); var conflicts = new List(); - tx.VerifyStateDependent(TestProtocolSettings.Default, snapshot, txVrfContext, conflicts).Should().Be(VerifyResult.Succeed); + tx.VerifyStateDependent(TestProtocolSettings.Default, snapshotCache, txVrfContext, conflicts).Should().Be(VerifyResult.Succeed); // The resulting witness verification cost for 3/4 multisig is 8389470 * 10e-8GAS. Cost depends on M/N. // The resulting witness Invocation script (198 bytes for 3 signatures): diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_FungibleToken.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_FungibleToken.cs index 6e3c18999a..7e7e27084c 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_FungibleToken.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_FungibleToken.cs @@ -22,8 +22,8 @@ public class UT_FungibleToken : TestKit [TestMethod] public void TestTotalSupply() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); - NativeContract.GAS.TotalSupply(snapshot).Should().Be(5200000050000000); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); + NativeContract.GAS.TotalSupply(snapshotCache).Should().Be(5200000050000000); } } } diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_GasToken.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_GasToken.cs index ebb66f0dff..a7d087fa86 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_GasToken.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_GasToken.cs @@ -27,13 +27,13 @@ namespace Neo.UnitTests.SmartContract.Native [TestClass] public class UT_GasToken { - private DataCache _snapshot; + private DataCache _snapshotCache; private Block _persistingBlock; [TestInitialize] public void TestSetup() { - _snapshot = TestBlockchain.GetTestSnapshotCache(); + _snapshotCache = TestBlockchain.GetTestSnapshotCache(); _persistingBlock = new Block { Header = new Header() }; } @@ -41,15 +41,15 @@ public void TestSetup() public void Check_Name() => NativeContract.GAS.Name.Should().Be(nameof(GasToken)); [TestMethod] - public void Check_Symbol() => NativeContract.GAS.Symbol(_snapshot).Should().Be("GAS"); + public void Check_Symbol() => NativeContract.GAS.Symbol(_snapshotCache).Should().Be("GAS"); [TestMethod] - public void Check_Decimals() => NativeContract.GAS.Decimals(_snapshot).Should().Be(8); + public void Check_Decimals() => NativeContract.GAS.Decimals(_snapshotCache).Should().Be(8); [TestMethod] public async Task Check_BalanceOfTransferAndBurn() { - var snapshot = _snapshot.CloneCache(); + var snapshot = _snapshotCache.CloneCache(); var persistingBlock = new Block { Header = new Header { Index = 1000 } }; byte[] from = Contract.GetBFTAddress(TestProtocolSettings.Default.StandbyValidators).ToArray(); byte[] to = new byte[20]; @@ -119,20 +119,20 @@ await Assert.ThrowsExceptionAsync(async () => await NativeContract.GAS.Burn(engine, new UInt160(to), new BigInteger(1)); - NativeContract.GAS.BalanceOf(engine.Snapshot, to).Should().Be(5200049999999999); + NativeContract.GAS.BalanceOf(engine.SnapshotCache, to).Should().Be(5200049999999999); - engine.Snapshot.GetChangeSet().Count().Should().Be(2); + engine.SnapshotCache.GetChangeSet().Count().Should().Be(2); // Burn all await NativeContract.GAS.Burn(engine, new UInt160(to), new BigInteger(5200049999999999)); - (keyCount - 2).Should().Be(engine.Snapshot.GetChangeSet().Count()); + (keyCount - 2).Should().Be(engine.SnapshotCache.GetChangeSet().Count()); // Bad inputs - Assert.ThrowsException(() => NativeContract.GAS.Transfer(engine.Snapshot, from, to, BigInteger.MinusOne, true, persistingBlock)); - Assert.ThrowsException(() => NativeContract.GAS.Transfer(engine.Snapshot, new byte[19], to, BigInteger.One, false, persistingBlock)); - Assert.ThrowsException(() => NativeContract.GAS.Transfer(engine.Snapshot, from, new byte[19], BigInteger.One, false, persistingBlock)); + Assert.ThrowsException(() => NativeContract.GAS.Transfer(engine.SnapshotCache, from, to, BigInteger.MinusOne, true, persistingBlock)); + Assert.ThrowsException(() => NativeContract.GAS.Transfer(engine.SnapshotCache, new byte[19], to, BigInteger.One, false, persistingBlock)); + Assert.ThrowsException(() => NativeContract.GAS.Transfer(engine.SnapshotCache, from, new byte[19], BigInteger.One, false, persistingBlock)); } internal static StorageKey CreateStorageKey(byte prefix, uint key) diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs index 7c1d874b1b..f9a3089f9d 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs @@ -27,7 +27,7 @@ namespace Neo.UnitTests.SmartContract.Native [TestClass] public class UT_NativeContract { - private DataCache _snapshot; + private DataCache _snapshotCache; /// /// _nativeStates contains a mapping from native contract name to expected native contract state /// constructed with all hardforks enabled and marshalled in JSON. @@ -37,7 +37,7 @@ public class UT_NativeContract [TestInitialize] public void TestSetup() { - _snapshot = TestBlockchain.GetTestSnapshotCache(); + _snapshotCache = TestBlockchain.GetTestSnapshotCache(); _nativeStates = new Dictionary { {"ContractManagement", """{"id":-1,"updatecounter":0,"hash":"0xfffdc93764dbaddd97c48f252a53ea4643faa3fd","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":1094259016},"manifest":{"name":"ContractManagement","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"deploy","parameters":[{"name":"nefFile","type":"ByteArray"},{"name":"manifest","type":"ByteArray"}],"returntype":"Array","offset":0,"safe":false},{"name":"deploy","parameters":[{"name":"nefFile","type":"ByteArray"},{"name":"manifest","type":"ByteArray"},{"name":"data","type":"Any"}],"returntype":"Array","offset":7,"safe":false},{"name":"destroy","parameters":[],"returntype":"Void","offset":14,"safe":false},{"name":"getContract","parameters":[{"name":"hash","type":"Hash160"}],"returntype":"Array","offset":21,"safe":true},{"name":"getContractById","parameters":[{"name":"id","type":"Integer"}],"returntype":"Array","offset":28,"safe":true},{"name":"getContractHashes","parameters":[],"returntype":"InteropInterface","offset":35,"safe":true},{"name":"getMinimumDeploymentFee","parameters":[],"returntype":"Integer","offset":42,"safe":true},{"name":"hasMethod","parameters":[{"name":"hash","type":"Hash160"},{"name":"method","type":"String"},{"name":"pcount","type":"Integer"}],"returntype":"Boolean","offset":49,"safe":true},{"name":"setMinimumDeploymentFee","parameters":[{"name":"value","type":"Integer"}],"returntype":"Void","offset":56,"safe":false},{"name":"update","parameters":[{"name":"nefFile","type":"ByteArray"},{"name":"manifest","type":"ByteArray"}],"returntype":"Void","offset":63,"safe":false},{"name":"update","parameters":[{"name":"nefFile","type":"ByteArray"},{"name":"manifest","type":"ByteArray"},{"name":"data","type":"Any"}],"returntype":"Void","offset":70,"safe":false}],"events":[{"name":"Deploy","parameters":[{"name":"Hash","type":"Hash160"}]},{"name":"Update","parameters":[{"name":"Hash","type":"Hash160"}]},{"name":"Destroy","parameters":[{"name":"Hash","type":"Hash160"}]}]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}""" }, @@ -123,7 +123,7 @@ public void TestGenesisNEP17Manifest() }, Transactions = [] }; - var snapshot = _snapshot.CloneCache(); + var snapshot = _snapshotCache.CloneCache(); // Ensure that native NEP17 contracts contain proper supported standards and events declared // in the manifest constructed for all hardforks enabled. Ref. https://github.com/neo-project/neo/pull/3195. @@ -150,7 +150,7 @@ public void TestGenesisNativeState() }, Transactions = [] }; - var snapshot = _snapshot.CloneCache(); + var snapshot = _snapshotCache.CloneCache(); // Ensure that all native contracts have proper state generated with an assumption that // all hardforks enabled. diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_NeoToken.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_NeoToken.cs index b08898aad5..cff1eb12b0 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_NeoToken.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_NeoToken.cs @@ -30,13 +30,13 @@ namespace Neo.UnitTests.SmartContract.Native [TestClass] public class UT_NeoToken { - private DataCache _snapshot; + private DataCache _snapshotCache; private Block _persistingBlock; [TestInitialize] public void TestSetup() { - _snapshot = TestBlockchain.GetTestSnapshotCache(); + _snapshotCache = TestBlockchain.GetTestSnapshotCache(); _persistingBlock = new Block { Header = new Header(), @@ -48,37 +48,37 @@ public void TestSetup() public void Check_Name() => NativeContract.NEO.Name.Should().Be(nameof(NeoToken)); [TestMethod] - public void Check_Symbol() => NativeContract.NEO.Symbol(_snapshot).Should().Be("NEO"); + public void Check_Symbol() => NativeContract.NEO.Symbol(_snapshotCache).Should().Be("NEO"); [TestMethod] - public void Check_Decimals() => NativeContract.NEO.Decimals(_snapshot).Should().Be(0); + public void Check_Decimals() => NativeContract.NEO.Decimals(_snapshotCache).Should().Be(0); [TestMethod] public void Check_Vote() { - var snapshot = _snapshot.CloneCache(); + var clonedCache = _snapshotCache.CloneCache(); var persistingBlock = new Block { Header = new Header { Index = 1000 } }; var storageKey = new KeyBuilder(NativeContract.Ledger.Id, 12); - snapshot.Add(storageKey, new StorageItem(new HashIndexState { Hash = UInt256.Zero, Index = persistingBlock.Index - 1 })); + clonedCache.Add(storageKey, new StorageItem(new HashIndexState { Hash = UInt256.Zero, Index = persistingBlock.Index - 1 })); byte[] from = Contract.GetBFTAddress(TestProtocolSettings.Default.StandbyValidators).ToArray(); // No signature - var ret = Check_Vote(snapshot, from, null, false, persistingBlock); + var ret = Check_Vote(clonedCache, from, null, false, persistingBlock); ret.Result.Should().BeFalse(); ret.State.Should().BeTrue(); // Wrong address - ret = Check_Vote(snapshot, new byte[19], null, false, persistingBlock); + ret = Check_Vote(clonedCache, new byte[19], null, false, persistingBlock); ret.Result.Should().BeFalse(); ret.State.Should().BeFalse(); // Wrong ec - ret = Check_Vote(snapshot, from, new byte[19], true, persistingBlock); + ret = Check_Vote(clonedCache, from, new byte[19], true, persistingBlock); ret.Result.Should().BeFalse(); ret.State.Should().BeFalse(); @@ -88,130 +88,130 @@ public void Check_Vote() fakeAddr[0] = 0x5F; fakeAddr[5] = 0xFF; - ret = Check_Vote(snapshot, fakeAddr, null, true, persistingBlock); + ret = Check_Vote(clonedCache, fakeAddr, null, true, persistingBlock); ret.Result.Should().BeFalse(); ret.State.Should().BeTrue(); // no registered - var accountState = snapshot.TryGet(CreateStorageKey(20, from)).GetInteroperable(); + var accountState = clonedCache.TryGet(CreateStorageKey(20, from)).GetInteroperable(); accountState.VoteTo = null; - ret = Check_Vote(snapshot, from, ECCurve.Secp256r1.G.ToArray(), true, persistingBlock); + ret = Check_Vote(clonedCache, from, ECCurve.Secp256r1.G.ToArray(), true, persistingBlock); ret.Result.Should().BeFalse(); ret.State.Should().BeTrue(); accountState.VoteTo.Should().BeNull(); // normal case - snapshot.Add(CreateStorageKey(33, ECCurve.Secp256r1.G.ToArray()), new StorageItem(new CandidateState() { Registered = true })); - ret = Check_Vote(snapshot, from, ECCurve.Secp256r1.G.ToArray(), true, persistingBlock); + clonedCache.Add(CreateStorageKey(33, ECCurve.Secp256r1.G.ToArray()), new StorageItem(new CandidateState() { Registered = true })); + ret = Check_Vote(clonedCache, from, ECCurve.Secp256r1.G.ToArray(), true, persistingBlock); ret.Result.Should().BeTrue(); ret.State.Should().BeTrue(); - accountState = snapshot.TryGet(CreateStorageKey(20, from)).GetInteroperable(); + accountState = clonedCache.TryGet(CreateStorageKey(20, from)).GetInteroperable(); accountState.VoteTo.Should().Be(ECCurve.Secp256r1.G); } [TestMethod] public void Check_Vote_Sameaccounts() { - var snapshot = _snapshot.CloneCache(); + var clonedCache = _snapshotCache.CloneCache(); var persistingBlock = new Block { Header = new Header { Index = 1000 } }; var storageKey = new KeyBuilder(NativeContract.Ledger.Id, 12); - snapshot.Add(storageKey, new StorageItem(new HashIndexState { Hash = UInt256.Zero, Index = persistingBlock.Index - 1 })); + clonedCache.Add(storageKey, new StorageItem(new HashIndexState { Hash = UInt256.Zero, Index = persistingBlock.Index - 1 })); byte[] from = Contract.GetBFTAddress(TestProtocolSettings.Default.StandbyValidators).ToArray(); - var accountState = snapshot.TryGet(CreateStorageKey(20, from)).GetInteroperable(); + var accountState = clonedCache.TryGet(CreateStorageKey(20, from)).GetInteroperable(); accountState.Balance = 100; - snapshot.Add(CreateStorageKey(33, ECCurve.Secp256r1.G.ToArray()), new StorageItem(new CandidateState() { Registered = true })); - var ret = Check_Vote(snapshot, from, ECCurve.Secp256r1.G.ToArray(), true, persistingBlock); + clonedCache.Add(CreateStorageKey(33, ECCurve.Secp256r1.G.ToArray()), new StorageItem(new CandidateState() { Registered = true })); + var ret = Check_Vote(clonedCache, from, ECCurve.Secp256r1.G.ToArray(), true, persistingBlock); ret.Result.Should().BeTrue(); ret.State.Should().BeTrue(); - accountState = snapshot.TryGet(CreateStorageKey(20, from)).GetInteroperable(); + accountState = clonedCache.TryGet(CreateStorageKey(20, from)).GetInteroperable(); accountState.VoteTo.Should().Be(ECCurve.Secp256r1.G); //two account vote for the same account - var stateValidator = snapshot.GetAndChange(CreateStorageKey(33, ECCurve.Secp256r1.G.ToArray())).GetInteroperable(); + var stateValidator = clonedCache.GetAndChange(CreateStorageKey(33, ECCurve.Secp256r1.G.ToArray())).GetInteroperable(); stateValidator.Votes.Should().Be(100); var G_Account = Contract.CreateSignatureContract(ECCurve.Secp256r1.G).ScriptHash.ToArray(); - snapshot.Add(CreateStorageKey(20, G_Account), new StorageItem(new NeoAccountState { Balance = 200 })); - var secondAccount = snapshot.TryGet(CreateStorageKey(20, G_Account)).GetInteroperable(); + clonedCache.Add(CreateStorageKey(20, G_Account), new StorageItem(new NeoAccountState { Balance = 200 })); + var secondAccount = clonedCache.TryGet(CreateStorageKey(20, G_Account)).GetInteroperable(); secondAccount.Balance.Should().Be(200); - ret = Check_Vote(snapshot, G_Account, ECCurve.Secp256r1.G.ToArray(), true, persistingBlock); + ret = Check_Vote(clonedCache, G_Account, ECCurve.Secp256r1.G.ToArray(), true, persistingBlock); ret.Result.Should().BeTrue(); ret.State.Should().BeTrue(); - stateValidator = snapshot.GetAndChange(CreateStorageKey(33, ECCurve.Secp256r1.G.ToArray())).GetInteroperable(); + stateValidator = clonedCache.GetAndChange(CreateStorageKey(33, ECCurve.Secp256r1.G.ToArray())).GetInteroperable(); stateValidator.Votes.Should().Be(300); } [TestMethod] public void Check_Vote_ChangeVote() { - var snapshot = _snapshot.CloneCache(); + var clonedCache = _snapshotCache.CloneCache(); var persistingBlock = new Block { Header = new Header { Index = 1000 } }; var storageKey = new KeyBuilder(NativeContract.Ledger.Id, 12); - snapshot.Add(storageKey, new StorageItem(new HashIndexState { Hash = UInt256.Zero, Index = persistingBlock.Index - 1 })); + clonedCache.Add(storageKey, new StorageItem(new HashIndexState { Hash = UInt256.Zero, Index = persistingBlock.Index - 1 })); //from vote to G byte[] from = TestProtocolSettings.Default.StandbyValidators[0].ToArray(); var from_Account = Contract.CreateSignatureContract(TestProtocolSettings.Default.StandbyValidators[0]).ScriptHash.ToArray(); - snapshot.Add(CreateStorageKey(20, from_Account), new StorageItem(new NeoAccountState())); - var accountState = snapshot.TryGet(CreateStorageKey(20, from_Account)).GetInteroperable(); + clonedCache.Add(CreateStorageKey(20, from_Account), new StorageItem(new NeoAccountState())); + var accountState = clonedCache.TryGet(CreateStorageKey(20, from_Account)).GetInteroperable(); accountState.Balance = 100; - snapshot.Add(CreateStorageKey(33, ECCurve.Secp256r1.G.ToArray()), new StorageItem(new CandidateState() { Registered = true })); - var ret = Check_Vote(snapshot, from_Account, ECCurve.Secp256r1.G.ToArray(), true, persistingBlock); + clonedCache.Add(CreateStorageKey(33, ECCurve.Secp256r1.G.ToArray()), new StorageItem(new CandidateState() { Registered = true })); + var ret = Check_Vote(clonedCache, from_Account, ECCurve.Secp256r1.G.ToArray(), true, persistingBlock); ret.Result.Should().BeTrue(); ret.State.Should().BeTrue(); - accountState = snapshot.TryGet(CreateStorageKey(20, from_Account)).GetInteroperable(); + accountState = clonedCache.TryGet(CreateStorageKey(20, from_Account)).GetInteroperable(); accountState.VoteTo.Should().Be(ECCurve.Secp256r1.G); //from change vote to itself - var G_stateValidator = snapshot.GetAndChange(CreateStorageKey(33, ECCurve.Secp256r1.G.ToArray())).GetInteroperable(); + var G_stateValidator = clonedCache.GetAndChange(CreateStorageKey(33, ECCurve.Secp256r1.G.ToArray())).GetInteroperable(); G_stateValidator.Votes.Should().Be(100); var G_Account = Contract.CreateSignatureContract(ECCurve.Secp256r1.G).ScriptHash.ToArray(); - snapshot.Add(CreateStorageKey(20, G_Account), new StorageItem(new NeoAccountState { Balance = 200 })); - snapshot.Add(CreateStorageKey(33, from), new StorageItem(new CandidateState() { Registered = true })); - ret = Check_Vote(snapshot, from_Account, from, true, persistingBlock); + clonedCache.Add(CreateStorageKey(20, G_Account), new StorageItem(new NeoAccountState { Balance = 200 })); + clonedCache.Add(CreateStorageKey(33, from), new StorageItem(new CandidateState() { Registered = true })); + ret = Check_Vote(clonedCache, from_Account, from, true, persistingBlock); ret.Result.Should().BeTrue(); ret.State.Should().BeTrue(); - G_stateValidator = snapshot.GetAndChange(CreateStorageKey(33, ECCurve.Secp256r1.G.ToArray())).GetInteroperable(); + G_stateValidator = clonedCache.GetAndChange(CreateStorageKey(33, ECCurve.Secp256r1.G.ToArray())).GetInteroperable(); G_stateValidator.Votes.Should().Be(0); - var from_stateValidator = snapshot.GetAndChange(CreateStorageKey(33, from)).GetInteroperable(); + var from_stateValidator = clonedCache.GetAndChange(CreateStorageKey(33, from)).GetInteroperable(); from_stateValidator.Votes.Should().Be(100); } [TestMethod] public void Check_Vote_VoteToNull() { - var snapshot = _snapshot.CloneCache(); + var clonedCache = _snapshotCache.CloneCache(); var persistingBlock = new Block { Header = new Header { Index = 1000 } }; var storageKey = new KeyBuilder(NativeContract.Ledger.Id, 12); - snapshot.Add(storageKey, new StorageItem(new HashIndexState { Hash = UInt256.Zero, Index = persistingBlock.Index - 1 })); + clonedCache.Add(storageKey, new StorageItem(new HashIndexState { Hash = UInt256.Zero, Index = persistingBlock.Index - 1 })); byte[] from = TestProtocolSettings.Default.StandbyValidators[0].ToArray(); var from_Account = Contract.CreateSignatureContract(TestProtocolSettings.Default.StandbyValidators[0]).ScriptHash.ToArray(); - snapshot.Add(CreateStorageKey(20, from_Account), new StorageItem(new NeoAccountState())); - var accountState = snapshot.TryGet(CreateStorageKey(20, from_Account)).GetInteroperable(); + clonedCache.Add(CreateStorageKey(20, from_Account), new StorageItem(new NeoAccountState())); + var accountState = clonedCache.TryGet(CreateStorageKey(20, from_Account)).GetInteroperable(); accountState.Balance = 100; - snapshot.Add(CreateStorageKey(33, ECCurve.Secp256r1.G.ToArray()), new StorageItem(new CandidateState() { Registered = true })); - snapshot.Add(CreateStorageKey(23, ECCurve.Secp256r1.G.ToArray()), new StorageItem(new BigInteger(100500))); - var ret = Check_Vote(snapshot, from_Account, ECCurve.Secp256r1.G.ToArray(), true, persistingBlock); + clonedCache.Add(CreateStorageKey(33, ECCurve.Secp256r1.G.ToArray()), new StorageItem(new CandidateState() { Registered = true })); + clonedCache.Add(CreateStorageKey(23, ECCurve.Secp256r1.G.ToArray()), new StorageItem(new BigInteger(100500))); + var ret = Check_Vote(clonedCache, from_Account, ECCurve.Secp256r1.G.ToArray(), true, persistingBlock); ret.Result.Should().BeTrue(); ret.State.Should().BeTrue(); - accountState = snapshot.TryGet(CreateStorageKey(20, from_Account)).GetInteroperable(); + accountState = clonedCache.TryGet(CreateStorageKey(20, from_Account)).GetInteroperable(); accountState.VoteTo.Should().Be(ECCurve.Secp256r1.G); accountState.LastGasPerVote.Should().Be(100500); //from vote to null account G votes becomes 0 - var G_stateValidator = snapshot.GetAndChange(CreateStorageKey(33, ECCurve.Secp256r1.G.ToArray())).GetInteroperable(); + var G_stateValidator = clonedCache.GetAndChange(CreateStorageKey(33, ECCurve.Secp256r1.G.ToArray())).GetInteroperable(); G_stateValidator.Votes.Should().Be(100); var G_Account = Contract.CreateSignatureContract(ECCurve.Secp256r1.G).ScriptHash.ToArray(); - snapshot.Add(CreateStorageKey(20, G_Account), new StorageItem(new NeoAccountState { Balance = 200 })); - snapshot.Add(CreateStorageKey(33, from), new StorageItem(new CandidateState() { Registered = true })); - ret = Check_Vote(snapshot, from_Account, null, true, persistingBlock); + clonedCache.Add(CreateStorageKey(20, G_Account), new StorageItem(new NeoAccountState { Balance = 200 })); + clonedCache.Add(CreateStorageKey(33, from), new StorageItem(new CandidateState() { Registered = true })); + ret = Check_Vote(clonedCache, from_Account, null, true, persistingBlock); ret.Result.Should().BeTrue(); ret.State.Should().BeTrue(); - G_stateValidator = snapshot.GetAndChange(CreateStorageKey(33, ECCurve.Secp256r1.G.ToArray())).GetInteroperable(); + G_stateValidator = clonedCache.GetAndChange(CreateStorageKey(33, ECCurve.Secp256r1.G.ToArray())).GetInteroperable(); G_stateValidator.Votes.Should().Be(0); - accountState = snapshot.TryGet(CreateStorageKey(20, from_Account)).GetInteroperable(); + accountState = clonedCache.TryGet(CreateStorageKey(20, from_Account)).GetInteroperable(); accountState.VoteTo.Should().Be(null); accountState.LastGasPerVote.Should().Be(0); } @@ -219,19 +219,19 @@ public void Check_Vote_VoteToNull() [TestMethod] public void Check_UnclaimedGas() { - var snapshot = _snapshot.CloneCache(); + var clonedCache = _snapshotCache.CloneCache(); var persistingBlock = new Block { Header = new Header { Index = 1000 } }; var storageKey = new KeyBuilder(NativeContract.Ledger.Id, 12); - snapshot.Add(storageKey, new StorageItem(new HashIndexState { Hash = UInt256.Zero, Index = persistingBlock.Index - 1 })); + clonedCache.Add(storageKey, new StorageItem(new HashIndexState { Hash = UInt256.Zero, Index = persistingBlock.Index - 1 })); byte[] from = Contract.GetBFTAddress(TestProtocolSettings.Default.StandbyValidators).ToArray(); - var unclaim = Check_UnclaimedGas(snapshot, from, persistingBlock); + var unclaim = Check_UnclaimedGas(clonedCache, from, persistingBlock); unclaim.Value.Should().Be(new BigInteger(0.5 * 1000 * 100000000L)); unclaim.State.Should().BeTrue(); - unclaim = Check_UnclaimedGas(snapshot, new byte[19], persistingBlock); + unclaim = Check_UnclaimedGas(clonedCache, new byte[19], persistingBlock); unclaim.Value.Should().Be(BigInteger.Zero); unclaim.State.Should().BeFalse(); } @@ -239,113 +239,113 @@ public void Check_UnclaimedGas() [TestMethod] public void Check_RegisterValidator() { - var snapshot = _snapshot.CloneCache(); + var clonedCache = _snapshotCache.CloneCache(); - var keyCount = snapshot.GetChangeSet().Count(); + var keyCount = clonedCache.GetChangeSet().Count(); var point = TestProtocolSettings.Default.StandbyValidators[0].EncodePoint(true).Clone() as byte[]; - var ret = Check_RegisterValidator(snapshot, point, _persistingBlock); // Exists + var ret = Check_RegisterValidator(clonedCache, point, _persistingBlock); // Exists ret.State.Should().BeTrue(); ret.Result.Should().BeTrue(); - snapshot.GetChangeSet().Count().Should().Be(++keyCount); // No changes + clonedCache.GetChangeSet().Count().Should().Be(++keyCount); // No changes point[20]++; // fake point - ret = Check_RegisterValidator(snapshot, point, _persistingBlock); // New + ret = Check_RegisterValidator(clonedCache, point, _persistingBlock); // New ret.State.Should().BeTrue(); ret.Result.Should().BeTrue(); - snapshot.GetChangeSet().Count().Should().Be(keyCount + 1); // New validator + clonedCache.GetChangeSet().Count().Should().Be(keyCount + 1); // New validator // Check GetRegisteredValidators - var members = NativeContract.NEO.GetCandidatesInternal(snapshot); + var members = NativeContract.NEO.GetCandidatesInternal(clonedCache); Assert.AreEqual(2, members.Count()); } [TestMethod] public void Check_UnregisterCandidate() { - var snapshot = _snapshot.CloneCache(); + var clonedCache = _snapshotCache.CloneCache(); _persistingBlock.Header.Index = 1; - var keyCount = snapshot.GetChangeSet().Count(); + var keyCount = clonedCache.GetChangeSet().Count(); var point = TestProtocolSettings.Default.StandbyValidators[0].EncodePoint(true); //without register - var ret = Check_UnregisterCandidate(snapshot, point, _persistingBlock); + var ret = Check_UnregisterCandidate(clonedCache, point, _persistingBlock); ret.State.Should().BeTrue(); ret.Result.Should().BeTrue(); - snapshot.GetChangeSet().Count().Should().Be(keyCount); + clonedCache.GetChangeSet().Count().Should().Be(keyCount); //register and then unregister - ret = Check_RegisterValidator(snapshot, point, _persistingBlock); - StorageItem item = snapshot.GetAndChange(CreateStorageKey(33, point)); + ret = Check_RegisterValidator(clonedCache, point, _persistingBlock); + StorageItem item = clonedCache.GetAndChange(CreateStorageKey(33, point)); item.Size.Should().Be(7); ret.State.Should().BeTrue(); ret.Result.Should().BeTrue(); - var members = NativeContract.NEO.GetCandidatesInternal(snapshot); + var members = NativeContract.NEO.GetCandidatesInternal(clonedCache); Assert.AreEqual(1, members.Count()); - snapshot.GetChangeSet().Count().Should().Be(keyCount + 1); + clonedCache.GetChangeSet().Count().Should().Be(keyCount + 1); StorageKey key = CreateStorageKey(33, point); - snapshot.TryGet(key).Should().NotBeNull(); + clonedCache.TryGet(key).Should().NotBeNull(); - ret = Check_UnregisterCandidate(snapshot, point, _persistingBlock); + ret = Check_UnregisterCandidate(clonedCache, point, _persistingBlock); ret.State.Should().BeTrue(); ret.Result.Should().BeTrue(); - snapshot.GetChangeSet().Count().Should().Be(keyCount); + clonedCache.GetChangeSet().Count().Should().Be(keyCount); - members = NativeContract.NEO.GetCandidatesInternal(snapshot); + members = NativeContract.NEO.GetCandidatesInternal(clonedCache); Assert.AreEqual(0, members.Count()); - snapshot.TryGet(key).Should().BeNull(); + clonedCache.TryGet(key).Should().BeNull(); //register with votes, then unregister - ret = Check_RegisterValidator(snapshot, point, _persistingBlock); + ret = Check_RegisterValidator(clonedCache, point, _persistingBlock); ret.State.Should().BeTrue(); var G_Account = Contract.CreateSignatureContract(ECCurve.Secp256r1.G).ScriptHash.ToArray(); - snapshot.Add(CreateStorageKey(20, G_Account), new StorageItem(new NeoAccountState())); - var accountState = snapshot.TryGet(CreateStorageKey(20, G_Account)).GetInteroperable(); + clonedCache.Add(CreateStorageKey(20, G_Account), new StorageItem(new NeoAccountState())); + var accountState = clonedCache.TryGet(CreateStorageKey(20, G_Account)).GetInteroperable(); accountState.Balance = 100; - Check_Vote(snapshot, G_Account, TestProtocolSettings.Default.StandbyValidators[0].ToArray(), true, _persistingBlock); - ret = Check_UnregisterCandidate(snapshot, point, _persistingBlock); + Check_Vote(clonedCache, G_Account, TestProtocolSettings.Default.StandbyValidators[0].ToArray(), true, _persistingBlock); + ret = Check_UnregisterCandidate(clonedCache, point, _persistingBlock); ret.State.Should().BeTrue(); ret.Result.Should().BeTrue(); - snapshot.TryGet(key).Should().NotBeNull(); - StorageItem pointItem = snapshot.TryGet(key); + clonedCache.TryGet(key).Should().NotBeNull(); + StorageItem pointItem = clonedCache.TryGet(key); CandidateState pointState = pointItem.GetInteroperable(); pointState.Registered.Should().BeFalse(); pointState.Votes.Should().Be(100); //vote fail - ret = Check_Vote(snapshot, G_Account, TestProtocolSettings.Default.StandbyValidators[0].ToArray(), true, _persistingBlock); + ret = Check_Vote(clonedCache, G_Account, TestProtocolSettings.Default.StandbyValidators[0].ToArray(), true, _persistingBlock); ret.State.Should().BeTrue(); ret.Result.Should().BeFalse(); - accountState = snapshot.TryGet(CreateStorageKey(20, G_Account)).GetInteroperable(); + accountState = clonedCache.TryGet(CreateStorageKey(20, G_Account)).GetInteroperable(); accountState.VoteTo.Should().Be(TestProtocolSettings.Default.StandbyValidators[0]); } [TestMethod] public void Check_GetCommittee() { - var snapshot = _snapshot.CloneCache(); - var keyCount = snapshot.GetChangeSet().Count(); + var clonedCache = _snapshotCache.CloneCache(); + var keyCount = clonedCache.GetChangeSet().Count(); var point = TestProtocolSettings.Default.StandbyValidators[0].EncodePoint(true); var persistingBlock = _persistingBlock; persistingBlock.Header.Index = 1; //register with votes with 20000000 var G_Account = Contract.CreateSignatureContract(ECCurve.Secp256r1.G).ScriptHash.ToArray(); - snapshot.Add(CreateStorageKey(20, G_Account), new StorageItem(new NeoAccountState())); - var accountState = snapshot.TryGet(CreateStorageKey(20, G_Account)).GetInteroperable(); + clonedCache.Add(CreateStorageKey(20, G_Account), new StorageItem(new NeoAccountState())); + var accountState = clonedCache.TryGet(CreateStorageKey(20, G_Account)).GetInteroperable(); accountState.Balance = 20000000; - var ret = Check_RegisterValidator(snapshot, ECCurve.Secp256r1.G.ToArray(), persistingBlock); + var ret = Check_RegisterValidator(clonedCache, ECCurve.Secp256r1.G.ToArray(), persistingBlock); ret.State.Should().BeTrue(); ret.Result.Should().BeTrue(); - ret = Check_Vote(snapshot, G_Account, ECCurve.Secp256r1.G.ToArray(), true, persistingBlock); + ret = Check_Vote(clonedCache, G_Account, ECCurve.Secp256r1.G.ToArray(), true, persistingBlock); ret.State.Should().BeTrue(); ret.Result.Should().BeTrue(); - var committeemembers = NativeContract.NEO.GetCommittee(snapshot); + var committeemembers = NativeContract.NEO.GetCommittee(clonedCache); var defaultCommittee = TestProtocolSettings.Default.StandbyCommittee.OrderBy(p => p).ToArray(); committeemembers.GetType().Should().Be(typeof(ECPoint[])); for (int i = 0; i < TestProtocolSettings.Default.CommitteeMembersCount; i++) @@ -368,14 +368,14 @@ public void Check_GetCommittee() }; for (int i = 0; i < TestProtocolSettings.Default.CommitteeMembersCount - 1; i++) { - ret = Check_RegisterValidator(snapshot, TestProtocolSettings.Default.StandbyCommittee[i].ToArray(), persistingBlock); + ret = Check_RegisterValidator(clonedCache, TestProtocolSettings.Default.StandbyCommittee[i].ToArray(), persistingBlock); ret.State.Should().BeTrue(); ret.Result.Should().BeTrue(); } - Check_OnPersist(snapshot, persistingBlock).Should().BeTrue(); + Check_OnPersist(clonedCache, persistingBlock).Should().BeTrue(); - committeemembers = NativeContract.NEO.GetCommittee(snapshot); + committeemembers = NativeContract.NEO.GetCommittee(clonedCache); committeemembers.Length.Should().Be(TestProtocolSettings.Default.CommitteeMembersCount); committeemembers.Contains(ECCurve.Secp256r1.G).Should().BeTrue(); for (int i = 0; i < TestProtocolSettings.Default.CommitteeMembersCount - 1; i++) @@ -388,79 +388,79 @@ public void Check_GetCommittee() [TestMethod] public void Check_Transfer() { - var snapshot = _snapshot.CloneCache(); + var clonedCache = _snapshotCache.CloneCache(); var persistingBlock = new Block { Header = new Header { Index = 1000 } }; byte[] from = Contract.GetBFTAddress(TestProtocolSettings.Default.StandbyValidators).ToArray(); byte[] to = new byte[20]; var storageKey = new KeyBuilder(NativeContract.Ledger.Id, 12); - snapshot.Add(storageKey, new StorageItem(new HashIndexState { Hash = UInt256.Zero, Index = persistingBlock.Index - 1 })); - var keyCount = snapshot.GetChangeSet().Count(); + clonedCache.Add(storageKey, new StorageItem(new HashIndexState { Hash = UInt256.Zero, Index = persistingBlock.Index - 1 })); + var keyCount = clonedCache.GetChangeSet().Count(); // Check unclaim - var unclaim = Check_UnclaimedGas(snapshot, from, persistingBlock); + var unclaim = Check_UnclaimedGas(clonedCache, from, persistingBlock); unclaim.Value.Should().Be(new BigInteger(0.5 * 1000 * 100000000L)); unclaim.State.Should().BeTrue(); // Transfer - NativeContract.NEO.Transfer(snapshot, from, to, BigInteger.One, false, persistingBlock).Should().BeFalse(); // Not signed - NativeContract.NEO.Transfer(snapshot, from, to, BigInteger.One, true, persistingBlock).Should().BeTrue(); - NativeContract.NEO.BalanceOf(snapshot, from).Should().Be(99999999); - NativeContract.NEO.BalanceOf(snapshot, to).Should().Be(1); + NativeContract.NEO.Transfer(clonedCache, from, to, BigInteger.One, false, persistingBlock).Should().BeFalse(); // Not signed + NativeContract.NEO.Transfer(clonedCache, from, to, BigInteger.One, true, persistingBlock).Should().BeTrue(); + NativeContract.NEO.BalanceOf(clonedCache, from).Should().Be(99999999); + NativeContract.NEO.BalanceOf(clonedCache, to).Should().Be(1); - var (from_balance, _, _) = GetAccountState(snapshot, new UInt160(from)); - var (to_balance, _, _) = GetAccountState(snapshot, new UInt160(to)); + var (from_balance, _, _) = GetAccountState(clonedCache, new UInt160(from)); + var (to_balance, _, _) = GetAccountState(clonedCache, new UInt160(to)); from_balance.Should().Be(99999999); to_balance.Should().Be(1); // Check unclaim - unclaim = Check_UnclaimedGas(snapshot, from, persistingBlock); + unclaim = Check_UnclaimedGas(clonedCache, from, persistingBlock); unclaim.Value.Should().Be(new BigInteger(0)); unclaim.State.Should().BeTrue(); - snapshot.GetChangeSet().Count().Should().Be(keyCount + 4); // Gas + new balance + clonedCache.GetChangeSet().Count().Should().Be(keyCount + 4); // Gas + new balance // Return balance - keyCount = snapshot.GetChangeSet().Count(); + keyCount = clonedCache.GetChangeSet().Count(); - NativeContract.NEO.Transfer(snapshot, to, from, BigInteger.One, true, persistingBlock).Should().BeTrue(); - NativeContract.NEO.BalanceOf(snapshot, to).Should().Be(0); - snapshot.GetChangeSet().Count().Should().Be(keyCount - 1); // Remove neo balance from address two + NativeContract.NEO.Transfer(clonedCache, to, from, BigInteger.One, true, persistingBlock).Should().BeTrue(); + NativeContract.NEO.BalanceOf(clonedCache, to).Should().Be(0); + clonedCache.GetChangeSet().Count().Should().Be(keyCount - 1); // Remove neo balance from address two // Bad inputs - Assert.ThrowsException(() => NativeContract.NEO.Transfer(snapshot, from, to, BigInteger.MinusOne, true, persistingBlock)); - Assert.ThrowsException(() => NativeContract.NEO.Transfer(snapshot, new byte[19], to, BigInteger.One, false, persistingBlock)); - Assert.ThrowsException(() => NativeContract.NEO.Transfer(snapshot, from, new byte[19], BigInteger.One, false, persistingBlock)); + Assert.ThrowsException(() => NativeContract.NEO.Transfer(clonedCache, from, to, BigInteger.MinusOne, true, persistingBlock)); + Assert.ThrowsException(() => NativeContract.NEO.Transfer(clonedCache, new byte[19], to, BigInteger.One, false, persistingBlock)); + Assert.ThrowsException(() => NativeContract.NEO.Transfer(clonedCache, from, new byte[19], BigInteger.One, false, persistingBlock)); // More than balance - NativeContract.NEO.Transfer(snapshot, to, from, new BigInteger(2), true, persistingBlock).Should().BeFalse(); + NativeContract.NEO.Transfer(clonedCache, to, from, new BigInteger(2), true, persistingBlock).Should().BeFalse(); } [TestMethod] public void Check_BalanceOf() { - var snapshot = _snapshot.CloneCache(); + var clonedCache = _snapshotCache.CloneCache(); byte[] account = Contract.GetBFTAddress(TestProtocolSettings.Default.StandbyValidators).ToArray(); - NativeContract.NEO.BalanceOf(snapshot, account).Should().Be(100_000_000); + NativeContract.NEO.BalanceOf(clonedCache, account).Should().Be(100_000_000); account[5]++; // Without existing balance - NativeContract.NEO.BalanceOf(snapshot, account).Should().Be(0); + NativeContract.NEO.BalanceOf(clonedCache, account).Should().Be(0); } [TestMethod] public void Check_CommitteeBonus() { - var snapshot = _snapshot.CloneCache(); + var clonedCache = _snapshotCache.CloneCache(); var persistingBlock = new Block { Header = new Header @@ -474,103 +474,103 @@ public void Check_CommitteeBonus() Transactions = Array.Empty() }; - Check_PostPersist(snapshot, persistingBlock).Should().BeTrue(); + Check_PostPersist(clonedCache, persistingBlock).Should().BeTrue(); var committee = TestProtocolSettings.Default.StandbyCommittee; - NativeContract.GAS.BalanceOf(snapshot, Contract.CreateSignatureContract(committee[0]).ScriptHash.ToArray()).Should().Be(50000000); - NativeContract.GAS.BalanceOf(snapshot, Contract.CreateSignatureContract(committee[1]).ScriptHash.ToArray()).Should().Be(50000000); - NativeContract.GAS.BalanceOf(snapshot, Contract.CreateSignatureContract(committee[2]).ScriptHash.ToArray()).Should().Be(0); + NativeContract.GAS.BalanceOf(clonedCache, Contract.CreateSignatureContract(committee[0]).ScriptHash.ToArray()).Should().Be(50000000); + NativeContract.GAS.BalanceOf(clonedCache, Contract.CreateSignatureContract(committee[1]).ScriptHash.ToArray()).Should().Be(50000000); + NativeContract.GAS.BalanceOf(clonedCache, Contract.CreateSignatureContract(committee[2]).ScriptHash.ToArray()).Should().Be(0); } [TestMethod] public void Check_Initialize() { - var snapshot = _snapshot.CloneCache(); + var clonedCache = _snapshotCache.CloneCache(); // StandbyValidators - Check_GetCommittee(snapshot, null); + Check_GetCommittee(clonedCache, null); } [TestMethod] public void TestCalculateBonus() { - var snapshot = _snapshot.CloneCache(); + var clonedCache = _snapshotCache.CloneCache(); var persistingBlock = new Block(); StorageKey key = CreateStorageKey(20, UInt160.Zero.ToArray()); // Fault: balance < 0 - snapshot.Add(key, new StorageItem(new NeoAccountState + clonedCache.Add(key, new StorageItem(new NeoAccountState { Balance = -100 })); - Action action = () => NativeContract.NEO.UnclaimedGas(snapshot, UInt160.Zero, 10).Should().Be(new BigInteger(0)); + Action action = () => NativeContract.NEO.UnclaimedGas(clonedCache, UInt160.Zero, 10).Should().Be(new BigInteger(0)); action.Should().Throw(); - snapshot.Delete(key); + clonedCache.Delete(key); // Fault range: start >= end - snapshot.GetAndChange(key, () => new StorageItem(new NeoAccountState + clonedCache.GetAndChange(key, () => new StorageItem(new NeoAccountState { Balance = 100, BalanceHeight = 100 })); - action = () => NativeContract.NEO.UnclaimedGas(snapshot, UInt160.Zero, 10).Should().Be(new BigInteger(0)); - snapshot.Delete(key); + action = () => NativeContract.NEO.UnclaimedGas(clonedCache, UInt160.Zero, 10).Should().Be(new BigInteger(0)); + clonedCache.Delete(key); // Fault range: start >= end - snapshot.GetAndChange(key, () => new StorageItem(new NeoAccountState + clonedCache.GetAndChange(key, () => new StorageItem(new NeoAccountState { Balance = 100, BalanceHeight = 100 })); - action = () => NativeContract.NEO.UnclaimedGas(snapshot, UInt160.Zero, 10).Should().Be(new BigInteger(0)); - snapshot.Delete(key); + action = () => NativeContract.NEO.UnclaimedGas(clonedCache, UInt160.Zero, 10).Should().Be(new BigInteger(0)); + clonedCache.Delete(key); // Normal 1) votee is non exist - snapshot.GetAndChange(key, () => new StorageItem(new NeoAccountState + clonedCache.GetAndChange(key, () => new StorageItem(new NeoAccountState { Balance = 100 })); var storageKey = new KeyBuilder(NativeContract.Ledger.Id, 12); - var item = snapshot.GetAndChange(storageKey).GetInteroperable(); + var item = clonedCache.GetAndChange(storageKey).GetInteroperable(); item.Index = 99; - NativeContract.NEO.UnclaimedGas(snapshot, UInt160.Zero, 100).Should().Be(new BigInteger(0.5 * 100 * 100)); - snapshot.Delete(key); + NativeContract.NEO.UnclaimedGas(clonedCache, UInt160.Zero, 100).Should().Be(new BigInteger(0.5 * 100 * 100)); + clonedCache.Delete(key); // Normal 2) votee is not committee - snapshot.GetAndChange(key, () => new StorageItem(new NeoAccountState + clonedCache.GetAndChange(key, () => new StorageItem(new NeoAccountState { Balance = 100, VoteTo = ECCurve.Secp256r1.G })); - NativeContract.NEO.UnclaimedGas(snapshot, UInt160.Zero, 100).Should().Be(new BigInteger(0.5 * 100 * 100)); - snapshot.Delete(key); + NativeContract.NEO.UnclaimedGas(clonedCache, UInt160.Zero, 100).Should().Be(new BigInteger(0.5 * 100 * 100)); + clonedCache.Delete(key); // Normal 3) votee is committee - snapshot.GetAndChange(key, () => new StorageItem(new NeoAccountState + clonedCache.GetAndChange(key, () => new StorageItem(new NeoAccountState { Balance = 100, VoteTo = TestProtocolSettings.Default.StandbyCommittee[0] })); - snapshot.Add(new KeyBuilder(NativeContract.NEO.Id, 23).Add(TestProtocolSettings.Default.StandbyCommittee[0]).AddBigEndian(uint.MaxValue - 50), new StorageItem() { Value = new BigInteger(50 * 10000L).ToByteArray() }); - NativeContract.NEO.UnclaimedGas(snapshot, UInt160.Zero, 100).Should().Be(new BigInteger(50 * 100)); - snapshot.Delete(key); + clonedCache.Add(new KeyBuilder(NativeContract.NEO.Id, 23).Add(TestProtocolSettings.Default.StandbyCommittee[0]).AddBigEndian(uint.MaxValue - 50), new StorageItem() { Value = new BigInteger(50 * 10000L).ToByteArray() }); + NativeContract.NEO.UnclaimedGas(clonedCache, UInt160.Zero, 100).Should().Be(new BigInteger(50 * 100)); + clonedCache.Delete(key); } [TestMethod] public void TestGetNextBlockValidators1() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); - var result = (VM.Types.Array)NativeContract.NEO.Call(snapshot, "getNextBlockValidators"); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); + var result = (VM.Types.Array)NativeContract.NEO.Call(snapshotCache, "getNextBlockValidators"); result.Count.Should().Be(7); result[0].GetSpan().ToHexString().Should().Be("02486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a70"); result[1].GetSpan().ToHexString().Should().Be("024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d"); @@ -584,8 +584,8 @@ public void TestGetNextBlockValidators1() [TestMethod] public void TestGetNextBlockValidators2() { - var snapshot = _snapshot.CloneCache(); - var result = NativeContract.NEO.GetNextBlockValidators(snapshot, 7); + var clonedCache = _snapshotCache.CloneCache(); + var result = NativeContract.NEO.GetNextBlockValidators(clonedCache, 7); result.Length.Should().Be(7); result[0].ToArray().ToHexString().Should().Be("02486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a70"); result[1].ToArray().ToHexString().Should().Be("024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d"); @@ -599,40 +599,40 @@ public void TestGetNextBlockValidators2() [TestMethod] public void TestGetCandidates1() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); - var array = (VM.Types.Array)NativeContract.NEO.Call(snapshot, "getCandidates"); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); + var array = (VM.Types.Array)NativeContract.NEO.Call(snapshotCache, "getCandidates"); array.Count.Should().Be(0); } [TestMethod] public void TestGetCandidates2() { - var snapshot = _snapshot.CloneCache(); - var result = NativeContract.NEO.GetCandidatesInternal(snapshot); + var clonedCache = _snapshotCache.CloneCache(); + var result = NativeContract.NEO.GetCandidatesInternal(clonedCache); result.Count().Should().Be(0); StorageKey key = NativeContract.NEO.CreateStorageKey(33, ECCurve.Secp256r1.G); - snapshot.Add(key, new StorageItem(new CandidateState() { Registered = true })); - NativeContract.NEO.GetCandidatesInternal(snapshot).Count().Should().Be(1); + clonedCache.Add(key, new StorageItem(new CandidateState() { Registered = true })); + NativeContract.NEO.GetCandidatesInternal(clonedCache).Count().Should().Be(1); } [TestMethod] public void TestCheckCandidate() { - var snapshot = _snapshot.CloneCache(); - var committee = NativeContract.NEO.GetCommittee(snapshot); + var cloneCache = _snapshotCache.CloneCache(); + var committee = NativeContract.NEO.GetCommittee(cloneCache); var point = committee[0].EncodePoint(true); // Prepare Prefix_VoterRewardPerCommittee var storageKey = new KeyBuilder(NativeContract.NEO.Id, 23).Add(committee[0]); - snapshot.Add(storageKey, new StorageItem(new BigInteger(1000))); + cloneCache.Add(storageKey, new StorageItem(new BigInteger(1000))); // Prepare Candidate storageKey = new KeyBuilder(NativeContract.NEO.Id, 33).Add(committee[0]); - snapshot.Add(storageKey, new StorageItem(new CandidateState { Registered = true, Votes = BigInteger.One })); + cloneCache.Add(storageKey, new StorageItem(new CandidateState { Registered = true, Votes = BigInteger.One })); storageKey = new KeyBuilder(NativeContract.NEO.Id, 23).Add(committee[0]); - snapshot.Find(storageKey.ToArray()).ToArray().Length.Should().Be(1); + cloneCache.Find(storageKey.ToArray()).ToArray().Length.Should().Be(1); // Pre-persist var persistingBlock = new Block @@ -647,32 +647,32 @@ public void TestCheckCandidate() }, Transactions = Array.Empty() }; - Check_OnPersist(snapshot, persistingBlock).Should().BeTrue(); + Check_OnPersist(cloneCache, persistingBlock).Should().BeTrue(); // Clear votes storageKey = new KeyBuilder(NativeContract.NEO.Id, 33).Add(committee[0]); - snapshot.GetAndChange(storageKey).GetInteroperable().Votes = BigInteger.Zero; + cloneCache.GetAndChange(storageKey).GetInteroperable().Votes = BigInteger.Zero; // Unregister candidate, remove - var ret = Check_UnregisterCandidate(snapshot, point, persistingBlock); + var ret = Check_UnregisterCandidate(cloneCache, point, persistingBlock); ret.State.Should().BeTrue(); ret.Result.Should().BeTrue(); storageKey = new KeyBuilder(NativeContract.NEO.Id, 23).Add(committee[0]); - snapshot.Find(storageKey.ToArray()).ToArray().Length.Should().Be(0); + cloneCache.Find(storageKey.ToArray()).ToArray().Length.Should().Be(0); // Post-persist - Check_PostPersist(snapshot, persistingBlock).Should().BeTrue(); + Check_PostPersist(cloneCache, persistingBlock).Should().BeTrue(); storageKey = new KeyBuilder(NativeContract.NEO.Id, 23).Add(committee[0]); - snapshot.Find(storageKey.ToArray()).ToArray().Length.Should().Be(1); + cloneCache.Find(storageKey.ToArray()).ToArray().Length.Should().Be(1); } [TestMethod] public void TestGetCommittee() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); - var result = (VM.Types.Array)NativeContract.NEO.Call(snapshot, "getCommittee"); + var clonedCache = TestBlockchain.GetTestSnapshotCache(); + var result = (VM.Types.Array)NativeContract.NEO.Call(clonedCache, "getCommittee"); result.Count.Should().Be(21); result[0].GetSpan().ToHexString().Should().Be("020f2887f41474cfeb11fd262e982051c1541418137c02a0f4961af911045de639"); result[1].GetSpan().ToHexString().Should().Be("03204223f8c86b8cd5c89ef12e4f0dbb314172e9241e30c9ef2293790793537cf0"); @@ -700,8 +700,8 @@ public void TestGetCommittee() [TestMethod] public void TestGetValidators() { - var snapshot = _snapshot.CloneCache(); - var result = NativeContract.NEO.ComputeNextBlockValidators(snapshot, TestProtocolSettings.Default); + var clonedCache = _snapshotCache.CloneCache(); + var result = NativeContract.NEO.ComputeNextBlockValidators(clonedCache, TestProtocolSettings.Default); result[0].ToArray().ToHexString().Should().Be("02486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a70"); result[1].ToArray().ToHexString().Should().Be("024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d"); result[2].ToArray().ToHexString().Should().Be("02aaec38470f6aad0042c6e877cfd8087d2676b0f516fddd362801b9bd3936399e"); @@ -730,64 +730,64 @@ public void TestOnBalanceChanging() [TestMethod] public void TestTotalSupply() { - var snapshot = _snapshot.CloneCache(); - NativeContract.NEO.TotalSupply(snapshot).Should().Be(new BigInteger(100000000)); + var clonedCache = _snapshotCache.CloneCache(); + NativeContract.NEO.TotalSupply(clonedCache).Should().Be(new BigInteger(100000000)); } [TestMethod] public void TestEconomicParameter() { const byte Prefix_CurrentBlock = 12; - var snapshot = _snapshot.CloneCache(); + var clonedCache = _snapshotCache.CloneCache(); var persistingBlock = new Block { Header = new Header() }; - (BigInteger, bool) result = Check_GetGasPerBlock(snapshot, persistingBlock); + (BigInteger, bool) result = Check_GetGasPerBlock(clonedCache, persistingBlock); result.Item2.Should().BeTrue(); result.Item1.Should().Be(5 * NativeContract.GAS.Factor); persistingBlock = new Block { Header = new Header { Index = 10 } }; - (VM.Types.Boolean, bool) result1 = Check_SetGasPerBlock(snapshot, 10 * NativeContract.GAS.Factor, persistingBlock); + (VM.Types.Boolean, bool) result1 = Check_SetGasPerBlock(clonedCache, 10 * NativeContract.GAS.Factor, persistingBlock); result1.Item2.Should().BeTrue(); result1.Item1.GetBoolean().Should().BeTrue(); - var height = snapshot[NativeContract.Ledger.CreateStorageKey(Prefix_CurrentBlock)].GetInteroperable(); + var height = clonedCache[NativeContract.Ledger.CreateStorageKey(Prefix_CurrentBlock)].GetInteroperable(); height.Index = persistingBlock.Index + 1; - result = Check_GetGasPerBlock(snapshot, persistingBlock); + result = Check_GetGasPerBlock(clonedCache, persistingBlock); result.Item2.Should().BeTrue(); result.Item1.Should().Be(10 * NativeContract.GAS.Factor); // Check calculate bonus - StorageItem storage = snapshot.GetOrAdd(CreateStorageKey(20, UInt160.Zero.ToArray()), () => new StorageItem(new NeoAccountState())); + StorageItem storage = clonedCache.GetOrAdd(CreateStorageKey(20, UInt160.Zero.ToArray()), () => new StorageItem(new NeoAccountState())); NeoAccountState state = storage.GetInteroperable(); state.Balance = 1000; state.BalanceHeight = 0; height.Index = persistingBlock.Index + 1; - NativeContract.NEO.UnclaimedGas(snapshot, UInt160.Zero, persistingBlock.Index + 2).Should().Be(6500); + NativeContract.NEO.UnclaimedGas(clonedCache, UInt160.Zero, persistingBlock.Index + 2).Should().Be(6500); } [TestMethod] public void TestClaimGas() { - var snapshot = _snapshot.CloneCache(); + var clonedCache = _snapshotCache.CloneCache(); // Initialize block - snapshot.Add(CreateStorageKey(1), new StorageItem(new BigInteger(30000000))); + clonedCache.Add(CreateStorageKey(1), new StorageItem(new BigInteger(30000000))); ECPoint[] standbyCommittee = TestProtocolSettings.Default.StandbyCommittee.OrderBy(p => p).ToArray(); CachedCommittee cachedCommittee = new(); for (var i = 0; i < TestProtocolSettings.Default.CommitteeMembersCount; i++) { ECPoint member = standbyCommittee[i]; - snapshot.Add(new KeyBuilder(NativeContract.NEO.Id, 33).Add(member), new StorageItem(new CandidateState() + clonedCache.Add(new KeyBuilder(NativeContract.NEO.Id, 33).Add(member), new StorageItem(new CandidateState() { Registered = true, Votes = 200 * 10000 })); cachedCommittee.Add((member, 200 * 10000)); } - snapshot.GetOrAdd(new KeyBuilder(NativeContract.NEO.Id, 14), () => new StorageItem()).Value = BinarySerializer.Serialize(cachedCommittee.ToStackItem(null), ExecutionEngineLimits.Default); + clonedCache.GetOrAdd(new KeyBuilder(NativeContract.NEO.Id, 14), () => new StorageItem()).Value = BinarySerializer.Serialize(cachedCommittee.ToStackItem(null), ExecutionEngineLimits.Default); - var item = snapshot.GetAndChange(new KeyBuilder(NativeContract.NEO.Id, 1), () => new StorageItem()); + var item = clonedCache.GetAndChange(new KeyBuilder(NativeContract.NEO.Id, 1), () => new StorageItem()); item.Value = ((BigInteger)2100 * 10000L).ToByteArray(); var persistingBlock = new Block @@ -802,17 +802,17 @@ public void TestClaimGas() }, Transactions = Array.Empty() }; - Check_PostPersist(snapshot, persistingBlock).Should().BeTrue(); + Check_PostPersist(clonedCache, persistingBlock).Should().BeTrue(); var committee = TestProtocolSettings.Default.StandbyCommittee.OrderBy(p => p).ToArray(); var accountA = committee[0]; var accountB = committee[TestProtocolSettings.Default.CommitteeMembersCount - 1]; - NativeContract.NEO.BalanceOf(snapshot, Contract.CreateSignatureContract(accountA).ScriptHash).Should().Be(0); + NativeContract.NEO.BalanceOf(clonedCache, Contract.CreateSignatureContract(accountA).ScriptHash).Should().Be(0); - StorageItem storageItem = snapshot.TryGet(new KeyBuilder(NativeContract.NEO.Id, 23).Add(accountA)); + StorageItem storageItem = clonedCache.TryGet(new KeyBuilder(NativeContract.NEO.Id, 23).Add(accountA)); ((BigInteger)storageItem).Should().Be(30000000000); - snapshot.TryGet(new KeyBuilder(NativeContract.NEO.Id, 23).Add(accountB).AddBigEndian(uint.MaxValue - 1)).Should().BeNull(); + clonedCache.TryGet(new KeyBuilder(NativeContract.NEO.Id, 23).Add(accountB).AddBigEndian(uint.MaxValue - 1)).Should().BeNull(); // Next block @@ -828,11 +828,11 @@ public void TestClaimGas() }, Transactions = Array.Empty() }; - Check_PostPersist(snapshot, persistingBlock).Should().BeTrue(); + Check_PostPersist(clonedCache, persistingBlock).Should().BeTrue(); - NativeContract.NEO.BalanceOf(snapshot, Contract.CreateSignatureContract(committee[1]).ScriptHash).Should().Be(0); + NativeContract.NEO.BalanceOf(clonedCache, Contract.CreateSignatureContract(committee[1]).ScriptHash).Should().Be(0); - storageItem = snapshot.TryGet(new KeyBuilder(NativeContract.NEO.Id, 23).Add(committee[1])); + storageItem = clonedCache.TryGet(new KeyBuilder(NativeContract.NEO.Id, 23).Add(committee[1])); ((BigInteger)storageItem).Should().Be(30000000000); // Next block @@ -849,99 +849,99 @@ public void TestClaimGas() }, Transactions = Array.Empty() }; - Check_PostPersist(snapshot, persistingBlock).Should().BeTrue(); + Check_PostPersist(clonedCache, persistingBlock).Should().BeTrue(); accountA = TestProtocolSettings.Default.StandbyCommittee.OrderBy(p => p).ToArray()[2]; - NativeContract.NEO.BalanceOf(snapshot, Contract.CreateSignatureContract(committee[2]).ScriptHash).Should().Be(0); + NativeContract.NEO.BalanceOf(clonedCache, Contract.CreateSignatureContract(committee[2]).ScriptHash).Should().Be(0); - storageItem = snapshot.TryGet(new KeyBuilder(NativeContract.NEO.Id, 23).Add(committee[2])); + storageItem = clonedCache.TryGet(new KeyBuilder(NativeContract.NEO.Id, 23).Add(committee[2])); ((BigInteger)storageItem).Should().Be(30000000000 * 2); // Claim GAS var account = Contract.CreateSignatureContract(committee[2]).ScriptHash; - snapshot.Add(new KeyBuilder(NativeContract.NEO.Id, 20).Add(account), new StorageItem(new NeoAccountState + clonedCache.Add(new KeyBuilder(NativeContract.NEO.Id, 20).Add(account), new StorageItem(new NeoAccountState { BalanceHeight = 3, Balance = 200 * 10000 - 2 * 100, VoteTo = committee[2], LastGasPerVote = 30000000000, })); - NativeContract.NEO.BalanceOf(snapshot, account).Should().Be(1999800); + NativeContract.NEO.BalanceOf(clonedCache, account).Should().Be(1999800); var storageKey = new KeyBuilder(NativeContract.Ledger.Id, 12); - snapshot.GetAndChange(storageKey).GetInteroperable().Index = 29 + 2; - BigInteger value = NativeContract.NEO.UnclaimedGas(snapshot, account, 29 + 3); + clonedCache.GetAndChange(storageKey).GetInteroperable().Index = 29 + 2; + BigInteger value = NativeContract.NEO.UnclaimedGas(clonedCache, account, 29 + 3); value.Should().Be(1999800 * 30000000000 / 100000000L + (1999800L * 10 * 5 * 29 / 100)); } [TestMethod] public void TestUnclaimedGas() { - var snapshot = _snapshot.CloneCache(); - NativeContract.NEO.UnclaimedGas(snapshot, UInt160.Zero, 10).Should().Be(new BigInteger(0)); - snapshot.Add(CreateStorageKey(20, UInt160.Zero.ToArray()), new StorageItem(new NeoAccountState())); - NativeContract.NEO.UnclaimedGas(snapshot, UInt160.Zero, 10).Should().Be(new BigInteger(0)); + var clonedCache = _snapshotCache.CloneCache(); + NativeContract.NEO.UnclaimedGas(clonedCache, UInt160.Zero, 10).Should().Be(new BigInteger(0)); + clonedCache.Add(CreateStorageKey(20, UInt160.Zero.ToArray()), new StorageItem(new NeoAccountState())); + NativeContract.NEO.UnclaimedGas(clonedCache, UInt160.Zero, 10).Should().Be(new BigInteger(0)); } [TestMethod] public void TestVote() { - var snapshot = _snapshot.CloneCache(); + var clonedCache = _snapshotCache.CloneCache(); UInt160 account = UInt160.Parse("01ff00ff00ff00ff00ff00ff00ff00ff00ff00a4"); StorageKey keyAccount = CreateStorageKey(20, account.ToArray()); StorageKey keyValidator = CreateStorageKey(33, ECCurve.Secp256r1.G.ToArray()); _persistingBlock.Header.Index = 1; - var ret = Check_Vote(snapshot, account.ToArray(), ECCurve.Secp256r1.G.ToArray(), false, _persistingBlock); + var ret = Check_Vote(clonedCache, account.ToArray(), ECCurve.Secp256r1.G.ToArray(), false, _persistingBlock); ret.State.Should().BeTrue(); ret.Result.Should().BeFalse(); - ret = Check_Vote(snapshot, account.ToArray(), ECCurve.Secp256r1.G.ToArray(), true, _persistingBlock); + ret = Check_Vote(clonedCache, account.ToArray(), ECCurve.Secp256r1.G.ToArray(), true, _persistingBlock); ret.State.Should().BeTrue(); ret.Result.Should().BeFalse(); - snapshot.Add(keyAccount, new StorageItem(new NeoAccountState())); - ret = Check_Vote(snapshot, account.ToArray(), ECCurve.Secp256r1.G.ToArray(), true, _persistingBlock); + clonedCache.Add(keyAccount, new StorageItem(new NeoAccountState())); + ret = Check_Vote(clonedCache, account.ToArray(), ECCurve.Secp256r1.G.ToArray(), true, _persistingBlock); ret.State.Should().BeTrue(); ret.Result.Should().BeFalse(); - var (_, _, vote_to_null) = GetAccountState(snapshot, account); + var (_, _, vote_to_null) = GetAccountState(clonedCache, account); vote_to_null.Should().BeNull(); - snapshot.Delete(keyAccount); - snapshot.GetAndChange(keyAccount, () => new StorageItem(new NeoAccountState + clonedCache.Delete(keyAccount); + clonedCache.GetAndChange(keyAccount, () => new StorageItem(new NeoAccountState { Balance = 1, VoteTo = ECCurve.Secp256r1.G })); - snapshot.Add(keyValidator, new StorageItem(new CandidateState() { Registered = true })); - ret = Check_Vote(snapshot, account.ToArray(), ECCurve.Secp256r1.G.ToArray(), true, _persistingBlock); + clonedCache.Add(keyValidator, new StorageItem(new CandidateState() { Registered = true })); + ret = Check_Vote(clonedCache, account.ToArray(), ECCurve.Secp256r1.G.ToArray(), true, _persistingBlock); ret.State.Should().BeTrue(); ret.Result.Should().BeTrue(); - var (_, _, voteto) = GetAccountState(snapshot, account); + var (_, _, voteto) = GetAccountState(clonedCache, account); voteto.ToHexString().Should().Be(ECCurve.Secp256r1.G.ToArray().ToHexString()); } internal (bool State, bool Result) Transfer4TesingOnBalanceChanging(BigInteger amount, bool addVotes) { - var snapshot = _snapshot.CloneCache(); + var clonedCache = _snapshotCache.CloneCache(); _persistingBlock.Header.Index = 1; - var engine = ApplicationEngine.Create(TriggerType.Application, TestBlockchain.TheNeoSystem.GenesisBlock, snapshot, _persistingBlock, settings: TestBlockchain.TheNeoSystem.Settings); + var engine = ApplicationEngine.Create(TriggerType.Application, TestBlockchain.TheNeoSystem.GenesisBlock, clonedCache, _persistingBlock, settings: TestBlockchain.TheNeoSystem.Settings); ScriptBuilder sb = new(); - var tmp = engine.ScriptContainer.GetScriptHashesForVerifying(engine.Snapshot); - UInt160 from = engine.ScriptContainer.GetScriptHashesForVerifying(engine.Snapshot)[0]; + var tmp = engine.ScriptContainer.GetScriptHashesForVerifying(engine.SnapshotCache); + UInt160 from = engine.ScriptContainer.GetScriptHashesForVerifying(engine.SnapshotCache)[0]; if (addVotes) { - snapshot.Add(CreateStorageKey(20, from.ToArray()), new StorageItem(new NeoAccountState + clonedCache.Add(CreateStorageKey(20, from.ToArray()), new StorageItem(new NeoAccountState { VoteTo = ECCurve.Secp256r1.G, Balance = new BigInteger(1000) })); - snapshot.Add(NativeContract.NEO.CreateStorageKey(33, ECCurve.Secp256r1.G), new StorageItem(new CandidateState())); + clonedCache.Add(NativeContract.NEO.CreateStorageKey(33, ECCurve.Secp256r1.G), new StorageItem(new CandidateState())); } else { - snapshot.Add(CreateStorageKey(20, from.ToArray()), new StorageItem(new NeoAccountState + clonedCache.Add(CreateStorageKey(20, from.ToArray()), new StorageItem(new NeoAccountState { Balance = new BigInteger(1000) })); @@ -956,29 +956,29 @@ public void TestVote() return (true, result.GetBoolean()); } - internal static bool Check_OnPersist(DataCache snapshot, Block persistingBlock) + internal static bool Check_OnPersist(DataCache clonedCache, Block persistingBlock) { var script = new ScriptBuilder(); script.EmitSysCall(ApplicationEngine.System_Contract_NativeOnPersist); - var engine = ApplicationEngine.Create(TriggerType.OnPersist, null, snapshot, persistingBlock, settings: TestBlockchain.TheNeoSystem.Settings); + var engine = ApplicationEngine.Create(TriggerType.OnPersist, null, clonedCache, persistingBlock, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); return engine.Execute() == VMState.HALT; } - internal static bool Check_PostPersist(DataCache snapshot, Block persistingBlock) + internal static bool Check_PostPersist(DataCache clonedCache, Block persistingBlock) { using var script = new ScriptBuilder(); script.EmitSysCall(ApplicationEngine.System_Contract_NativePostPersist); - using var engine = ApplicationEngine.Create(TriggerType.PostPersist, null, snapshot, persistingBlock, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.PostPersist, null, clonedCache, persistingBlock, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); return engine.Execute() == VMState.HALT; } - internal static (BigInteger Value, bool State) Check_GetGasPerBlock(DataCache snapshot, Block persistingBlock) + internal static (BigInteger Value, bool State) Check_GetGasPerBlock(DataCache clonedCache, Block persistingBlock) { - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, persistingBlock, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, clonedCache, persistingBlock, settings: TestBlockchain.TheNeoSystem.Settings); using var script = new ScriptBuilder(); script.EmitDynamicCall(NativeContract.NEO.Hash, "getGasPerBlock"); @@ -995,10 +995,10 @@ internal static (BigInteger Value, bool State) Check_GetGasPerBlock(DataCache sn return (((VM.Types.Integer)result).GetInteger(), true); } - internal static (VM.Types.Boolean Value, bool State) Check_SetGasPerBlock(DataCache snapshot, BigInteger gasPerBlock, Block persistingBlock) + internal static (VM.Types.Boolean Value, bool State) Check_SetGasPerBlock(DataCache clonedCache, BigInteger gasPerBlock, Block persistingBlock) { - UInt160 committeeMultiSigAddr = NativeContract.NEO.GetCommitteeAddress(snapshot); - using var engine = ApplicationEngine.Create(TriggerType.Application, new Nep17NativeContractExtensions.ManualWitness(committeeMultiSigAddr), snapshot, persistingBlock, settings: TestBlockchain.TheNeoSystem.Settings); + UInt160 committeeMultiSigAddr = NativeContract.NEO.GetCommitteeAddress(clonedCache); + using var engine = ApplicationEngine.Create(TriggerType.Application, new Nep17NativeContractExtensions.ManualWitness(committeeMultiSigAddr), clonedCache, persistingBlock, settings: TestBlockchain.TheNeoSystem.Settings); var script = new ScriptBuilder(); script.EmitDynamicCall(NativeContract.NEO.Hash, "setGasPerBlock", gasPerBlock); @@ -1012,10 +1012,10 @@ internal static (VM.Types.Boolean Value, bool State) Check_SetGasPerBlock(DataCa return (true, true); } - internal static (bool State, bool Result) Check_Vote(DataCache snapshot, byte[] account, byte[] pubkey, bool signAccount, Block persistingBlock) + internal static (bool State, bool Result) Check_Vote(DataCache clonedCache, byte[] account, byte[] pubkey, bool signAccount, Block persistingBlock) { using var engine = ApplicationEngine.Create(TriggerType.Application, - new Nep17NativeContractExtensions.ManualWitness(signAccount ? new UInt160(account) : UInt160.Zero), snapshot, persistingBlock, settings: TestBlockchain.TheNeoSystem.Settings); + new Nep17NativeContractExtensions.ManualWitness(signAccount ? new UInt160(account) : UInt160.Zero), clonedCache, persistingBlock, settings: TestBlockchain.TheNeoSystem.Settings); using var script = new ScriptBuilder(); script.EmitDynamicCall(NativeContract.NEO.Hash, "vote", account, pubkey); @@ -1033,10 +1033,10 @@ internal static (bool State, bool Result) Check_Vote(DataCache snapshot, byte[] return (true, result.GetBoolean()); } - internal static (bool State, bool Result) Check_RegisterValidator(DataCache snapshot, byte[] pubkey, Block persistingBlock) + internal static (bool State, bool Result) Check_RegisterValidator(DataCache clonedCache, byte[] pubkey, Block persistingBlock) { using var engine = ApplicationEngine.Create(TriggerType.Application, - new Nep17NativeContractExtensions.ManualWitness(Contract.CreateSignatureRedeemScript(ECPoint.DecodePoint(pubkey, ECCurve.Secp256r1)).ToScriptHash()), snapshot, persistingBlock, settings: TestBlockchain.TheNeoSystem.Settings, gas: 1100_00000000); + new Nep17NativeContractExtensions.ManualWitness(Contract.CreateSignatureRedeemScript(ECPoint.DecodePoint(pubkey, ECCurve.Secp256r1)).ToScriptHash()), clonedCache, persistingBlock, settings: TestBlockchain.TheNeoSystem.Settings, gas: 1100_00000000); using var script = new ScriptBuilder(); script.EmitDynamicCall(NativeContract.NEO.Hash, "registerCandidate", pubkey); @@ -1053,9 +1053,9 @@ internal static (bool State, bool Result) Check_RegisterValidator(DataCache snap return (true, result.GetBoolean()); } - internal static ECPoint[] Check_GetCommittee(DataCache snapshot, Block persistingBlock) + internal static ECPoint[] Check_GetCommittee(DataCache clonedCache, Block persistingBlock) { - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, persistingBlock, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, clonedCache, persistingBlock, settings: TestBlockchain.TheNeoSystem.Settings); using var script = new ScriptBuilder(); script.EmitDynamicCall(NativeContract.NEO.Hash, "getCommittee"); @@ -1069,9 +1069,9 @@ internal static ECPoint[] Check_GetCommittee(DataCache snapshot, Block persistin return (result as VM.Types.Array).Select(u => ECPoint.DecodePoint(u.GetSpan(), ECCurve.Secp256r1)).ToArray(); } - internal static (BigInteger Value, bool State) Check_UnclaimedGas(DataCache snapshot, byte[] address, Block persistingBlock) + internal static (BigInteger Value, bool State) Check_UnclaimedGas(DataCache clonedCache, byte[] address, Block persistingBlock) { - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, persistingBlock, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, clonedCache, persistingBlock, settings: TestBlockchain.TheNeoSystem.Settings); using var script = new ScriptBuilder(); script.EmitDynamicCall(NativeContract.NEO.Hash, "unclaimedGas", address, persistingBlock.Index); @@ -1123,10 +1123,10 @@ internal static StorageKey CreateStorageKey(byte prefix, byte[] key = null) }; } - internal static (bool State, bool Result) Check_UnregisterCandidate(DataCache snapshot, byte[] pubkey, Block persistingBlock) + internal static (bool State, bool Result) Check_UnregisterCandidate(DataCache clonedCache, byte[] pubkey, Block persistingBlock) { using var engine = ApplicationEngine.Create(TriggerType.Application, - new Nep17NativeContractExtensions.ManualWitness(Contract.CreateSignatureRedeemScript(ECPoint.DecodePoint(pubkey, ECCurve.Secp256r1)).ToScriptHash()), snapshot, persistingBlock, settings: TestBlockchain.TheNeoSystem.Settings); + new Nep17NativeContractExtensions.ManualWitness(Contract.CreateSignatureRedeemScript(ECPoint.DecodePoint(pubkey, ECCurve.Secp256r1)).ToScriptHash()), clonedCache, persistingBlock, settings: TestBlockchain.TheNeoSystem.Settings); using var script = new ScriptBuilder(); script.EmitDynamicCall(NativeContract.NEO.Hash, "unregisterCandidate", pubkey); @@ -1143,9 +1143,9 @@ internal static (bool State, bool Result) Check_UnregisterCandidate(DataCache sn return (true, result.GetBoolean()); } - internal static (BigInteger balance, BigInteger height, byte[] voteto) GetAccountState(DataCache snapshot, UInt160 account) + internal static (BigInteger balance, BigInteger height, byte[] voteto) GetAccountState(DataCache clonedCache, UInt160 account) { - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, clonedCache, settings: TestBlockchain.TheNeoSystem.Settings); using var script = new ScriptBuilder(); script.EmitDynamicCall(NativeContract.NEO.Hash, "getAccountState", account); diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs index 62052ad4bf..745670977e 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs @@ -26,21 +26,21 @@ namespace Neo.UnitTests.SmartContract.Native [TestClass] public class UT_PolicyContract { - private DataCache _snapshot; + private DataCache _snapshotCache; [TestInitialize] public void TestSetup() { - _snapshot = TestBlockchain.GetTestSnapshotCache(); + _snapshotCache = TestBlockchain.GetTestSnapshotCache(); - ApplicationEngine engine = ApplicationEngine.Create(TriggerType.OnPersist, null, _snapshot, new Block { Header = new Header() }, settings: TestBlockchain.TheNeoSystem.Settings, gas: 0); + ApplicationEngine engine = ApplicationEngine.Create(TriggerType.OnPersist, null, _snapshotCache, new Block { Header = new Header() }, settings: TestBlockchain.TheNeoSystem.Settings, gas: 0); NativeContract.ContractManagement.OnPersistAsync(engine); } [TestMethod] public void Check_Default() { - var snapshot = _snapshot.CloneCache(); + var snapshot = _snapshotCache.CloneCache(); var ret = NativeContract.Policy.Call(snapshot, "getFeePerByte"); ret.Should().BeOfType(); @@ -56,7 +56,7 @@ public void Check_Default() [TestMethod] public void Check_SetAttributeFee() { - var snapshot = _snapshot.CloneCache(); + var snapshot = _snapshotCache.CloneCache(); // Fake blockchain Block block = new() @@ -115,7 +115,7 @@ public void Check_SetAttributeFee() [TestMethod] public void Check_SetFeePerByte() { - var snapshot = _snapshot.CloneCache(); + var snapshot = _snapshotCache.CloneCache(); // Fake blockchain @@ -154,7 +154,7 @@ public void Check_SetFeePerByte() [TestMethod] public void Check_SetBaseExecFee() { - var snapshot = _snapshot.CloneCache(); + var snapshot = _snapshotCache.CloneCache(); // Fake blockchain @@ -204,7 +204,7 @@ public void Check_SetBaseExecFee() [TestMethod] public void Check_SetStoragePrice() { - var snapshot = _snapshot.CloneCache(); + var snapshot = _snapshotCache.CloneCache(); // Fake blockchain @@ -254,7 +254,7 @@ public void Check_SetStoragePrice() [TestMethod] public void Check_BlockAccount() { - var snapshot = _snapshot.CloneCache(); + var snapshot = _snapshotCache.CloneCache(); // Fake blockchain @@ -310,7 +310,7 @@ public void Check_BlockAccount() [TestMethod] public void Check_Block_UnblockAccount() { - var snapshot = _snapshot.CloneCache(); + var snapshot = _snapshotCache.CloneCache(); // Fake blockchain diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_RoleManagement.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_RoleManagement.cs index 1fbb2a47a0..ad3cb4b6c8 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_RoleManagement.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_RoleManagement.cs @@ -29,12 +29,12 @@ namespace Neo.UnitTests.SmartContract.Native [TestClass] public class UT_RoleManagement { - private DataCache _snapshot; + private DataCache _snapshotCache; [TestInitialize] public void TestSetup() { - _snapshot = TestBlockchain.GetTestSnapshotCache(); + _snapshotCache = TestBlockchain.GetTestSnapshotCache(); } [TestCleanup] @@ -62,7 +62,7 @@ public void TestSetAndGet() List roles = new List() { Role.StateValidator, Role.Oracle, Role.NeoFSAlphabetNode, Role.P2PNotary }; foreach (var role in roles) { - var snapshot1 = _snapshot.CloneCache(); + var snapshot1 = _snapshotCache.CloneCache(); UInt160 committeeMultiSigAddr = NativeContract.NEO.GetCommitteeAddress(snapshot1); List notifications = new List(); EventHandler ev = (o, e) => notifications.Add(e); @@ -79,7 +79,7 @@ public void TestSetAndGet() ApplicationEngine.Notify -= ev; notifications.Count.Should().Be(1); notifications[0].EventName.Should().Be("Designation"); - var snapshot2 = _snapshot.CloneCache(); + var snapshot2 = _snapshotCache.CloneCache(); ret = NativeContract.RoleManagement.Call( snapshot2, "getDesignatedByRole", diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_StdLib.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_StdLib.cs index 28835aa55e..a13d2659ce 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_StdLib.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_StdLib.cs @@ -62,7 +62,7 @@ public void TestItoaAtoi() [TestMethod] public void MemoryCompare() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); using (var script = new ScriptBuilder()) { @@ -71,7 +71,7 @@ public void MemoryCompare() script.EmitDynamicCall(NativeContract.StdLib.Hash, "memoryCompare", "abc", "abc"); script.EmitDynamicCall(NativeContract.StdLib.Hash, "memoryCompare", "abc", "abcd"); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(engine.Execute(), VMState.HALT); @@ -87,13 +87,13 @@ public void MemoryCompare() [TestMethod] public void CheckDecodeEncode() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); using (ScriptBuilder script = new()) { script.EmitDynamicCall(NativeContract.StdLib.Hash, "base58CheckEncode", new byte[] { 1, 2, 3 }); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(engine.Execute(), VMState.HALT); @@ -106,7 +106,7 @@ public void CheckDecodeEncode() { script.EmitDynamicCall(NativeContract.StdLib.Hash, "base58CheckDecode", "3DUz7ncyT"); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(engine.Execute(), VMState.HALT); @@ -121,7 +121,7 @@ public void CheckDecodeEncode() { script.EmitDynamicCall(NativeContract.StdLib.Hash, "base58CheckDecode", "AA"); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(engine.Execute(), VMState.FAULT); @@ -131,7 +131,7 @@ public void CheckDecodeEncode() { script.EmitDynamicCall(NativeContract.StdLib.Hash, "base58CheckDecode", null); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(engine.Execute(), VMState.FAULT); @@ -141,7 +141,7 @@ public void CheckDecodeEncode() [TestMethod] public void MemorySearch() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); using (var script = new ScriptBuilder()) { @@ -151,7 +151,7 @@ public void MemorySearch() script.EmitDynamicCall(NativeContract.StdLib.Hash, "memorySearch", "abc", "c", 3); script.EmitDynamicCall(NativeContract.StdLib.Hash, "memorySearch", "abc", "d", 0); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(engine.Execute(), VMState.HALT); @@ -171,7 +171,7 @@ public void MemorySearch() script.EmitDynamicCall(NativeContract.StdLib.Hash, "memorySearch", "abc", "c", 3, false); script.EmitDynamicCall(NativeContract.StdLib.Hash, "memorySearch", "abc", "d", 0, false); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(engine.Execute(), VMState.HALT); @@ -191,7 +191,7 @@ public void MemorySearch() script.EmitDynamicCall(NativeContract.StdLib.Hash, "memorySearch", "abc", "c", 3, true); script.EmitDynamicCall(NativeContract.StdLib.Hash, "memorySearch", "abc", "d", 0, true); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(engine.Execute(), VMState.HALT); @@ -207,12 +207,12 @@ public void MemorySearch() [TestMethod] public void StringSplit() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); using var script = new ScriptBuilder(); script.EmitDynamicCall(NativeContract.StdLib.Hash, "stringSplit", "a,b", ","); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(engine.Execute(), VMState.HALT); @@ -227,14 +227,14 @@ public void StringSplit() [TestMethod] public void StringElementLength() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); using var script = new ScriptBuilder(); script.EmitDynamicCall(NativeContract.StdLib.Hash, "strLen", "🦆"); script.EmitDynamicCall(NativeContract.StdLib.Hash, "strLen", "ã"); script.EmitDynamicCall(NativeContract.StdLib.Hash, "strLen", "a"); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(engine.Execute(), VMState.HALT); @@ -250,13 +250,13 @@ public void TestInvalidUtf8Sequence() // Simulating invalid UTF-8 byte (0xff) decoded as a UTF-16 char const char badChar = (char)0xff; var badStr = badChar.ToString(); - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); using var script = new ScriptBuilder(); script.EmitDynamicCall(NativeContract.StdLib.Hash, "strLen", badStr); script.EmitDynamicCall(NativeContract.StdLib.Hash, "strLen", badStr + "ab"); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(engine.Execute(), VMState.HALT); @@ -268,7 +268,7 @@ public void TestInvalidUtf8Sequence() [TestMethod] public void Json_Deserialize() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); // Good @@ -277,7 +277,7 @@ public void Json_Deserialize() script.EmitDynamicCall(NativeContract.StdLib.Hash, "jsonDeserialize", "123"); script.EmitDynamicCall(NativeContract.StdLib.Hash, "jsonDeserialize", "null"); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(engine.Execute(), VMState.HALT); @@ -293,7 +293,7 @@ public void Json_Deserialize() { script.EmitDynamicCall(NativeContract.StdLib.Hash, "jsonDeserialize", "***"); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(engine.Execute(), VMState.FAULT); @@ -306,7 +306,7 @@ public void Json_Deserialize() { script.EmitDynamicCall(NativeContract.StdLib.Hash, "jsonDeserialize", "123.45"); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(engine.Execute(), VMState.FAULT); @@ -317,7 +317,7 @@ public void Json_Deserialize() [TestMethod] public void Json_Serialize() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); // Good @@ -337,7 +337,7 @@ public void Json_Serialize() } }); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(engine.Execute(), VMState.HALT); @@ -356,7 +356,7 @@ public void Json_Serialize() { script.EmitDynamicCall(NativeContract.StdLib.Hash, "jsonSerialize"); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(engine.Execute(), VMState.FAULT); @@ -367,7 +367,7 @@ public void Json_Serialize() [TestMethod] public void TestRuntime_Serialize() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); // Good @@ -375,7 +375,7 @@ public void TestRuntime_Serialize() script.EmitDynamicCall(NativeContract.StdLib.Hash, "serialize", 100); script.EmitDynamicCall(NativeContract.StdLib.Hash, "serialize", "test"); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(engine.Execute(), VMState.HALT); @@ -388,7 +388,7 @@ public void TestRuntime_Serialize() [TestMethod] public void TestRuntime_Deserialize() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); // Good @@ -396,7 +396,7 @@ public void TestRuntime_Deserialize() script.EmitDynamicCall(NativeContract.StdLib.Hash, "deserialize", "280474657374".HexToBytes()); script.EmitDynamicCall(NativeContract.StdLib.Hash, "deserialize", "210164".HexToBytes()); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(engine.Execute(), VMState.HALT); diff --git a/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.cs b/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.cs index 9a150c2b22..a670e3b4b7 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.cs @@ -30,8 +30,8 @@ public partial class UT_ApplicationEngine [TestMethod] public void TestNotify() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); - using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(System.Array.Empty()); ApplicationEngine.Notify += Test_Notify1; const string notifyEvent = "TestEvent"; @@ -66,9 +66,9 @@ private void Test_Notify2(object sender, NotifyEventArgs e) [TestMethod] public void TestCreateDummyBlock() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); byte[] SyscallSystemRuntimeCheckWitnessHash = new byte[] { 0x68, 0xf8, 0x27, 0xec, 0x8c }; - ApplicationEngine engine = ApplicationEngine.Run(SyscallSystemRuntimeCheckWitnessHash, snapshot, settings: TestProtocolSettings.Default); + ApplicationEngine engine = ApplicationEngine.Run(SyscallSystemRuntimeCheckWitnessHash, snapshotCache, settings: TestProtocolSettings.Default); engine.PersistingBlock.Version.Should().Be(0); engine.PersistingBlock.PrevHash.Should().Be(TestBlockchain.TheNeoSystem.GenesisBlock.Hash); engine.PersistingBlock.MerkleRoot.Should().Be(new UInt256()); @@ -111,7 +111,7 @@ public void TestCheckingHardfork() public void TestSystem_Contract_Call_Permissions() { UInt160 scriptHash; - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); // Setup: put a simple contract to the storage. using (var script = new ScriptBuilder()) @@ -123,7 +123,7 @@ public void TestSystem_Contract_Call_Permissions() // Mock contract and put it to the Managemant's storage. scriptHash = script.ToArray().ToScriptHash(); - snapshot.DeleteContract(scriptHash); + snapshotCache.DeleteContract(scriptHash); var contract = TestUtils.GetContract(script.ToArray(), TestUtils.CreateManifest("test", ContractParameterType.Any)); contract.Manifest.Abi.Methods = new[] { @@ -138,11 +138,11 @@ public void TestSystem_Contract_Call_Permissions() Parameters = new ContractParameterDefinition[]{} } }; - snapshot.AddContract(scriptHash, contract); + snapshotCache.AddContract(scriptHash, contract); } // Disallowed method call. - using (var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, null, ProtocolSettings.Default)) + using (var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, null, ProtocolSettings.Default)) using (var script = new ScriptBuilder()) { // Build call script calling disallowed method. @@ -172,7 +172,7 @@ public void TestSystem_Contract_Call_Permissions() } // Allowed method call. - using (var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, null, ProtocolSettings.Default)) + using (var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, null, ProtocolSettings.Default)) using (var script = new ScriptBuilder()) { // Build call script. diff --git a/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngineProvider.cs b/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngineProvider.cs index 75fc558669..1d9da111e1 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngineProvider.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngineProvider.cs @@ -59,8 +59,8 @@ public ApplicationEngine Create(TriggerType trigger, IVerifiable container, Data class TestEngine : ApplicationEngine { - public TestEngine(TriggerType trigger, IVerifiable container, DataCache snapshot, Block persistingBlock, ProtocolSettings settings, long gas, IDiagnostic diagnostic, JumpTable jumpTable) - : base(trigger, container, snapshot, persistingBlock, settings, gas, diagnostic, jumpTable) + public TestEngine(TriggerType trigger, IVerifiable container, DataCache snapshotCache, Block persistingBlock, ProtocolSettings settings, long gas, IDiagnostic diagnostic, JumpTable jumpTable) + : base(trigger, container, snapshotCache, persistingBlock, settings, gas, diagnostic, jumpTable) { } } diff --git a/tests/Neo.UnitTests/SmartContract/UT_ContractParameterContext.cs b/tests/Neo.UnitTests/SmartContract/UT_ContractParameterContext.cs index 8d22a0391c..9523c41be4 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_ContractParameterContext.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_ContractParameterContext.cs @@ -43,18 +43,18 @@ public static void ClassSetUp(TestContext ctx) [TestMethod] public void TestGetComplete() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); Transaction tx = TestUtils.GetTransaction(UInt160.Parse("0x1bd5c777ec35768892bd3daab60fb7a1cb905066")); - var context = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network); + var context = new ContractParametersContext(snapshotCache, tx, TestProtocolSettings.Default.Network); context.Completed.Should().BeFalse(); } [TestMethod] public void TestToString() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); Transaction tx = TestUtils.GetTransaction(UInt160.Parse("0x1bd5c777ec35768892bd3daab60fb7a1cb905066")); - var context = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network); + var context = new ContractParametersContext(snapshotCache, tx, TestProtocolSettings.Default.Network); context.Add(contract, 0, new byte[] { 0x01 }); string str = context.ToString(); str.Should().Be(@"{""type"":""Neo.Network.P2P.Payloads.Transaction"",""hash"":""0x602c1fa1c08b041e4e6b87aa9a9f9c643166cd34bdd5215a3dd85778c59cce88"",""data"":""AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFmUJDLobcPtqo9vZKIdjXsd8fVGwEAARI="",""items"":{},""network"":" + TestProtocolSettings.Default.Network + "}"); @@ -63,8 +63,8 @@ public void TestToString() [TestMethod] public void TestParse() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); - var ret = ContractParametersContext.Parse("{\"type\":\"Neo.Network.P2P.Payloads.Transaction\",\"data\":\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFmUJDLobcPtqo9vZKIdjXsd8fVGwEAARI=\",\"items\":{\"0xbecaad15c0ea585211faf99738a4354014f177f2\":{\"script\":\"IQJv8DuUkkHOHa3UNRnmlg4KhbQaaaBcMoEDqivOFZTKFmh0dHaq\",\"parameters\":[{\"type\":\"Signature\",\"value\":\"AQ==\"}],\"signatures\":{\"03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c\":\"AQ==\"}}},\"network\":" + TestProtocolSettings.Default.Network + "}", snapshot); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); + var ret = ContractParametersContext.Parse("{\"type\":\"Neo.Network.P2P.Payloads.Transaction\",\"data\":\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFmUJDLobcPtqo9vZKIdjXsd8fVGwEAARI=\",\"items\":{\"0xbecaad15c0ea585211faf99738a4354014f177f2\":{\"script\":\"IQJv8DuUkkHOHa3UNRnmlg4KhbQaaaBcMoEDqivOFZTKFmh0dHaq\",\"parameters\":[{\"type\":\"Signature\",\"value\":\"AQ==\"}],\"signatures\":{\"03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c\":\"AQ==\"}}},\"network\":" + TestProtocolSettings.Default.Network + "}", snapshotCache); ret.ScriptHashes[0].ToString().Should().Be("0x1bd5c777ec35768892bd3daab60fb7a1cb905066"); ((Transaction)ret.Verifiable).Script.Span.ToHexString().Should().Be(new byte[] { 18 }.ToHexString()); } @@ -72,21 +72,21 @@ public void TestParse() [TestMethod] public void TestFromJson() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); - Action action = () => ContractParametersContext.Parse("{\"type\":\"wrongType\",\"data\":\"00000000007c97764845172d827d3c863743293931a691271a0000000000000000000000000000000000000000000100\",\"items\":{\"0x1bd5c777ec35768892bd3daab60fb7a1cb905066\":{\"script\":\"21026ff03b949241ce1dadd43519e6960e0a85b41a69a05c328103aa2bce1594ca1650680a906ad4\",\"parameters\":[{\"type\":\"Signature\",\"value\":\"01\"}]}}}", snapshot); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); + Action action = () => ContractParametersContext.Parse("{\"type\":\"wrongType\",\"data\":\"00000000007c97764845172d827d3c863743293931a691271a0000000000000000000000000000000000000000000100\",\"items\":{\"0x1bd5c777ec35768892bd3daab60fb7a1cb905066\":{\"script\":\"21026ff03b949241ce1dadd43519e6960e0a85b41a69a05c328103aa2bce1594ca1650680a906ad4\",\"parameters\":[{\"type\":\"Signature\",\"value\":\"01\"}]}}}", snapshotCache); action.Should().Throw(); } [TestMethod] public void TestAdd() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); Transaction tx = TestUtils.GetTransaction(UInt160.Zero); - var context1 = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network); + var context1 = new ContractParametersContext(snapshotCache, tx, TestProtocolSettings.Default.Network); context1.Add(contract, 0, new byte[] { 0x01 }).Should().BeFalse(); tx = TestUtils.GetTransaction(UInt160.Parse("0x902e0d38da5e513b6d07c1c55b85e77d3dce8063")); - var context2 = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network); + var context2 = new ContractParametersContext(snapshotCache, tx, TestProtocolSettings.Default.Network); context2.Add(contract, 0, new byte[] { 0x01 }).Should().BeTrue(); //test repeatlly createItem context2.Add(contract, 0, new byte[] { 0x01 }).Should().BeTrue(); @@ -95,9 +95,9 @@ public void TestAdd() [TestMethod] public void TestGetParameter() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); Transaction tx = TestUtils.GetTransaction(UInt160.Parse("0x902e0d38da5e513b6d07c1c55b85e77d3dce8063")); - var context = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network); + var context = new ContractParametersContext(snapshotCache, tx, TestProtocolSettings.Default.Network); context.GetParameter(tx.Sender, 0).Should().BeNull(); context.Add(contract, 0, new byte[] { 0x01 }); @@ -108,9 +108,9 @@ public void TestGetParameter() [TestMethod] public void TestGetWitnesses() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); Transaction tx = TestUtils.GetTransaction(UInt160.Parse("0x902e0d38da5e513b6d07c1c55b85e77d3dce8063")); - var context = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network); + var context = new ContractParametersContext(snapshotCache, tx, TestProtocolSettings.Default.Network); context.Add(contract, 0, new byte[] { 0x01 }); Witness[] witnesses = context.GetWitnesses(); witnesses.Length.Should().Be(1); @@ -121,18 +121,18 @@ public void TestGetWitnesses() [TestMethod] public void TestAddSignature() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var singleSender = UInt160.Parse("0x902e0d38da5e513b6d07c1c55b85e77d3dce8063"); Transaction tx = TestUtils.GetTransaction(singleSender); //singleSign - var context = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network); + var context = new ContractParametersContext(snapshotCache, tx, TestProtocolSettings.Default.Network); context.AddSignature(contract, key.PublicKey, new byte[] { 0x01 }).Should().BeTrue(); var contract1 = Contract.CreateSignatureContract(key.PublicKey); contract1.ParameterList = Array.Empty(); - context = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network); + context = new ContractParametersContext(snapshotCache, tx, TestProtocolSettings.Default.Network); context.AddSignature(contract1, key.PublicKey, new byte[] { 0x01 }).Should().BeFalse(); contract1.ParameterList = new[] { ContractParameterType.Signature, ContractParameterType.Signature }; @@ -154,16 +154,16 @@ public void TestAddSignature() }); var multiSender = UInt160.Parse("0xf76b51bc6605ac3cfcd188173af0930507f51210"); tx = TestUtils.GetTransaction(multiSender); - context = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network); + context = new ContractParametersContext(snapshotCache, tx, TestProtocolSettings.Default.Network); context.AddSignature(multiSignContract, key.PublicKey, new byte[] { 0x01 }).Should().BeTrue(); context.AddSignature(multiSignContract, key2.PublicKey, new byte[] { 0x01 }).Should().BeTrue(); tx = TestUtils.GetTransaction(singleSender); - context = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network); + context = new ContractParametersContext(snapshotCache, tx, TestProtocolSettings.Default.Network); context.AddSignature(multiSignContract, key.PublicKey, new byte[] { 0x01 }).Should().BeFalse(); tx = TestUtils.GetTransaction(multiSender); - context = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network); + context = new ContractParametersContext(snapshotCache, tx, TestProtocolSettings.Default.Network); byte[] privateKey3 = new byte[] { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, diff --git a/tests/Neo.UnitTests/SmartContract/UT_InteropPrices.cs b/tests/Neo.UnitTests/SmartContract/UT_InteropPrices.cs index fff5ef1877..dfc685f335 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_InteropPrices.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_InteropPrices.cs @@ -64,11 +64,11 @@ public void ApplicationEngineRegularPut() StorageKey skey = TestUtils.GetStorageKey(contractState.Id, key); StorageItem sItem = TestUtils.GetStorageItem(System.Array.Empty()); - var snapshot = TestBlockchain.GetTestSnapshotCache(); - snapshot.Add(skey, sItem); - snapshot.AddContract(script.ToScriptHash(), contractState); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); + snapshotCache.Add(skey, sItem); + snapshotCache.AddContract(script.ToScriptHash(), contractState); - using ApplicationEngine ae = ApplicationEngine.Create(TriggerType.Application, null, snapshot); + using ApplicationEngine ae = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache); Debugger debugger = new(ae); ae.LoadScript(script); debugger.StepInto(); @@ -95,11 +95,11 @@ public void ApplicationEngineReusedStorage_FullReuse() StorageKey skey = TestUtils.GetStorageKey(contractState.Id, key); StorageItem sItem = TestUtils.GetStorageItem(value); - var snapshot = TestBlockchain.GetTestSnapshotCache(); - snapshot.Add(skey, sItem); - snapshot.AddContract(script.ToScriptHash(), contractState); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); + snapshotCache.Add(skey, sItem); + snapshotCache.AddContract(script.ToScriptHash(), contractState); - using ApplicationEngine applicationEngine = ApplicationEngine.Create(TriggerType.Application, null, snapshot); + using ApplicationEngine applicationEngine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache); Debugger debugger = new(applicationEngine); applicationEngine.LoadScript(script); debugger.StepInto(); @@ -128,11 +128,11 @@ public void ApplicationEngineReusedStorage_PartialReuse() StorageKey skey = TestUtils.GetStorageKey(contractState.Id, key); StorageItem sItem = TestUtils.GetStorageItem(oldValue); - var snapshot = TestBlockchain.GetTestSnapshotCache(); - snapshot.Add(skey, sItem); - snapshot.AddContract(script.ToScriptHash(), contractState); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); + snapshotCache.Add(skey, sItem); + snapshotCache.AddContract(script.ToScriptHash(), contractState); - using ApplicationEngine ae = ApplicationEngine.Create(TriggerType.Application, null, snapshot); + using ApplicationEngine ae = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache); Debugger debugger = new(ae); ae.LoadScript(script); debugger.StepInto(); @@ -162,11 +162,11 @@ public void ApplicationEngineReusedStorage_PartialReuseTwice() StorageKey skey = TestUtils.GetStorageKey(contractState.Id, key); StorageItem sItem = TestUtils.GetStorageItem(oldValue); - var snapshot = TestBlockchain.GetTestSnapshotCache(); - snapshot.Add(skey, sItem); - snapshot.AddContract(script.ToScriptHash(), contractState); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); + snapshotCache.Add(skey, sItem); + snapshotCache.AddContract(script.ToScriptHash(), contractState); - using ApplicationEngine ae = ApplicationEngine.Create(TriggerType.Application, null, snapshot); + using ApplicationEngine ae = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache); Debugger debugger = new(ae); ae.LoadScript(script); debugger.StepInto(); //push value diff --git a/tests/Neo.UnitTests/SmartContract/UT_InteropService.NEO.cs b/tests/Neo.UnitTests/SmartContract/UT_InteropService.NEO.cs index a2e22dbff3..657206ab57 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_InteropService.NEO.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_InteropService.NEO.cs @@ -113,7 +113,7 @@ public void TestCrypto_CheckMultiSig() [TestMethod] public void TestContract_Create() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var nef = new NefFile() { Script = Enumerable.Repeat((byte)OpCode.RET, byte.MaxValue).ToArray(), @@ -124,9 +124,9 @@ public void TestContract_Create() nef.CheckSum = NefFile.ComputeChecksum(nef); var nefFile = nef.ToArray(); var manifest = TestUtils.CreateDefaultManifest(); - Assert.ThrowsException(() => snapshot.DeployContract(null, nefFile, manifest.ToJson().ToByteArray(false))); - Assert.ThrowsException(() => snapshot.DeployContract(UInt160.Zero, nefFile, new byte[ContractManifest.MaxLength + 1])); - Assert.ThrowsException(() => snapshot.DeployContract(UInt160.Zero, nefFile, manifest.ToJson().ToByteArray(true), 10000000)); + Assert.ThrowsException(() => snapshotCache.DeployContract(null, nefFile, manifest.ToJson().ToByteArray(false))); + Assert.ThrowsException(() => snapshotCache.DeployContract(UInt160.Zero, nefFile, new byte[ContractManifest.MaxLength + 1])); + Assert.ThrowsException(() => snapshotCache.DeployContract(UInt160.Zero, nefFile, manifest.ToJson().ToByteArray(true), 10000000)); var script_exceedMaxLength = new NefFile() { @@ -138,29 +138,29 @@ public void TestContract_Create() script_exceedMaxLength.CheckSum = NefFile.ComputeChecksum(script_exceedMaxLength); Assert.ThrowsException(() => script_exceedMaxLength.ToArray().AsSerializable()); - Assert.ThrowsException(() => snapshot.DeployContract(UInt160.Zero, script_exceedMaxLength.ToArray(), manifest.ToJson().ToByteArray(true))); + Assert.ThrowsException(() => snapshotCache.DeployContract(UInt160.Zero, script_exceedMaxLength.ToArray(), manifest.ToJson().ToByteArray(true))); var script_zeroLength = System.Array.Empty(); - Assert.ThrowsException(() => snapshot.DeployContract(UInt160.Zero, script_zeroLength, manifest.ToJson().ToByteArray(true))); + Assert.ThrowsException(() => snapshotCache.DeployContract(UInt160.Zero, script_zeroLength, manifest.ToJson().ToByteArray(true))); var manifest_zeroLength = System.Array.Empty(); - Assert.ThrowsException(() => snapshot.DeployContract(UInt160.Zero, nefFile, manifest_zeroLength)); + Assert.ThrowsException(() => snapshotCache.DeployContract(UInt160.Zero, nefFile, manifest_zeroLength)); manifest = TestUtils.CreateDefaultManifest(); - var ret = snapshot.DeployContract(UInt160.Zero, nefFile, manifest.ToJson().ToByteArray(false)); + var ret = snapshotCache.DeployContract(UInt160.Zero, nefFile, manifest.ToJson().ToByteArray(false)); ret.Hash.ToString().Should().Be("0x7b37d4bd3d87f53825c3554bd1a617318235a685"); - Assert.ThrowsException(() => snapshot.DeployContract(UInt160.Zero, nefFile, manifest.ToJson().ToByteArray(false))); + Assert.ThrowsException(() => snapshotCache.DeployContract(UInt160.Zero, nefFile, manifest.ToJson().ToByteArray(false))); var state = TestUtils.GetContract(); - snapshot.AddContract(state.Hash, state); + snapshotCache.AddContract(state.Hash, state); - Assert.ThrowsException(() => snapshot.DeployContract(UInt160.Zero, nefFile, manifest.ToJson().ToByteArray(false))); + Assert.ThrowsException(() => snapshotCache.DeployContract(UInt160.Zero, nefFile, manifest.ToJson().ToByteArray(false))); } [TestMethod] public void TestContract_Update() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var nef = new NefFile() { Script = new[] { (byte)OpCode.RET }, @@ -169,7 +169,7 @@ public void TestContract_Update() Tokens = Array.Empty() }; nef.CheckSum = NefFile.ComputeChecksum(nef); - Assert.ThrowsException(() => snapshot.UpdateContract(null, nef.ToArray(), new byte[0])); + Assert.ThrowsException(() => snapshotCache.UpdateContract(null, nef.ToArray(), new byte[0])); var manifest = TestUtils.CreateDefaultManifest(); byte[] privkey = { 0x01,0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, @@ -197,12 +197,12 @@ public void TestContract_Update() Id = state.Id, Key = new byte[] { 0x01 } }; - snapshot.AddContract(state.Hash, state); - snapshot.Add(storageKey, storageItem); + snapshotCache.AddContract(state.Hash, state); + snapshotCache.Add(storageKey, storageItem); state.UpdateCounter.Should().Be(0); - snapshot.UpdateContract(state.Hash, nef.ToArray(), manifest.ToJson().ToByteArray(false)); - var ret = NativeContract.ContractManagement.GetContract(snapshot, state.Hash); - snapshot.Find(BitConverter.GetBytes(state.Id)).ToList().Count().Should().Be(1); + snapshotCache.UpdateContract(state.Hash, nef.ToArray(), manifest.ToJson().ToByteArray(false)); + var ret = NativeContract.ContractManagement.GetContract(snapshotCache, state.Hash); + snapshotCache.Find(BitConverter.GetBytes(state.Id)).ToList().Count().Should().Be(1); ret.UpdateCounter.Should().Be(1); ret.Id.Should().Be(state.Id); ret.Manifest.ToJson().ToString().Should().Be(manifest.ToJson().ToString()); @@ -221,11 +221,11 @@ public void TestContract_Update_Invalid() }; nefFile.CheckSum = NefFile.ComputeChecksum(nefFile); - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); - Assert.ThrowsException(() => snapshot.UpdateContract(null, null, new byte[] { 0x01 })); - Assert.ThrowsException(() => snapshot.UpdateContract(null, nefFile.ToArray(), null)); - Assert.ThrowsException(() => snapshot.UpdateContract(null, null, null)); + Assert.ThrowsException(() => snapshotCache.UpdateContract(null, null, new byte[] { 0x01 })); + Assert.ThrowsException(() => snapshotCache.UpdateContract(null, nefFile.ToArray(), null)); + Assert.ThrowsException(() => snapshotCache.UpdateContract(null, null, null)); nefFile = new NefFile() { @@ -236,14 +236,14 @@ public void TestContract_Update_Invalid() }; nefFile.CheckSum = NefFile.ComputeChecksum(nefFile); - Assert.ThrowsException(() => snapshot.UpdateContract(null, nefFile.ToArray(), new byte[] { 0x01 })); - Assert.ThrowsException(() => snapshot.UpdateContract(null, nefFile.ToArray(), new byte[0])); + Assert.ThrowsException(() => snapshotCache.UpdateContract(null, nefFile.ToArray(), new byte[] { 0x01 })); + Assert.ThrowsException(() => snapshotCache.UpdateContract(null, nefFile.ToArray(), new byte[0])); } [TestMethod] public void TestStorage_Find() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var state = TestUtils.GetContract(); var storageItem = new StorageItem @@ -255,9 +255,9 @@ public void TestStorage_Find() Id = state.Id, Key = new byte[] { 0x01 } }; - snapshot.AddContract(state.Hash, state); - snapshot.Add(storageKey, storageItem); - var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot); + snapshotCache.AddContract(state.Hash, state); + snapshotCache.Add(storageKey, storageItem); + var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache); engine.LoadScript(new byte[] { 0x01 }); var iterator = engine.Find(new StorageContext diff --git a/tests/Neo.UnitTests/SmartContract/UT_InteropService.cs b/tests/Neo.UnitTests/SmartContract/UT_InteropService.cs index 48203a644a..972f8dc0d1 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_InteropService.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_InteropService.cs @@ -38,7 +38,7 @@ public partial class UT_InteropService : TestKit public void Runtime_GetNotifications_Test() { UInt160 scriptHash2; - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); using (var script = new ScriptBuilder()) { @@ -56,7 +56,7 @@ public void Runtime_GetNotifications_Test() scriptHash2 = script.ToArray().ToScriptHash(); - snapshot.DeleteContract(scriptHash2); + snapshotCache.DeleteContract(scriptHash2); var contract = TestUtils.GetContract(script.ToArray(), TestUtils.CreateManifest("test", ContractParameterType.Any, ContractParameterType.Integer, ContractParameterType.Integer)); contract.Manifest.Abi.Events = new[] { @@ -80,12 +80,12 @@ public void Runtime_GetNotifications_Test() Methods = WildcardContainer.Create(new string[]{"test"}) } }; - snapshot.AddContract(scriptHash2, contract); + snapshotCache.AddContract(scriptHash2, contract); } // Wrong length - using (var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, null, ProtocolSettings.Default)) + using (var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, null, ProtocolSettings.Default)) using (var script = new ScriptBuilder()) { // Retrive @@ -102,7 +102,7 @@ public void Runtime_GetNotifications_Test() // All test - using (var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, null, ProtocolSettings.Default)) + using (var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, null, ProtocolSettings.Default)) using (var script = new ScriptBuilder()) { // Notification @@ -179,7 +179,7 @@ public void Runtime_GetNotifications_Test() // Script notifications - using (var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, null, ProtocolSettings.Default)) + using (var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, null, ProtocolSettings.Default)) using (var script = new ScriptBuilder()) { // Notification @@ -255,7 +255,7 @@ public void Runtime_GetNotifications_Test() // Clean storage - snapshot.DeleteContract(scriptHash2); + snapshotCache.DeleteContract(scriptHash2); } private static void AssertNotification(StackItem stackItem, UInt160 scriptHash, string notification) @@ -291,7 +291,7 @@ public void TestExecutionEngine_GetCallingScriptHash() var contract = TestUtils.GetContract(scriptA.ToArray(), TestUtils.CreateManifest("test", ContractParameterType.Any, ContractParameterType.String, ContractParameterType.Integer)); engine = GetEngine(true, true, addScript: false); - engine.Snapshot.AddContract(contract.Hash, contract); + engine.SnapshotCache.AddContract(contract.Hash, contract); using ScriptBuilder scriptB = new(); scriptB.EmitDynamicCall(contract.Hash, "test", "0", 1); @@ -439,7 +439,7 @@ public void TestCrypto_Verify() public void TestBlockchain_GetHeight() { var engine = GetEngine(true, true); - NativeContract.Ledger.CurrentIndex(engine.Snapshot).Should().Be(0); + NativeContract.Ledger.CurrentIndex(engine.SnapshotCache).Should().Be(0); } [TestMethod] @@ -447,14 +447,14 @@ public void TestBlockchain_GetBlock() { var engine = GetEngine(true, true); - NativeContract.Ledger.GetBlock(engine.Snapshot, UInt256.Zero).Should().BeNull(); + NativeContract.Ledger.GetBlock(engine.SnapshotCache, UInt256.Zero).Should().BeNull(); var data1 = new byte[] { 0x01, 0x01, 0x01 ,0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}; - NativeContract.Ledger.GetBlock(engine.Snapshot, new UInt256(data1)).Should().BeNull(); - NativeContract.Ledger.GetBlock(engine.Snapshot, TestBlockchain.TheNeoSystem.GenesisBlock.Hash).Should().NotBeNull(); + NativeContract.Ledger.GetBlock(engine.SnapshotCache, new UInt256(data1)).Should().BeNull(); + NativeContract.Ledger.GetBlock(engine.SnapshotCache, TestBlockchain.TheNeoSystem.GenesisBlock.Hash).Should().NotBeNull(); } [TestMethod] @@ -465,7 +465,7 @@ public void TestBlockchain_GetTransaction() 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}; - NativeContract.Ledger.GetTransaction(engine.Snapshot, new UInt256(data1)).Should().BeNull(); + NativeContract.Ledger.GetTransaction(engine.SnapshotCache, new UInt256(data1)).Should().BeNull(); } [TestMethod] @@ -477,7 +477,7 @@ public void TestBlockchain_GetTransactionHeight() BlockIndex = 0, Transaction = TestUtils.CreateRandomHashTransaction() }; - TestUtils.TransactionAdd(engine.Snapshot, state); + TestUtils.TransactionAdd(engine.SnapshotCache, state); using var script = new ScriptBuilder(); script.EmitDynamicCall(NativeContract.Ledger.Hash, "getTransactionHeight", state.Transaction.Hash); @@ -498,21 +498,21 @@ public void TestBlockchain_GetContract() 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }; - NativeContract.ContractManagement.GetContract(engine.Snapshot, new UInt160(data1)).Should().BeNull(); + NativeContract.ContractManagement.GetContract(engine.SnapshotCache, new UInt160(data1)).Should().BeNull(); - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var state = TestUtils.GetContract(); - snapshot.AddContract(state.Hash, state); - engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot); + snapshotCache.AddContract(state.Hash, state); + engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache); engine.LoadScript(new byte[] { 0x01 }); - NativeContract.ContractManagement.GetContract(engine.Snapshot, state.Hash).Hash.Should().Be(state.Hash); + NativeContract.ContractManagement.GetContract(engine.SnapshotCache, state.Hash).Hash.Should().Be(state.Hash); } [TestMethod] public void TestBlockchain_GetContractById() { var engine = GetEngine(true, true); - var contract = NativeContract.ContractManagement.GetContractById(engine.Snapshot, -1); + var contract = NativeContract.ContractManagement.GetContractById(engine.SnapshotCache, -1); contract.Id.Should().Be(-1); contract.Manifest.Name.Should().Be(nameof(ContractManagement)); } @@ -521,25 +521,25 @@ public void TestBlockchain_GetContractById() public void TestBlockchain_HasMethod() { var engine = GetEngine(true, true); - NativeContract.ContractManagement.HasMethod(engine.Snapshot, NativeContract.NEO.Hash, "symbol", 0).Should().Be(true); - NativeContract.ContractManagement.HasMethod(engine.Snapshot, NativeContract.NEO.Hash, "transfer", 4).Should().Be(true); + NativeContract.ContractManagement.HasMethod(engine.SnapshotCache, NativeContract.NEO.Hash, "symbol", 0).Should().Be(true); + NativeContract.ContractManagement.HasMethod(engine.SnapshotCache, NativeContract.NEO.Hash, "transfer", 4).Should().Be(true); } [TestMethod] public void TestBlockchain_ListContracts() { var engine = GetEngine(true, true); - var list = NativeContract.ContractManagement.ListContracts(engine.Snapshot); + var list = NativeContract.ContractManagement.ListContracts(engine.SnapshotCache); list.ForEach(p => p.Id.Should().BeLessThan(0)); - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var state = TestUtils.GetContract(); - snapshot.AddContract(state.Hash, state); - engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot); + snapshotCache.AddContract(state.Hash, state); + engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache); engine.LoadScript(new byte[] { 0x01 }); - NativeContract.ContractManagement.GetContract(engine.Snapshot, state.Hash).Hash.Should().Be(state.Hash); + NativeContract.ContractManagement.GetContract(engine.SnapshotCache, state.Hash).Hash.Should().Be(state.Hash); - var list2 = NativeContract.ContractManagement.ListContracts(engine.Snapshot); + var list2 = NativeContract.ContractManagement.ListContracts(engine.SnapshotCache); list2.Count().Should().Be(list.Count() + 1); } @@ -548,7 +548,7 @@ public void TestStorage_GetContext() { var engine = GetEngine(false, true); var state = TestUtils.GetContract(); - engine.Snapshot.AddContract(state.Hash, state); + engine.SnapshotCache.AddContract(state.Hash, state); engine.LoadScript(state.Script); engine.GetStorageContext().IsReadOnly.Should().BeFalse(); } @@ -558,7 +558,7 @@ public void TestStorage_GetReadOnlyContext() { var engine = GetEngine(false, true); var state = TestUtils.GetContract(); - engine.Snapshot.AddContract(state.Hash, state); + engine.SnapshotCache.AddContract(state.Hash, state); engine.LoadScript(state.Script); engine.GetReadOnlyContext().IsReadOnly.Should().BeTrue(); } @@ -566,7 +566,7 @@ public void TestStorage_GetReadOnlyContext() [TestMethod] public void TestStorage_Get() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var state = TestUtils.GetContract(); var storageKey = new StorageKey @@ -579,9 +579,9 @@ public void TestStorage_Get() { Value = new byte[] { 0x01, 0x02, 0x03, 0x04 } }; - snapshot.AddContract(state.Hash, state); - snapshot.Add(storageKey, storageItem); - var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot); + snapshotCache.AddContract(state.Hash, state); + snapshotCache.Add(storageKey, storageItem); + var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache); engine.LoadScript(new byte[] { 0x01 }); engine.Get(new StorageContext @@ -624,7 +624,7 @@ public void TestStorage_Put() Assert.ThrowsException(() => engine.Put(storageContext, key, value)); //storage value is constant - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var storageKey = new StorageKey { @@ -635,9 +635,9 @@ public void TestStorage_Put() { Value = new byte[] { 0x01, 0x02, 0x03, 0x04 } }; - snapshot.AddContract(state.Hash, state); - snapshot.Add(storageKey, storageItem); - engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot); + snapshotCache.AddContract(state.Hash, state); + snapshotCache.Add(storageKey, storageItem); + engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache); engine.LoadScript(new byte[] { 0x01 }); key = new byte[] { 0x01 }; value = new byte[] { 0x02 }; @@ -654,7 +654,7 @@ public void TestStorage_Put() public void TestStorage_Delete() { var engine = GetEngine(false, true); - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var state = TestUtils.GetContract(); var storageKey = new StorageKey { @@ -665,9 +665,9 @@ public void TestStorage_Delete() { Value = new byte[] { 0x01, 0x02, 0x03, 0x04 } }; - snapshot.AddContract(state.Hash, state); - snapshot.Add(storageKey, storageItem); - engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot); + snapshotCache.AddContract(state.Hash, state); + snapshotCache.Add(storageKey, storageItem); + engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache); engine.LoadScript(new byte[] { 0x01 }); var key = new byte[] { 0x01 }; var storageContext = new StorageContext @@ -697,38 +697,38 @@ public void TestStorageContext_AsReadOnly() [TestMethod] public void TestContract_Call() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var method = "method"; var args = new VM.Types.Array { 0, 1 }; var state = TestUtils.GetContract(method, args.Count); - var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, null, ProtocolSettings.Default); + var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, null, ProtocolSettings.Default); engine.LoadScript(new byte[] { 0x01 }); - engine.Snapshot.AddContract(state.Hash, state); + engine.SnapshotCache.AddContract(state.Hash, state); engine.CallContract(state.Hash, method, CallFlags.All, args); engine.CurrentContext.EvaluationStack.Pop().Should().Be(args[0]); engine.CurrentContext.EvaluationStack.Pop().Should().Be(args[1]); state.Manifest.Permissions[0].Methods = WildcardContainer.Create("a"); - engine.Snapshot.DeleteContract(state.Hash); - engine.Snapshot.AddContract(state.Hash, state); + engine.SnapshotCache.DeleteContract(state.Hash); + engine.SnapshotCache.AddContract(state.Hash, state); Assert.ThrowsException(() => engine.CallContract(state.Hash, method, CallFlags.All, args)); state.Manifest.Permissions[0].Methods = WildcardContainer.CreateWildcard(); - engine.Snapshot.DeleteContract(state.Hash); - engine.Snapshot.AddContract(state.Hash, state); + engine.SnapshotCache.DeleteContract(state.Hash); + engine.SnapshotCache.AddContract(state.Hash, state); engine.CallContract(state.Hash, method, CallFlags.All, args); - engine.Snapshot.DeleteContract(state.Hash); - engine.Snapshot.AddContract(state.Hash, state); + engine.SnapshotCache.DeleteContract(state.Hash); + engine.SnapshotCache.AddContract(state.Hash, state); Assert.ThrowsException(() => engine.CallContract(UInt160.Zero, method, CallFlags.All, args)); } [TestMethod] public void TestContract_Destroy() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var state = TestUtils.GetContract(); var scriptHash = UInt160.Parse("0xcb9f3b7c6fb1cf2c13a40637c189bdd066a272b4"); var storageItem = new StorageItem @@ -741,16 +741,16 @@ public void TestContract_Destroy() Id = 0x43000000, Key = new byte[] { 0x01 } }; - snapshot.AddContract(scriptHash, state); - snapshot.Add(storageKey, storageItem); - snapshot.DestroyContract(scriptHash); - snapshot.Find(BitConverter.GetBytes(0x43000000)).Any().Should().BeFalse(); + snapshotCache.AddContract(scriptHash, state); + snapshotCache.Add(storageKey, storageItem); + snapshotCache.DestroyContract(scriptHash); + snapshotCache.Find(BitConverter.GetBytes(0x43000000)).Any().Should().BeFalse(); //storages are removed state = TestUtils.GetContract(); - snapshot.AddContract(scriptHash, state); - snapshot.DestroyContract(scriptHash); - snapshot.Find(BitConverter.GetBytes(0x43000000)).Any().Should().BeFalse(); + snapshotCache.AddContract(scriptHash, state); + snapshotCache.DestroyContract(scriptHash); + snapshotCache.Find(BitConverter.GetBytes(0x43000000)).Any().Should().BeFalse(); } [TestMethod] @@ -769,9 +769,9 @@ public static void LogEvent(object sender, LogEventArgs args) private static ApplicationEngine GetEngine(bool hasContainer = false, bool hasSnapshot = false, bool hasBlock = false, bool addScript = true, long gas = 20_00000000) { var tx = hasContainer ? TestUtils.GetTransaction(UInt160.Zero) : null; - var snapshot = hasSnapshot ? TestBlockchain.GetTestSnapshotCache() : null; + var snapshotCache = hasSnapshot ? TestBlockchain.GetTestSnapshotCache() : null; var block = hasBlock ? new Block { Header = new Header() } : null; - var engine = ApplicationEngine.Create(TriggerType.Application, tx, snapshot, block, TestBlockchain.TheNeoSystem.Settings, gas: gas); + var engine = ApplicationEngine.Create(TriggerType.Application, tx, snapshotCache, block, TestBlockchain.TheNeoSystem.Settings, gas: gas); if (addScript) engine.LoadScript(new byte[] { 0x01 }); return engine; } @@ -827,21 +827,21 @@ public void TestMurmur32() [TestMethod] public void TestGetBlockHash() { - var snapshot = GetEngine(true, true).Snapshot; - var hash = LedgerContract.Ledger.GetBlockHash(snapshot, 0); - var hash2 = LedgerContract.Ledger.GetBlock(snapshot, 0).Hash; - var hash3 = LedgerContract.Ledger.GetHeader(snapshot, 0).Hash; + var snapshotCache = GetEngine(true, true).SnapshotCache; + var hash = LedgerContract.Ledger.GetBlockHash(snapshotCache, 0); + var hash2 = LedgerContract.Ledger.GetBlock(snapshotCache, 0).Hash; + var hash3 = LedgerContract.Ledger.GetHeader(snapshotCache, 0).Hash; hash.ToString().Should().Be(hash2.ToString()); hash.ToString().Should().Be(hash3.ToString()); hash.ToString().Should().Be("0x1f4d1defa46faa5e7b9b8d3f79a06bec777d7c26c4aa5f6f5899a291daa87c15"); - LedgerContract.Ledger.ContainsBlock(snapshot, hash).Should().BeTrue(); + LedgerContract.Ledger.ContainsBlock(snapshotCache, hash).Should().BeTrue(); } [TestMethod] public void TestGetCandidateVote() { - var snapshot = GetEngine(true, true).Snapshot; - var vote = LedgerContract.NEO.GetCandidateVote(snapshot, new ECPoint()); + var snapshotCache = GetEngine(true, true).SnapshotCache; + var vote = LedgerContract.NEO.GetCandidateVote(snapshotCache, new ECPoint()); vote.Should().Be(-1); } diff --git a/tests/Neo.UnitTests/SmartContract/UT_SmartContractHelper.cs b/tests/Neo.UnitTests/SmartContract/UT_SmartContractHelper.cs index ceb13a2a64..42308d91f2 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_SmartContractHelper.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_SmartContractHelper.cs @@ -124,9 +124,9 @@ public void TestIsStandardContract() [TestMethod] public void TestVerifyWitnesses() { - var snapshot1 = TestBlockchain.GetTestSnapshotCache().CreateSnapshot(); + var snapshotCache1 = TestBlockchain.GetTestSnapshotCache().CreateSnapshot(); UInt256 index1 = UInt256.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff01"); - TestUtils.BlocksAdd(snapshot1, index1, new TrimmedBlock() + TestUtils.BlocksAdd(snapshotCache1, index1, new TrimmedBlock() { Header = new Header { @@ -138,10 +138,10 @@ public void TestVerifyWitnesses() }, Hashes = new UInt256[1] { UInt256.Zero }, }); - TestUtils.BlocksDelete(snapshot1, index1); - Assert.AreEqual(false, Neo.SmartContract.Helper.VerifyWitnesses(new Header() { PrevHash = index1 }, TestProtocolSettings.Default, snapshot1, 100)); + TestUtils.BlocksDelete(snapshotCache1, index1); + Assert.AreEqual(false, Neo.SmartContract.Helper.VerifyWitnesses(new Header() { PrevHash = index1 }, TestProtocolSettings.Default, snapshotCache1, 100)); - var snapshot2 = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache2 = TestBlockchain.GetTestSnapshotCache(); UInt256 index2 = UInt256.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff01"); TrimmedBlock block2 = new() { @@ -155,14 +155,14 @@ public void TestVerifyWitnesses() }, Hashes = new UInt256[1] { UInt256.Zero }, }; - TestUtils.BlocksAdd(snapshot2, index2, block2); + TestUtils.BlocksAdd(snapshotCache2, index2, block2); Header header2 = new() { PrevHash = index2, Witness = new Witness { InvocationScript = Array.Empty(), VerificationScript = Array.Empty() } }; - snapshot2.AddContract(UInt160.Zero, new ContractState()); - snapshot2.DeleteContract(UInt160.Zero); - Assert.AreEqual(false, Neo.SmartContract.Helper.VerifyWitnesses(header2, TestProtocolSettings.Default, snapshot2, 100)); + snapshotCache2.AddContract(UInt160.Zero, new ContractState()); + snapshotCache2.DeleteContract(UInt160.Zero); + Assert.AreEqual(false, Neo.SmartContract.Helper.VerifyWitnesses(header2, TestProtocolSettings.Default, snapshotCache2, 100)); - var snapshot3 = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache3 = TestBlockchain.GetTestSnapshotCache(); UInt256 index3 = UInt256.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff01"); TrimmedBlock block3 = new() { @@ -176,7 +176,7 @@ public void TestVerifyWitnesses() }, Hashes = new UInt256[1] { UInt256.Zero }, }; - TestUtils.BlocksAdd(snapshot3, index3, block3); + TestUtils.BlocksAdd(snapshotCache3, index3, block3); Header header3 = new() { PrevHash = index3, @@ -186,13 +186,13 @@ public void TestVerifyWitnesses() VerificationScript = Array.Empty() } }; - snapshot3.AddContract(UInt160.Zero, new ContractState() + snapshotCache3.AddContract(UInt160.Zero, new ContractState() { Nef = new NefFile { Script = Array.Empty() }, Hash = Array.Empty().ToScriptHash(), Manifest = TestUtils.CreateManifest("verify", ContractParameterType.Boolean, ContractParameterType.Signature), }); - Assert.AreEqual(false, Neo.SmartContract.Helper.VerifyWitnesses(header3, TestProtocolSettings.Default, snapshot3, 100)); + Assert.AreEqual(false, Neo.SmartContract.Helper.VerifyWitnesses(header3, TestProtocolSettings.Default, snapshotCache3, 100)); // Smart contract verification @@ -202,13 +202,13 @@ public void TestVerifyWitnesses() Hash = "11".HexToBytes().ToScriptHash(), Manifest = TestUtils.CreateManifest("verify", ContractParameterType.Boolean, ContractParameterType.Signature), // Offset = 0 }; - snapshot3.AddContract(contract.Hash, contract); + snapshotCache3.AddContract(contract.Hash, contract); var tx = new Nep17NativeContractExtensions.ManualWitness(contract.Hash) { Witnesses = new Witness[] { new Witness() { InvocationScript = Array.Empty(), VerificationScript = Array.Empty() } } }; - Assert.AreEqual(true, Neo.SmartContract.Helper.VerifyWitnesses(tx, TestProtocolSettings.Default, snapshot3, 1000)); + Assert.AreEqual(true, Neo.SmartContract.Helper.VerifyWitnesses(tx, TestProtocolSettings.Default, snapshotCache3, 1000)); } } } diff --git a/tests/Neo.UnitTests/SmartContract/UT_Syscalls.cs b/tests/Neo.UnitTests/SmartContract/UT_Syscalls.cs index 43448ef218..a864c5d427 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_Syscalls.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_Syscalls.cs @@ -62,14 +62,14 @@ public void System_Blockchain_GetBlock() Hashes = new[] { tx.Hash } }; - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); using ScriptBuilder script = new(); script.EmitDynamicCall(NativeContract.Ledger.Hash, "getBlock", block.Hash.ToArray()); // Without block - var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(engine.Execute(), VMState.HALT); @@ -81,18 +81,18 @@ public void System_Blockchain_GetBlock() const byte Prefix_Transaction = 11; const byte Prefix_CurrentBlock = 12; - TestUtils.BlocksAdd(snapshot, block.Hash, block); + TestUtils.BlocksAdd(snapshotCache, block.Hash, block); - var height = snapshot[NativeContract.Ledger.CreateStorageKey(Prefix_CurrentBlock)].GetInteroperable(); + var height = snapshotCache[NativeContract.Ledger.CreateStorageKey(Prefix_CurrentBlock)].GetInteroperable(); height.Index = block.Index + TestProtocolSettings.Default.MaxTraceableBlocks; - snapshot.Add(NativeContract.Ledger.CreateStorageKey(Prefix_Transaction, tx.Hash), new StorageItem(new TransactionState + snapshotCache.Add(NativeContract.Ledger.CreateStorageKey(Prefix_Transaction, tx.Hash), new StorageItem(new TransactionState { BlockIndex = block.Index, Transaction = tx })); - engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(engine.Execute(), VMState.HALT); @@ -101,10 +101,10 @@ public void System_Blockchain_GetBlock() // With block - height = snapshot[NativeContract.Ledger.CreateStorageKey(Prefix_CurrentBlock)].GetInteroperable(); + height = snapshotCache[NativeContract.Ledger.CreateStorageKey(Prefix_CurrentBlock)].GetInteroperable(); height.Index = block.Index; - engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); engine.LoadScript(script.ToArray()); Assert.AreEqual(engine.Execute(), VMState.HALT); @@ -117,13 +117,13 @@ public void System_Blockchain_GetBlock() [TestMethod] public void System_ExecutionEngine_GetScriptContainer() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); using ScriptBuilder script = new(); script.EmitSysCall(ApplicationEngine.System_Runtime_GetScriptContainer); // Without tx - var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot); + var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache); engine.LoadScript(script.ToArray()); Assert.AreEqual(engine.Execute(), VMState.FAULT); @@ -153,7 +153,7 @@ public void System_ExecutionEngine_GetScriptContainer() Witnesses = new Witness[] { new Witness() { VerificationScript = new byte[] { 0x07 } } }, }; - engine = ApplicationEngine.Create(TriggerType.Application, tx, snapshot); + engine = ApplicationEngine.Create(TriggerType.Application, tx, snapshotCache); engine.LoadScript(script.ToArray()); Assert.AreEqual(engine.Execute(), VMState.HALT); @@ -166,7 +166,7 @@ public void System_ExecutionEngine_GetScriptContainer() [TestMethod] public void System_Runtime_GasLeft() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); using (var script = new ScriptBuilder()) { @@ -181,7 +181,7 @@ public void System_Runtime_GasLeft() // Execute - var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, gas: 100_000_000); + var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, gas: 100_000_000); engine.LoadScript(script.ToArray()); Assert.AreEqual(engine.Execute(), VMState.HALT); @@ -202,7 +202,7 @@ public void System_Runtime_GasLeft() // Execute - var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot); + var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache); engine.LoadScript(script.ToArray()); // Check the results @@ -218,7 +218,7 @@ public void System_Runtime_GasLeft() public void System_Runtime_GetInvocationCounter() { ContractState contractA, contractB, contractC; - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); // Create dummy contracts @@ -236,15 +236,15 @@ public void System_Runtime_GetInvocationCounter() // Init A,B,C contracts // First two drops is for drop method and arguments - snapshot.DeleteContract(contractA.Hash); - snapshot.DeleteContract(contractB.Hash); - snapshot.DeleteContract(contractC.Hash); + snapshotCache.DeleteContract(contractA.Hash); + snapshotCache.DeleteContract(contractB.Hash); + snapshotCache.DeleteContract(contractC.Hash); contractA.Manifest = TestUtils.CreateManifest("dummyMain", ContractParameterType.Any, ContractParameterType.String, ContractParameterType.Integer); contractB.Manifest = TestUtils.CreateManifest("dummyMain", ContractParameterType.Any, ContractParameterType.String, ContractParameterType.Integer); contractC.Manifest = TestUtils.CreateManifest("dummyMain", ContractParameterType.Any, ContractParameterType.String, ContractParameterType.Integer); - snapshot.AddContract(contractA.Hash, contractA); - snapshot.AddContract(contractB.Hash, contractB); - snapshot.AddContract(contractC.Hash, contractC); + snapshotCache.AddContract(contractA.Hash, contractA); + snapshotCache.AddContract(contractB.Hash, contractB); + snapshotCache.AddContract(contractC.Hash, contractC); } // Call A,B,B,C @@ -258,7 +258,7 @@ public void System_Runtime_GetInvocationCounter() // Execute - var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, null, ProtocolSettings.Default); + var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, null, ProtocolSettings.Default); engine.LoadScript(script.ToArray()); Assert.AreEqual(VMState.HALT, engine.Execute()); diff --git a/tests/Neo.UnitTests/UT_DataCache.cs b/tests/Neo.UnitTests/UT_DataCache.cs index 5271d446ff..5bc5b4085c 100644 --- a/tests/Neo.UnitTests/UT_DataCache.cs +++ b/tests/Neo.UnitTests/UT_DataCache.cs @@ -22,8 +22,8 @@ public class UT_DataCache [TestMethod] public void TestCachedFind_Between() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); - var storages = snapshot.CreateSnapshot(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); + var storages = snapshotCache.CreateSnapshot(); var cache = new ClonedCache(storages); storages.Add @@ -93,8 +93,8 @@ public void TestCachedFind_Last() [TestMethod] public void TestCachedFind_Empty() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); - var storages = snapshot.CreateSnapshot(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); + var storages = snapshotCache.CreateSnapshot(); var cache = new ClonedCache(storages); cache.Add diff --git a/tests/Neo.UnitTests/Wallets/UT_AssetDescriptor.cs b/tests/Neo.UnitTests/Wallets/UT_AssetDescriptor.cs index 427af290b1..ff2386c466 100644 --- a/tests/Neo.UnitTests/Wallets/UT_AssetDescriptor.cs +++ b/tests/Neo.UnitTests/Wallets/UT_AssetDescriptor.cs @@ -22,10 +22,10 @@ public class UT_AssetDescriptor [TestMethod] public void TestConstructorWithNonexistAssetId() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); Action action = () => { - var descriptor = new Neo.Wallets.AssetDescriptor(snapshot, TestProtocolSettings.Default, UInt160.Parse("01ff00ff00ff00ff00ff00ff00ff00ff00ff00a4")); + var descriptor = new Neo.Wallets.AssetDescriptor(snapshotCache, TestProtocolSettings.Default, UInt160.Parse("01ff00ff00ff00ff00ff00ff00ff00ff00ff00a4")); }; action.Should().Throw(); } @@ -33,8 +33,8 @@ public void TestConstructorWithNonexistAssetId() [TestMethod] public void Check_GAS() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); - var descriptor = new Neo.Wallets.AssetDescriptor(snapshot, TestProtocolSettings.Default, NativeContract.GAS.Hash); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); + var descriptor = new Neo.Wallets.AssetDescriptor(snapshotCache, TestProtocolSettings.Default, NativeContract.GAS.Hash); descriptor.AssetId.Should().Be(NativeContract.GAS.Hash); descriptor.AssetName.Should().Be(nameof(GasToken)); descriptor.ToString().Should().Be(nameof(GasToken)); @@ -45,8 +45,8 @@ public void Check_GAS() [TestMethod] public void Check_NEO() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); - var descriptor = new Neo.Wallets.AssetDescriptor(snapshot, TestProtocolSettings.Default, NativeContract.NEO.Hash); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); + var descriptor = new Neo.Wallets.AssetDescriptor(snapshotCache, TestProtocolSettings.Default, NativeContract.NEO.Hash); descriptor.AssetId.Should().Be(NativeContract.NEO.Hash); descriptor.AssetName.Should().Be(nameof(NeoToken)); descriptor.ToString().Should().Be(nameof(NeoToken)); diff --git a/tests/Neo.UnitTests/Wallets/UT_Wallet.cs b/tests/Neo.UnitTests/Wallets/UT_Wallet.cs index 06619d74f5..bba7ff05a1 100644 --- a/tests/Neo.UnitTests/Wallets/UT_Wallet.cs +++ b/tests/Neo.UnitTests/Wallets/UT_Wallet.cs @@ -217,14 +217,14 @@ public void TestGetAvailable() account.Lock = false; // Fake balance - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var key = NativeContract.GAS.CreateStorageKey(20, account.ScriptHash); - var entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); + var entry = snapshotCache.GetAndChange(key, () => new StorageItem(new AccountState())); entry.GetInteroperable().Balance = 10000 * NativeContract.GAS.Factor; - wallet.GetAvailable(snapshot, NativeContract.GAS.Hash).Should().Be(new BigDecimal(new BigInteger(1000000000000M), 8)); + wallet.GetAvailable(snapshotCache, NativeContract.GAS.Hash).Should().Be(new BigDecimal(new BigInteger(1000000000000M), 8)); - entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); + entry = snapshotCache.GetAndChange(key, () => new StorageItem(new AccountState())); entry.GetInteroperable().Balance = 0; } @@ -237,15 +237,15 @@ public void TestGetBalance() account.Lock = false; // Fake balance - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var key = NativeContract.GAS.CreateStorageKey(20, account.ScriptHash); - var entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); + var entry = snapshotCache.GetAndChange(key, () => new StorageItem(new AccountState())); entry.GetInteroperable().Balance = 10000 * NativeContract.GAS.Factor; - wallet.GetBalance(snapshot, UInt160.Zero, new UInt160[] { account.ScriptHash }).Should().Be(new BigDecimal(BigInteger.Zero, 0)); - wallet.GetBalance(snapshot, NativeContract.GAS.Hash, new UInt160[] { account.ScriptHash }).Should().Be(new BigDecimal(new BigInteger(1000000000000M), 8)); + wallet.GetBalance(snapshotCache, UInt160.Zero, new UInt160[] { account.ScriptHash }).Should().Be(new BigDecimal(BigInteger.Zero, 0)); + wallet.GetBalance(snapshotCache, NativeContract.GAS.Hash, new UInt160[] { account.ScriptHash }).Should().Be(new BigDecimal(new BigInteger(1000000000000M), 8)); - entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); + entry = snapshotCache.GetAndChange(key, () => new StorageItem(new AccountState())); entry.GetInteroperable().Balance = 0; } @@ -290,13 +290,13 @@ public void TestImport2() [TestMethod] public void TestMakeTransaction1() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); MyWallet wallet = new(); Contract contract = Contract.Create(new ContractParameterType[] { ContractParameterType.Boolean }, new byte[] { 1 }); WalletAccount account = wallet.CreateAccount(contract, glkey.PrivateKey); account.Lock = false; - Action action = () => wallet.MakeTransaction(snapshot, new TransferOutput[] + Action action = () => wallet.MakeTransaction(snapshotCache, new TransferOutput[] { new TransferOutput() { @@ -308,7 +308,7 @@ public void TestMakeTransaction1() }, UInt160.Zero); action.Should().Throw(); - action = () => wallet.MakeTransaction(snapshot, new TransferOutput[] + action = () => wallet.MakeTransaction(snapshotCache, new TransferOutput[] { new TransferOutput() { @@ -320,7 +320,7 @@ public void TestMakeTransaction1() }, account.ScriptHash); action.Should().Throw(); - action = () => wallet.MakeTransaction(snapshot, new TransferOutput[] + action = () => wallet.MakeTransaction(snapshotCache, new TransferOutput[] { new TransferOutput() { @@ -334,14 +334,14 @@ public void TestMakeTransaction1() // Fake balance var key = NativeContract.GAS.CreateStorageKey(20, account.ScriptHash); - var entry1 = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); + var entry1 = snapshotCache.GetAndChange(key, () => new StorageItem(new AccountState())); entry1.GetInteroperable().Balance = 10000 * NativeContract.GAS.Factor; key = NativeContract.NEO.CreateStorageKey(20, account.ScriptHash); - var entry2 = snapshot.GetAndChange(key, () => new StorageItem(new NeoToken.NeoAccountState())); + var entry2 = snapshotCache.GetAndChange(key, () => new StorageItem(new NeoToken.NeoAccountState())); entry2.GetInteroperable().Balance = 10000 * NativeContract.NEO.Factor; - var tx = wallet.MakeTransaction(snapshot, new TransferOutput[] + var tx = wallet.MakeTransaction(snapshotCache, new TransferOutput[] { new TransferOutput() { @@ -352,7 +352,7 @@ public void TestMakeTransaction1() }); tx.Should().NotBeNull(); - tx = wallet.MakeTransaction(snapshot, new TransferOutput[] + tx = wallet.MakeTransaction(snapshotCache, new TransferOutput[] { new TransferOutput() { @@ -364,8 +364,8 @@ public void TestMakeTransaction1() }); tx.Should().NotBeNull(); - entry1 = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); - entry2 = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); + entry1 = snapshotCache.GetAndChange(key, () => new StorageItem(new AccountState())); + entry2 = snapshotCache.GetAndChange(key, () => new StorageItem(new AccountState())); entry1.GetInteroperable().Balance = 0; entry2.GetInteroperable().Balance = 0; } @@ -373,9 +373,9 @@ public void TestMakeTransaction1() [TestMethod] public void TestMakeTransaction2() { - var snapshot = TestBlockchain.GetTestSnapshotCache(); + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); MyWallet wallet = new(); - Action action = () => wallet.MakeTransaction(snapshot, Array.Empty(), null, null, Array.Empty()); + Action action = () => wallet.MakeTransaction(snapshotCache, Array.Empty(), null, null, Array.Empty()); action.Should().Throw(); Contract contract = Contract.Create(new ContractParameterType[] { ContractParameterType.Boolean }, new byte[] { 1 }); @@ -384,10 +384,10 @@ public void TestMakeTransaction2() // Fake balance var key = NativeContract.GAS.CreateStorageKey(20, account.ScriptHash); - var entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); + var entry = snapshotCache.GetAndChange(key, () => new StorageItem(new AccountState())); entry.GetInteroperable().Balance = 1000000 * NativeContract.GAS.Factor; - var tx = wallet.MakeTransaction(snapshot, Array.Empty(), account.ScriptHash, new[]{ new Signer() + var tx = wallet.MakeTransaction(snapshotCache, Array.Empty(), account.ScriptHash, new[]{ new Signer() { Account = account.ScriptHash, Scopes = WitnessScope.CalledByEntry @@ -395,10 +395,10 @@ public void TestMakeTransaction2() tx.Should().NotBeNull(); - tx = wallet.MakeTransaction(snapshot, Array.Empty(), null, null, Array.Empty()); + tx = wallet.MakeTransaction(snapshotCache, Array.Empty(), null, null, Array.Empty()); tx.Should().NotBeNull(); - entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); + entry = snapshotCache.GetAndChange(key, () => new StorageItem(new AccountState())); entry.GetInteroperable().Balance = 0; } From c2141e81aff0b2c42511f643f00f3ea04eac49c5 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Mon, 29 Jul 2024 16:39:59 +0800 Subject: [PATCH 3/3] [Neo Plugin RpcServer UT]Plugin rpcserver wallet UTs (#3433) * wallet * fix util * add comments and fix ut * Update tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Wallet.cs * remove comment --------- Co-authored-by: Christopher Schuchardt Co-authored-by: Shargon Co-authored-by: NGD Admin <154295625+NGDAdmin@users.noreply.github.com> --- src/Plugins/RpcServer/Result.cs | 2 +- .../RpcServer/RpcServer.SmartContract.cs | 10 +- src/Plugins/RpcServer/RpcServer.Wallet.cs | 188 +++++++- .../UT_RpcServer.Wallet.cs | 403 ++++++++++++++++++ tests/Neo.UnitTests/TestUtils.Contract.cs | 105 +++++ tests/Neo.UnitTests/TestUtils.Transaction.cs | 102 +++++ tests/Neo.UnitTests/TestUtils.cs | 179 -------- 7 files changed, 785 insertions(+), 204 deletions(-) create mode 100644 tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Wallet.cs create mode 100644 tests/Neo.UnitTests/TestUtils.Contract.cs diff --git a/src/Plugins/RpcServer/Result.cs b/src/Plugins/RpcServer/Result.cs index 9c7ace227c..c76e15153b 100644 --- a/src/Plugins/RpcServer/Result.cs +++ b/src/Plugins/RpcServer/Result.cs @@ -23,7 +23,7 @@ public static class Result /// The return type /// The execution result /// The Rpc exception - public static T Ok_Or(this Func function, RpcError err, bool withData = false) + public static T Ok_Or(Func function, RpcError err, bool withData = false) { try { diff --git a/src/Plugins/RpcServer/RpcServer.SmartContract.cs b/src/Plugins/RpcServer/RpcServer.SmartContract.cs index 473ae0cb5d..70edc4cedb 100644 --- a/src/Plugins/RpcServer/RpcServer.SmartContract.cs +++ b/src/Plugins/RpcServer/RpcServer.SmartContract.cs @@ -213,7 +213,7 @@ private static Witness[] WitnessesFromJson(JArray _params) } [RpcMethod] - protected virtual JToken InvokeFunction(JArray _params) + protected internal virtual JToken InvokeFunction(JArray _params) { UInt160 script_hash = Result.Ok_Or(() => UInt160.Parse(_params[0].AsString()), RpcError.InvalidParams.WithData($"Invalid script hash {nameof(script_hash)}")); string operation = Result.Ok_Or(() => _params[1].AsString(), RpcError.InvalidParams); @@ -231,7 +231,7 @@ protected virtual JToken InvokeFunction(JArray _params) } [RpcMethod] - protected virtual JToken InvokeScript(JArray _params) + protected internal virtual JToken InvokeScript(JArray _params) { byte[] script = Result.Ok_Or(() => Convert.FromBase64String(_params[0].AsString()), RpcError.InvalidParams); Signer[] signers = _params.Count >= 2 ? SignersFromJson((JArray)_params[1], system.Settings) : null; @@ -241,7 +241,7 @@ protected virtual JToken InvokeScript(JArray _params) } [RpcMethod] - protected virtual JToken TraverseIterator(JArray _params) + protected internal virtual JToken TraverseIterator(JArray _params) { settings.SessionEnabled.True_Or(RpcError.SessionsDisabled); Guid sid = Result.Ok_Or(() => Guid.Parse(_params[0].GetString()), RpcError.InvalidParams.WithData($"Invalid session id {nameof(sid)}")); @@ -262,7 +262,7 @@ protected virtual JToken TraverseIterator(JArray _params) } [RpcMethod] - protected virtual JToken TerminateSession(JArray _params) + protected internal virtual JToken TerminateSession(JArray _params) { settings.SessionEnabled.True_Or(RpcError.SessionsDisabled); Guid sid = Result.Ok_Or(() => Guid.Parse(_params[0].GetString()), RpcError.InvalidParams.WithData("Invalid session id")); @@ -278,7 +278,7 @@ protected virtual JToken TerminateSession(JArray _params) } [RpcMethod] - protected virtual JToken GetUnclaimedGas(JArray _params) + protected internal virtual JToken GetUnclaimedGas(JArray _params) { string address = Result.Ok_Or(() => _params[0].AsString(), RpcError.InvalidParams.WithData($"Invalid address {nameof(address)}")); JObject json = new(); diff --git a/src/Plugins/RpcServer/RpcServer.Wallet.cs b/src/Plugins/RpcServer/RpcServer.Wallet.cs index 155c56d91b..50f3c7a1e0 100644 --- a/src/Plugins/RpcServer/RpcServer.Wallet.cs +++ b/src/Plugins/RpcServer/RpcServer.Wallet.cs @@ -48,22 +48,36 @@ public override void Delete() { } public override void Save() { } } - protected Wallet wallet; + protected internal Wallet wallet; + /// + /// Checks if a wallet is open and throws an error if not. + /// private void CheckWallet() { wallet.NotNull_Or(RpcError.NoOpenedWallet); } + /// + /// Closes the currently opened wallet. + /// + /// An empty array. + /// Returns true if the wallet was successfully closed. [RpcMethod] - protected virtual JToken CloseWallet(JArray _params) + protected internal virtual JToken CloseWallet(JArray _params) { wallet = null; return true; } + /// + /// Exports the private key of a specified address. + /// + /// An array containing the address as a string. + /// The exported private key as a string. + /// Thrown when no wallet is open or the address is invalid. [RpcMethod] - protected virtual JToken DumpPrivKey(JArray _params) + protected internal virtual JToken DumpPrivKey(JArray _params) { CheckWallet(); UInt160 scriptHash = AddressToScriptHash(_params[0].AsString(), system.Settings.AddressVersion); @@ -71,8 +85,14 @@ protected virtual JToken DumpPrivKey(JArray _params) return account.GetKey().Export(); } + /// + /// Creates a new address in the wallet. + /// + /// An empty array. + /// The newly created address as a string. + /// Thrown when no wallet is open. [RpcMethod] - protected virtual JToken GetNewAddress(JArray _params) + protected internal virtual JToken GetNewAddress(JArray _params) { CheckWallet(); WalletAccount account = wallet.CreateAccount(); @@ -81,8 +101,14 @@ protected virtual JToken GetNewAddress(JArray _params) return account.Address; } + /// + /// Gets the balance of a specified asset in the wallet. + /// + /// An array containing the asset ID as a string. + /// A JSON object containing the balance of the specified asset. + /// Thrown when no wallet is open or the asset ID is invalid. [RpcMethod] - protected virtual JToken GetWalletBalance(JArray _params) + protected internal virtual JToken GetWalletBalance(JArray _params) { CheckWallet(); UInt160 asset_id = Result.Ok_Or(() => UInt160.Parse(_params[0].AsString()), RpcError.InvalidParams.WithData($"Invalid asset id: {_params[0]}")); @@ -91,8 +117,14 @@ protected virtual JToken GetWalletBalance(JArray _params) return json; } + /// + /// Gets the amount of unclaimed GAS in the wallet. + /// + /// An empty array. + /// The amount of unclaimed GAS as a string. + /// Thrown when no wallet is open. [RpcMethod] - protected virtual JToken GetWalletUnclaimedGas(JArray _params) + protected internal virtual JToken GetWalletUnclaimedGas(JArray _params) { CheckWallet(); // Datoshi is the smallest unit of GAS, 1 GAS = 10^8 Datoshi @@ -106,8 +138,14 @@ protected virtual JToken GetWalletUnclaimedGas(JArray _params) return datoshi.ToString(); } + /// + /// Imports a private key into the wallet. + /// + /// An array containing the private key as a string. + /// A JSON object containing information about the imported account. + /// Thrown when no wallet is open or the private key is invalid. [RpcMethod] - protected virtual JToken ImportPrivKey(JArray _params) + protected internal virtual JToken ImportPrivKey(JArray _params) { CheckWallet(); string privkey = _params[0].AsString(); @@ -123,10 +161,20 @@ protected virtual JToken ImportPrivKey(JArray _params) }; } + /// + /// Calculates the network fee for a given transaction. + /// + /// An array containing the Base64-encoded serialized transaction. + /// A JSON object containing the calculated network fee. + /// Thrown when the input parameters are invalid or the transaction is malformed. [RpcMethod] - protected virtual JToken CalculateNetworkFee(JArray _params) + protected internal virtual JToken CalculateNetworkFee(JArray _params) { - var tx = Convert.FromBase64String(_params[0].AsString()); + if (_params.Count == 0) + { + throw new RpcException(RpcError.InvalidParams.WithData("Params array is empty, need a raw transaction.")); + } + var tx = Result.Ok_Or(() => Convert.FromBase64String(_params[0].AsString()), RpcError.InvalidParams.WithData($"Invalid tx: {_params[0]}")); ; JObject account = new(); var networkfee = Wallets.Helper.CalculateNetworkFee( @@ -136,8 +184,14 @@ protected virtual JToken CalculateNetworkFee(JArray _params) return account; } + /// + /// Lists all addresses in the wallet. + /// + /// An empty array. + /// An array of JSON objects, each containing information about an address in the wallet. + /// Thrown when no wallet is open. [RpcMethod] - protected virtual JToken ListAddress(JArray _params) + protected internal virtual JToken ListAddress(JArray _params) { CheckWallet(); return wallet.GetAccounts().Select(p => @@ -151,16 +205,39 @@ protected virtual JToken ListAddress(JArray _params) }).ToArray(); } + /// + /// Opens a wallet file. + /// + /// An array containing the wallet path and password. + /// Returns true if the wallet was successfully opened. + /// Thrown when the wallet file is not found, the wallet is not supported, or the password is invalid. [RpcMethod] - protected virtual JToken OpenWallet(JArray _params) + protected internal virtual JToken OpenWallet(JArray _params) { string path = _params[0].AsString(); string password = _params[1].AsString(); File.Exists(path).True_Or(RpcError.WalletNotFound); - wallet = Wallet.Open(path, password, system.Settings).NotNull_Or(RpcError.WalletNotSupported); + try + { + wallet = Wallet.Open(path, password, system.Settings).NotNull_Or(RpcError.WalletNotSupported); + } + catch (NullReferenceException) + { + throw new RpcException(RpcError.WalletNotSupported); + } + catch (InvalidOperationException) + { + throw new RpcException(RpcError.WalletNotSupported.WithData("Invalid password.")); + } + return true; } + /// + /// Processes the result of an invocation with wallet for signing. + /// + /// The result object to process. + /// Optional signers for the transaction. private void ProcessInvokeWithWallet(JObject result, Signer[] signers = null) { if (wallet == null || signers == null || signers.Length == 0) return; @@ -189,8 +266,14 @@ private void ProcessInvokeWithWallet(JObject result, Signer[] signers = null) } } + /// + /// Transfers an asset from a specific address to another address. + /// + /// An array containing asset ID, from address, to address, amount, and optional signers. + /// The transaction details if successful, or the contract parameters if signatures are incomplete. + /// Thrown when no wallet is open, parameters are invalid, or there are insufficient funds. [RpcMethod] - protected virtual JToken SendFrom(JArray _params) + protected internal virtual JToken SendFrom(JArray _params) { CheckWallet(); UInt160 assetId = Result.Ok_Or(() => UInt160.Parse(_params[0].AsString()), RpcError.InvalidParams.WithData($"Invalid asset id: {_params[0]}")); @@ -202,7 +285,7 @@ protected virtual JToken SendFrom(JArray _params) (amount.Sign > 0).True_Or(RpcErrorFactory.InvalidParams("Amount can't be negative.")); Signer[] signers = _params.Count >= 5 ? ((JArray)_params[4]).Select(p => new Signer() { Account = AddressToScriptHash(p.AsString(), system.Settings.AddressVersion), Scopes = WitnessScope.CalledByEntry }).ToArray() : null; - Transaction tx = wallet.MakeTransaction(snapshot, new[] + Transaction tx = Result.Ok_Or(() => wallet.MakeTransaction(snapshot, new[] { new TransferOutput { @@ -210,7 +293,7 @@ protected virtual JToken SendFrom(JArray _params) Value = amount, ScriptHash = to } - }, from, signers).NotNull_Or(RpcError.InsufficientFunds); + }, from, signers), RpcError.InvalidRequest.WithData("Can not process this request.")).NotNull_Or(RpcError.InsufficientFunds); ContractParametersContext transContext = new(snapshot, tx, settings.Network); wallet.Sign(transContext); @@ -227,8 +310,37 @@ protected virtual JToken SendFrom(JArray _params) return SignAndRelay(snapshot, tx); } + /// + /// Transfers assets to multiple addresses. + /// + /// + /// An array containing the following elements: + /// [0] (optional): The address to send from as a string. If omitted, the assets will be sent from any address in the wallet. + /// [1]: An array of transfer objects, each containing: + /// - "asset": The asset ID (UInt160) as a string. + /// - "value": The amount to transfer as a string. + /// - "address": The recipient address as a string. + /// [2] (optional): An array of signers, each containing: + /// - The address of the signer as a string. + /// + /// + /// If the transaction is successfully created and all signatures are present: + /// Returns a JSON object representing the transaction. + /// If not all signatures are present: + /// Returns a JSON object representing the contract parameters that need to be signed. + /// + /// + /// Thrown when: + /// - No wallet is open. + /// - The 'to' parameter is invalid or empty. + /// - Any of the asset IDs are invalid. + /// - Any of the amounts are negative or invalid. + /// - Any of the addresses are invalid. + /// - There are insufficient funds for the transfer. + /// - The network fee exceeds the maximum allowed fee. + /// [RpcMethod] - protected virtual JToken SendMany(JArray _params) + protected internal virtual JToken SendMany(JArray _params) { CheckWallet(); int to_start = 0; @@ -273,8 +385,14 @@ protected virtual JToken SendMany(JArray _params) return SignAndRelay(snapshot, tx); } + /// + /// Transfers an asset to a specific address. + /// + /// An array containing asset ID, to address, and amount. + /// The transaction details if successful, or the contract parameters if signatures are incomplete. + /// Thrown when no wallet is open, parameters are invalid, or there are insufficient funds. [RpcMethod] - protected virtual JToken SendToAddress(JArray _params) + protected internal virtual JToken SendToAddress(JArray _params) { CheckWallet(); UInt160 assetId = Result.Ok_Or(() => UInt160.Parse(_params[0].AsString()), RpcError.InvalidParams.WithData($"Invalid asset hash: {_params[0]}")); @@ -308,8 +426,14 @@ protected virtual JToken SendToAddress(JArray _params) return SignAndRelay(snapshot, tx); } + /// + /// Cancels an unconfirmed transaction. + /// + /// An array containing the transaction ID to cancel, signers, and optional extra fee. + /// The details of the cancellation transaction. + /// Thrown when no wallet is open, the transaction is already confirmed, or there are insufficient funds for the cancellation fee. [RpcMethod] - protected virtual JToken CancelTransaction(JArray _params) + protected internal virtual JToken CancelTransaction(JArray _params) { CheckWallet(); var txid = Result.Ok_Or(() => UInt256.Parse(_params[0].AsString()), RpcError.InvalidParams.WithData($"Invalid txid: {_params[0]}")); @@ -342,8 +466,14 @@ protected virtual JToken CancelTransaction(JArray _params) return SignAndRelay(system.StoreView, tx); } + /// + /// Invokes the verify method of a contract. + /// + /// An array containing the script hash, optional arguments, and optional signers and witnesses. + /// A JSON object containing the result of the verification. + /// Thrown when the script hash is invalid, the contract is not found, or the verification fails. [RpcMethod] - protected virtual JToken InvokeContractVerify(JArray _params) + protected internal virtual JToken InvokeContractVerify(JArray _params) { UInt160 script_hash = Result.Ok_Or(() => UInt160.Parse(_params[0].AsString()), RpcError.InvalidParams.WithData($"Invalid script hash: {_params[0]}")); ContractParameter[] args = _params.Count >= 2 ? ((JArray)_params[1]).Select(p => ContractParameter.FromJson((JObject)p)).ToArray() : Array.Empty(); @@ -352,6 +482,14 @@ protected virtual JToken InvokeContractVerify(JArray _params) return GetVerificationResult(script_hash, args, signers, witnesses); } + /// + /// Gets the result of the contract verification. + /// + /// The script hash of the contract. + /// The contract parameters. + /// Optional signers for the verification. + /// Optional witnesses for the verification. + /// A JSON object containing the verification result. private JObject GetVerificationResult(UInt160 scriptHash, ContractParameter[] args, Signer[] signers = null, Witness[] witnesses = null) { using var snapshot = system.GetSnapshotCache(); @@ -396,6 +534,12 @@ private JObject GetVerificationResult(UInt160 scriptHash, ContractParameter[] ar return json; } + /// + /// Signs and relays a transaction. + /// + /// The data snapshot. + /// The transaction to sign and relay. + /// A JSON object containing the transaction details. private JObject SignAndRelay(DataCache snapshot, Transaction tx) { ContractParametersContext context = new(snapshot, tx, settings.Network); @@ -412,6 +556,12 @@ private JObject SignAndRelay(DataCache snapshot, Transaction tx) } } + /// + /// Converts an address to a script hash. + /// + /// The address to convert. + /// The address version. + /// The script hash corresponding to the address. internal static UInt160 AddressToScriptHash(string address, byte version) { if (UInt160.TryParse(address, out var scriptHash)) diff --git a/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Wallet.cs b/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Wallet.cs new file mode 100644 index 0000000000..2db71ae570 --- /dev/null +++ b/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Wallet.cs @@ -0,0 +1,403 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// UT_RpcServer.Wallet.cs file belongs to the neo project and is free +// software distributed under the MIT software license, see the +// accompanying file LICENSE in the main directory of the +// repository or http://www.opensource.org/licenses/mit-license.php +// for more details. +// +// Redistribution and use in source and binary forms with or without +// modifications are permitted. + +using FluentAssertions; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.IO; +using Neo.Json; +using Neo.Network.P2P.Payloads; +using Neo.SmartContract; +using Neo.SmartContract.Native; +using Neo.UnitTests; +using Neo.UnitTests.Extensions; +using System; +using System.IO; +using System.Linq; + +namespace Neo.Plugins.RpcServer.Tests; + +partial class UT_RpcServer +{ + [TestMethod] + public void TestOpenWallet() + { + const string Path = "wallet.json"; + const string Password = "123456"; + File.WriteAllText(Path, "{\"name\":null,\"version\":\"1.0\",\"scrypt\":{\"n\":16384,\"r\":8,\"p\":8},\"accounts\":[{\"address\":\"NVizn8DiExdmnpTQfjiVY3dox8uXg3Vrxv\",\"label\":null,\"isDefault\":false,\"lock\":false,\"key\":\"6PYPMrsCJ3D4AXJCFWYT2WMSBGF7dLoaNipW14t4UFAkZw3Z9vQRQV1bEU\",\"contract\":{\"script\":\"DCEDaR\\u002BFVb8lOdiMZ/wCHLiI\\u002Bzuf17YuGFReFyHQhB80yMpBVuezJw==\",\"parameters\":[{\"name\":\"signature\",\"type\":\"Signature\"}],\"deployed\":false},\"extra\":null}],\"extra\":null}"); + var paramsArray = new JArray(Path, Password); + var res = _rpcServer.OpenWallet(paramsArray); + Assert.IsTrue(res.AsBoolean()); + Assert.IsNotNull(_rpcServer.wallet); + Assert.AreEqual(_rpcServer.wallet.GetAccounts().FirstOrDefault()!.Address, "NVizn8DiExdmnpTQfjiVY3dox8uXg3Vrxv"); + _rpcServer.CloseWallet([]); + File.Delete(Path); + Assert.IsNull(_rpcServer.wallet); + } + + [TestMethod] + public void TestOpenInvalidWallet() + { + const string Path = "wallet.json"; + const string Password = "password"; + File.Delete(Path); + var paramsArray = new JArray(Path, Password); + var exception = Assert.ThrowsException(() => _rpcServer.OpenWallet(paramsArray), "Should throw RpcException for unsupported wallet"); + Assert.AreEqual(RpcError.WalletNotFound.Code, exception.HResult); + + File.WriteAllText(Path, "{}"); + exception = Assert.ThrowsException(() => _rpcServer.OpenWallet(paramsArray), "Should throw RpcException for unsupported wallet"); + File.Delete(Path); + Assert.AreEqual(RpcError.WalletNotSupported.Code, exception.HResult); + var result = _rpcServer.CloseWallet(new JArray()); + Assert.IsTrue(result.AsBoolean()); + Assert.IsNull(_rpcServer.wallet); + + File.WriteAllText(Path, "{\"name\":null,\"version\":\"1.0\",\"scrypt\":{\"n\":16384,\"r\":8,\"p\":8},\"accounts\":[{\"address\":\"NVizn8DiExdmnpTQfjiVY3dox8uXg3Vrxv\",\"label\":null,\"isDefault\":false,\"lock\":false,\"key\":\"6PYPMrsCJ3D4AXJCFWYT2WMSBGF7dLoaNipW14t4UFAkZw3Z9vQRQV1bEU\",\"contract\":{\"script\":\"DCEDaR\\u002BFVb8lOdiMZ/wCHLiI\\u002Bzuf17YuGFReFyHQhB80yMpBVuezJw==\",\"parameters\":[{\"name\":\"signature\",\"type\":\"Signature\"}],\"deployed\":false},\"extra\":null}],\"extra\":null}"); + exception = Assert.ThrowsException(() => _rpcServer.OpenWallet(paramsArray), "Should throw RpcException for unsupported wallet"); + Assert.AreEqual(RpcError.WalletNotSupported.Code, exception.HResult); + Assert.AreEqual(exception.Message, "Wallet not supported - Invalid password."); + File.Delete(Path); + } + + [TestMethod] + public void TestDumpPrivKey() + { + TestUtilOpenWallet(); + var account = _rpcServer.wallet.GetAccounts().FirstOrDefault(); + Assert.IsNotNull(account); + var privKey = account.GetKey().Export(); + var address = account.Address; + var result = _rpcServer.DumpPrivKey(new JArray(address)); + Assert.AreEqual(privKey, result.AsString()); + TestUtilCloseWallet(); + } + + [TestMethod] + public void TestGetNewAddress() + { + TestUtilOpenWallet(); + var result = _rpcServer.GetNewAddress([]); + Assert.IsInstanceOfType(result, typeof(JString)); + Assert.IsTrue(_rpcServer.wallet.GetAccounts().Any(a => a.Address == result.AsString())); + TestUtilCloseWallet(); + } + + [TestMethod] + public void TestGetWalletBalance() + { + TestUtilOpenWallet(); + var assetId = NativeContract.NEO.Hash; + var paramsArray = new JArray(assetId.ToString()); + var result = _rpcServer.GetWalletBalance(paramsArray); + Assert.IsInstanceOfType(result, typeof(JObject)); + var json = (JObject)result; + Assert.IsTrue(json.ContainsProperty("balance")); + TestUtilCloseWallet(); + } + + [TestMethod] + public void TestGetWalletBalanceInvalidAsset() + { + TestUtilOpenWallet(); + var assetId = UInt160.Zero; + var paramsArray = new JArray(assetId.ToString()); + var result = _rpcServer.GetWalletBalance(paramsArray); + Assert.IsInstanceOfType(result, typeof(JObject)); + var json = (JObject)result; + Assert.IsTrue(json.ContainsProperty("balance")); + TestUtilCloseWallet(); + } + + [TestMethod] + public void TestGetWalletUnclaimedGas() + { + TestUtilOpenWallet(); + var result = _rpcServer.GetWalletUnclaimedGas([]); + Assert.IsInstanceOfType(result, typeof(JString)); + TestUtilCloseWallet(); + } + + [TestMethod] + public void TestImportPrivKey() + { + TestUtilOpenWallet(); + var privKey = _walletAccount.GetKey().Export(); + var paramsArray = new JArray(privKey); + var result = _rpcServer.ImportPrivKey(paramsArray); + Assert.IsInstanceOfType(result, typeof(JObject)); + var json = (JObject)result; + Assert.IsTrue(json.ContainsProperty("address")); + Assert.IsTrue(json.ContainsProperty("haskey")); + Assert.IsTrue(json.ContainsProperty("label")); + Assert.IsTrue(json.ContainsProperty("watchonly")); + TestUtilCloseWallet(); + } + + [TestMethod] + public void TestImportPrivKeyNoWallet() + { + var privKey = _walletAccount.GetKey().Export(); + var paramsArray = new JArray(privKey); + var exception = Assert.ThrowsException(() => _rpcServer.ImportPrivKey(paramsArray)); + Assert.AreEqual(exception.HResult, RpcError.NoOpenedWallet.Code); + } + + [TestMethod] + public void TestCalculateNetworkFee() + { + var snapshot = _neoSystem.GetSnapshot(); + var tx = TestUtils.CreateValidTx(snapshot, _wallet, _walletAccount); + var txBase64 = Convert.ToBase64String(tx.ToArray()); + var paramsArray = new JArray(txBase64); + var result = _rpcServer.CalculateNetworkFee(paramsArray); + Assert.IsInstanceOfType(result, typeof(JObject)); + var json = (JObject)result; + Assert.IsTrue(json.ContainsProperty("networkfee")); + } + + [TestMethod] + public void TestCalculateNetworkFeeNoParam() + { + var exception = Assert.ThrowsException(() => _rpcServer.CalculateNetworkFee([])); + Assert.AreEqual(exception.HResult, RpcError.InvalidParams.Code); + } + + [TestMethod] + public void TestListAddressNoWallet() + { + var exception = Assert.ThrowsException(() => _rpcServer.ListAddress([])); + Assert.AreEqual(exception.HResult, RpcError.NoOpenedWallet.Code); + } + + [TestMethod] + public void TestListAddress() + { + TestUtilOpenWallet(); + var result = _rpcServer.ListAddress([]); + Assert.IsInstanceOfType(result, typeof(JArray)); + var json = (JArray)result; + Assert.IsTrue(json.Count > 0); + TestUtilCloseWallet(); + } + + [TestMethod] + public void TestSendFromNoWallet() + { + var assetId = NativeContract.GAS.Hash; + var from = _walletAccount.Address; + var to = _walletAccount.Address; + var amount = "1"; + var paramsArray = new JArray(assetId.ToString(), from, to, amount); + var exception = Assert.ThrowsException(() => _rpcServer.SendFrom(paramsArray), "Should throw RpcException for insufficient funds"); + Assert.AreEqual(exception.HResult, RpcError.NoOpenedWallet.Code); + } + + [TestMethod] + public void TestSendFrom() + { + TestUtilOpenWallet(); + var assetId = NativeContract.GAS.Hash; + var from = _walletAccount.Address; + var to = _walletAccount.Address; + var amount = "1"; + var paramsArray = new JArray(assetId.ToString(), from, to, amount); + var exception = Assert.ThrowsException(() => _rpcServer.SendFrom(paramsArray)); + Assert.AreEqual(exception.HResult, RpcError.InvalidRequest.Code); + TestUtilCloseWallet(); + } + + [TestMethod] + public void TestSendMany() + { + var from = _walletAccount.Address; + var to = new JArray { new JObject { ["asset"] = NativeContract.GAS.Hash.ToString(), ["value"] = "1", ["address"] = _walletAccount.Address } }; + var paramsArray = new JArray(from, to); + var exception = Assert.ThrowsException(() => _rpcServer.SendMany(paramsArray), "Should throw RpcException for insufficient funds"); + Assert.AreEqual(exception.HResult, RpcError.NoOpenedWallet.Code); + } + + [TestMethod] + public void TestSendToAddress() + { + var assetId = NativeContract.GAS.Hash; + var to = _walletAccount.Address; + var amount = "1"; + var paramsArray = new JArray(assetId.ToString(), to, amount); + var exception = Assert.ThrowsException(() => _rpcServer.SendToAddress(paramsArray), "Should throw RpcException for insufficient funds"); + Assert.AreEqual(exception.HResult, RpcError.NoOpenedWallet.Code); + } + + [TestMethod] + public void TestCloseWallet_WhenWalletNotOpen() + { + _rpcServer.wallet = null; + var result = _rpcServer.CloseWallet(new JArray()); + Assert.IsTrue(result.AsBoolean()); + } + + [TestMethod] + public void TestDumpPrivKey_WhenWalletNotOpen() + { + _rpcServer.wallet = null; + var exception = Assert.ThrowsException(() => _rpcServer.DumpPrivKey(new JArray(_walletAccount.Address)), "Should throw RpcException for no opened wallet"); + Assert.AreEqual(exception.HResult, RpcError.NoOpenedWallet.Code); + } + + [TestMethod] + public void TestGetNewAddress_WhenWalletNotOpen() + { + _rpcServer.wallet = null; + var exception = Assert.ThrowsException(() => _rpcServer.GetNewAddress(new JArray()), "Should throw RpcException for no opened wallet"); + Assert.AreEqual(exception.HResult, RpcError.NoOpenedWallet.Code); + } + + [TestMethod] + public void TestGetWalletBalance_WhenWalletNotOpen() + { + _rpcServer.wallet = null; + var exception = Assert.ThrowsException(() => _rpcServer.GetWalletBalance(new JArray(NativeContract.NEO.Hash.ToString())), "Should throw RpcException for no opened wallet"); + Assert.AreEqual(exception.HResult, RpcError.NoOpenedWallet.Code); + } + + [TestMethod] + public void TestGetWalletUnclaimedGas_WhenWalletNotOpen() + { + _rpcServer.wallet = null; + var exception = Assert.ThrowsException(() => _rpcServer.GetWalletUnclaimedGas(new JArray()), "Should throw RpcException for no opened wallet"); + Assert.AreEqual(exception.HResult, RpcError.NoOpenedWallet.Code); + } + + [TestMethod] + public void TestImportPrivKey_WhenWalletNotOpen() + { + _rpcServer.wallet = null; + var privKey = _walletAccount.GetKey().Export(); + var exception = Assert.ThrowsException(() => _rpcServer.ImportPrivKey(new JArray(privKey)), "Should throw RpcException for no opened wallet"); + Assert.AreEqual(exception.HResult, RpcError.NoOpenedWallet.Code); + } + + [TestMethod] + public void TestCalculateNetworkFee_InvalidTransactionFormat() + { + var invalidTxBase64 = "invalid_base64"; + var paramsArray = new JArray(invalidTxBase64); + var exception = Assert.ThrowsException(() => _rpcServer.CalculateNetworkFee(paramsArray), "Should throw RpcException for invalid transaction format"); + Assert.AreEqual(exception.HResult, RpcError.InvalidParams.Code); + } + + [TestMethod] + public void TestListAddress_WhenWalletNotOpen() + { + // Ensure the wallet is not open + _rpcServer.wallet = null; + + // Attempt to call ListAddress and expect an RpcException + var exception = Assert.ThrowsException(() => _rpcServer.ListAddress(new JArray())); + + // Verify the exception has the expected error code + Assert.AreEqual(RpcError.NoOpenedWallet.Code, exception.HResult); + } + + [TestMethod] + public void TestCancelTransaction() + { + TestUtilOpenWallet(); + var snapshot = _neoSystem.GetSnapshot(); + var tx = TestUtils.CreateValidTx(snapshot, _wallet, _walletAccount); + snapshot.Commit(); + var paramsArray = new JArray(tx.Hash.ToString(), new JArray(_walletAccount.Address)); + var exception = Assert.ThrowsException(() => _rpcServer.CancelTransaction(paramsArray), "Should throw RpcException for non-existing transaction"); + + Assert.AreEqual(RpcError.InsufficientFunds.Code, exception.HResult); + + // Test with invalid transaction id + var invalidParamsArray = new JArray("invalid_txid", new JArray(_walletAccount.Address)); + exception = Assert.ThrowsException(() => _rpcServer.CancelTransaction(invalidParamsArray), "Should throw RpcException for invalid txid"); + Assert.AreEqual(exception.HResult, RpcError.InvalidParams.Code); + + // Test with no signer + invalidParamsArray = new JArray(tx.Hash.ToString()); + exception = Assert.ThrowsException(() => _rpcServer.CancelTransaction(invalidParamsArray), "Should throw RpcException for invalid txid"); + Assert.AreEqual(exception.HResult, RpcError.BadRequest.Code); + + // Test with null wallet + _rpcServer.wallet = null; + exception = Assert.ThrowsException(() => _rpcServer.CancelTransaction(paramsArray), "Should throw RpcException for no opened wallet"); + Assert.AreEqual(exception.HResult, RpcError.NoOpenedWallet.Code); + TestUtilCloseWallet(); + } + + [TestMethod] + public void TestInvokeContractVerify() + { + var scriptHash = UInt160.Parse("0x70cde1619e405cdef363ab66a1e8dce430d798d5"); + var paramsArray = new JArray(scriptHash.ToString()); + var exception = Assert.ThrowsException(() => _rpcServer.InvokeContractVerify(paramsArray), "Should throw RpcException for unknown contract"); + Assert.AreEqual(exception.HResult, RpcError.UnknownContract.Code); + // Test with invalid script hash + var invalidParamsArray = new JArray("invalid_script_hash"); + exception = Assert.ThrowsException(() => _rpcServer.InvokeContractVerify(invalidParamsArray), "Should throw RpcException for invalid script hash"); + Assert.AreEqual(exception.HResult, RpcError.InvalidParams.Code); + } + + + private void TestUtilOpenWallet() + { + try + { + const string Path = "wallet.json"; + const string Password = "123456"; + File.WriteAllText(Path, "{\"name\":null,\"version\":\"1.0\",\"scrypt\":{\"n\":16384,\"r\":8,\"p\":8},\"accounts\":[{\"address\":\"NVizn8DiExdmnpTQfjiVY3dox8uXg3Vrxv\",\"label\":null,\"isDefault\":false,\"lock\":false,\"key\":\"6PYPMrsCJ3D4AXJCFWYT2WMSBGF7dLoaNipW14t4UFAkZw3Z9vQRQV1bEU\",\"contract\":{\"script\":\"DCEDaR\\u002BFVb8lOdiMZ/wCHLiI\\u002Bzuf17YuGFReFyHQhB80yMpBVuezJw==\",\"parameters\":[{\"name\":\"signature\",\"type\":\"Signature\"}],\"deployed\":false},\"extra\":null}],\"extra\":null}"); + var paramsArray = new JArray(Path, Password); + _rpcServer.OpenWallet(paramsArray); + } + catch (Exception e) + { + Console.WriteLine(e); + } + } + + private void TestUtilCloseWallet() + { + try + { + const string Path = "wallet.json"; + _rpcServer.CloseWallet([]); + File.Delete(Path); + } + catch (Exception e) + { + Console.WriteLine(e); + } + } + + private UInt160 TestUtilAddTestContract() + { + var state = TestUtils.GetContract(); + + var storageKey = new StorageKey + { + Id = state.Id, + Key = new byte[] { 0x01 } + }; + + var storageItem = new StorageItem + { + Value = new byte[] { 0x01, 0x02, 0x03, 0x04 } + }; + + var snapshot = _neoSystem.GetSnapshotCache(); + snapshot.AddContract(state.Hash, state); + snapshot.Add(storageKey, storageItem); + snapshot.Commit(); + return state.Hash; + } +} diff --git a/tests/Neo.UnitTests/TestUtils.Contract.cs b/tests/Neo.UnitTests/TestUtils.Contract.cs new file mode 100644 index 0000000000..da3139561c --- /dev/null +++ b/tests/Neo.UnitTests/TestUtils.Contract.cs @@ -0,0 +1,105 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// TestUtils.Contract.cs file belongs to the neo project and is free +// software distributed under the MIT software license, see the +// accompanying file LICENSE in the main directory of the +// repository or http://www.opensource.org/licenses/mit-license.php +// for more details. +// +// Redistribution and use in source and binary forms with or without +// modifications are permitted. + +using Neo.SmartContract; +using Neo.SmartContract.Manifest; +using System; +using System.Linq; + +namespace Neo.UnitTests; + +partial class TestUtils +{ + public static ContractManifest CreateDefaultManifest() + { + return new ContractManifest + { + Name = "testManifest", + Groups = [], + SupportedStandards = [], + Abi = new ContractAbi + { + Events = [], + Methods = + [ + new ContractMethodDescriptor + { + Name = "testMethod", + Parameters = [], + ReturnType = ContractParameterType.Void, + Offset = 0, + Safe = true + } + ] + }, + Permissions = [ContractPermission.DefaultPermission], + Trusts = WildcardContainer.Create(), + Extra = null + }; + } + + public static ContractManifest CreateManifest(string method, ContractParameterType returnType, params ContractParameterType[] parameterTypes) + { + var manifest = CreateDefaultManifest(); + manifest.Abi.Methods = + [ + new ContractMethodDescriptor() + { + Name = method, + Parameters = parameterTypes.Select((p, i) => new ContractParameterDefinition + { + Name = $"p{i}", + Type = p + }).ToArray(), + ReturnType = returnType + } + ]; + return manifest; + } + + public static ContractState GetContract(string method = "test", int parametersCount = 0) + { + NefFile nef = new() + { + Compiler = "", + Source = "", + Tokens = [], + Script = new byte[] { 0x01, 0x01, 0x01, 0x01 } + }; + nef.CheckSum = NefFile.ComputeChecksum(nef); + return new ContractState + { + Id = 0x43000000, + Nef = nef, + Hash = nef.Script.Span.ToScriptHash(), + Manifest = CreateManifest(method, ContractParameterType.Any, Enumerable.Repeat(ContractParameterType.Any, parametersCount).ToArray()) + }; + } + + internal static ContractState GetContract(byte[] script, ContractManifest manifest = null) + { + NefFile nef = new() + { + Compiler = "", + Source = "", + Tokens = [], + Script = script + }; + nef.CheckSum = NefFile.ComputeChecksum(nef); + return new ContractState + { + Id = 1, + Hash = script.ToScriptHash(), + Nef = nef, + Manifest = manifest ?? CreateDefaultManifest() + }; + } +} diff --git a/tests/Neo.UnitTests/TestUtils.Transaction.cs b/tests/Neo.UnitTests/TestUtils.Transaction.cs index f96ac8ec74..f6d6ebd4b5 100644 --- a/tests/Neo.UnitTests/TestUtils.Transaction.cs +++ b/tests/Neo.UnitTests/TestUtils.Transaction.cs @@ -11,6 +11,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography; +using Neo.Cryptography.ECC; using Neo.IO; using Neo.Network.P2P.Payloads; using Neo.Persistence; @@ -22,11 +23,112 @@ using System; using System.IO; using System.Linq; +using System.Numerics; namespace Neo.UnitTests; public partial class TestUtils { + public static Transaction CreateValidTx(DataCache snapshot, NEP6Wallet wallet, WalletAccount account) + { + return CreateValidTx(snapshot, wallet, account.ScriptHash, (uint)new Random().Next()); + } + + public static Transaction CreateValidTx(DataCache snapshot, NEP6Wallet wallet, UInt160 account, uint nonce) + { + var tx = wallet.MakeTransaction(snapshot, [ + new TransferOutput + { + AssetId = NativeContract.GAS.Hash, + ScriptHash = account, + Value = new BigDecimal(BigInteger.One, 8) + } + ], + account); + + tx.Nonce = nonce; + tx.Signers = [new Signer { Account = account, Scopes = WitnessScope.CalledByEntry }]; + var data = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network); + Assert.IsNull(data.GetSignatures(tx.Sender)); + Assert.IsTrue(wallet.Sign(data)); + Assert.IsTrue(data.Completed); + Assert.AreEqual(1, data.GetSignatures(tx.Sender).Count); + + tx.Witnesses = data.GetWitnesses(); + return tx; + } + + public static Transaction CreateValidTx(DataCache snapshot, NEP6Wallet wallet, UInt160 account, uint nonce, UInt256[] conflicts) + { + var tx = wallet.MakeTransaction(snapshot, [ + new TransferOutput + { + AssetId = NativeContract.GAS.Hash, + ScriptHash = account, + Value = new BigDecimal(BigInteger.One, 8) + } + ], + account); + tx.Attributes = conflicts.Select(conflict => new Conflicts { Hash = conflict }).ToArray(); + tx.Nonce = nonce; + tx.Signers = [new Signer { Account = account, Scopes = WitnessScope.CalledByEntry }]; + var data = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network); + Assert.IsNull(data.GetSignatures(tx.Sender)); + Assert.IsTrue(wallet.Sign(data)); + Assert.IsTrue(data.Completed); + Assert.AreEqual(1, data.GetSignatures(tx.Sender).Count); + tx.Witnesses = data.GetWitnesses(); + return tx; + } + + public static Transaction CreateRandomHashTransaction() + { + var randomBytes = new byte[16]; + TestRandom.NextBytes(randomBytes); + return new Transaction + { + Script = randomBytes, + Attributes = [], + Signers = [new Signer { Account = UInt160.Zero }], + Witnesses = + [ + new Witness + { + InvocationScript = Array.Empty(), + VerificationScript = Array.Empty() + } + ] + }; + } + + public static Transaction GetTransaction(UInt160 sender) + { + return new Transaction + { + Script = new[] { (byte)OpCode.PUSH2 }, + Attributes = [], + Signers = + [ + new Signer + { + Account = sender, + Scopes = WitnessScope.CalledByEntry, + AllowedContracts = [], + AllowedGroups = [], + Rules = [], + } + ], + Witnesses = + [ + new Witness + { + InvocationScript = Array.Empty(), + VerificationScript = Array.Empty() + } + ] + }; + } + public static Transaction CreateInvalidTransaction(DataCache snapshot, NEP6Wallet wallet, WalletAccount account, InvalidTransactionType type, UInt256 conflict = null) { var rand = new Random(); diff --git a/tests/Neo.UnitTests/TestUtils.cs b/tests/Neo.UnitTests/TestUtils.cs index c1694347a7..a9ad4d8ff7 100644 --- a/tests/Neo.UnitTests/TestUtils.cs +++ b/tests/Neo.UnitTests/TestUtils.cs @@ -48,53 +48,6 @@ public static UInt160 RandomUInt160() return new UInt160(data); } - public static ContractManifest CreateDefaultManifest() - { - return new ContractManifest() - { - Name = "testManifest", - Groups = new ContractGroup[0], - SupportedStandards = Array.Empty(), - Abi = new ContractAbi() - { - Events = new ContractEventDescriptor[0], - Methods = new[] - { - new ContractMethodDescriptor - { - Name = "testMethod", - Parameters = new ContractParameterDefinition[0], - ReturnType = ContractParameterType.Void, - Offset = 0, - Safe = true - } - } - }, - Permissions = new[] { ContractPermission.DefaultPermission }, - Trusts = WildcardContainer.Create(), - Extra = null - }; - } - - public static ContractManifest CreateManifest(string method, ContractParameterType returnType, params ContractParameterType[] parameterTypes) - { - ContractManifest manifest = CreateDefaultManifest(); - manifest.Abi.Methods = new ContractMethodDescriptor[] - { - new ContractMethodDescriptor() - { - Name = method, - Parameters = parameterTypes.Select((p, i) => new ContractParameterDefinition - { - Name = $"p{i}", - Type = p - }).ToArray(), - ReturnType = returnType - } - }; - return manifest; - } - public static StorageKey CreateStorageKey(this NativeContract contract, byte prefix, ISerializable key = null) { var k = new KeyBuilder(contract.Id, prefix); @@ -130,118 +83,6 @@ public static NEP6Wallet GenerateTestWallet(string password) return new NEP6Wallet(null, password, TestProtocolSettings.Default, wallet); } - public static Transaction CreateValidTx(DataCache snapshot, NEP6Wallet wallet, WalletAccount account) - { - return CreateValidTx(snapshot, wallet, account.ScriptHash, (uint)new Random().Next()); - } - - public static Transaction CreateValidTx(DataCache snapshot, NEP6Wallet wallet, UInt160 account, uint nonce) - { - var tx = wallet.MakeTransaction(snapshot, [ - new TransferOutput - { - AssetId = NativeContract.GAS.Hash, - ScriptHash = account, - Value = new BigDecimal(BigInteger.One, 8) - } - ], - account); - - tx.Nonce = nonce; - - var data = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network); - Assert.IsNull(data.GetSignatures(tx.Sender)); - Assert.IsTrue(wallet.Sign(data)); - Assert.IsTrue(data.Completed); - Assert.AreEqual(1, data.GetSignatures(tx.Sender).Count()); - - tx.Witnesses = data.GetWitnesses(); - return tx; - } - - public static Transaction CreateValidTx(DataCache snapshot, NEP6Wallet wallet, UInt160 account, uint nonce, UInt256[] conflicts) - { - var tx = wallet.MakeTransaction(snapshot, [ - new TransferOutput - { - AssetId = NativeContract.GAS.Hash, - ScriptHash = account, - Value = new BigDecimal(BigInteger.One, 8) - } - ], - account); - tx.Attributes = conflicts.Select(conflict => new Conflicts { Hash = conflict }).ToArray(); - tx.Nonce = nonce; - - var data = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network); - Assert.IsNull(data.GetSignatures(tx.Sender)); - Assert.IsTrue(wallet.Sign(data)); - Assert.IsTrue(data.Completed); - Assert.AreEqual(1, data.GetSignatures(tx.Sender).Count); - tx.Witnesses = data.GetWitnesses(); - return tx; - } - - public static Transaction GetTransaction(UInt160 sender) - { - return new Transaction - { - Script = new byte[] { (byte)OpCode.PUSH2 }, - Attributes = Array.Empty(), - Signers = new[]{ new Signer() - { - Account = sender, - Scopes = WitnessScope.CalledByEntry, - AllowedContracts = Array.Empty(), - AllowedGroups = Array.Empty(), - Rules = Array.Empty(), - } }, - Witnesses = new Witness[]{ new Witness - { - InvocationScript = Array.Empty(), - VerificationScript = Array.Empty() - } } - }; - } - - public static ContractState GetContract(string method = "test", int parametersCount = 0) - { - NefFile nef = new() - { - Compiler = "", - Source = "", - Tokens = Array.Empty(), - Script = new byte[] { 0x01, 0x01, 0x01, 0x01 } - }; - nef.CheckSum = NefFile.ComputeChecksum(nef); - return new ContractState - { - Id = 0x43000000, - Nef = nef, - Hash = nef.Script.Span.ToScriptHash(), - Manifest = CreateManifest(method, ContractParameterType.Any, Enumerable.Repeat(ContractParameterType.Any, parametersCount).ToArray()) - }; - } - - internal static ContractState GetContract(byte[] script, ContractManifest manifest = null) - { - NefFile nef = new() - { - Compiler = "", - Source = "", - Tokens = Array.Empty(), - Script = script - }; - nef.CheckSum = NefFile.ComputeChecksum(nef); - return new ContractState - { - Id = 1, - Hash = script.ToScriptHash(), - Nef = nef, - Manifest = manifest ?? CreateDefaultManifest() - }; - } - internal static StorageItem GetStorageItem(byte[] value) { return new StorageItem @@ -268,26 +109,6 @@ public static void StorageItemAdd(DataCache snapshot, int id, byte[] keyValue, b }, new StorageItem(value)); } - public static Transaction CreateRandomHashTransaction() - { - var randomBytes = new byte[16]; - TestRandom.NextBytes(randomBytes); - return new Transaction - { - Script = randomBytes, - Attributes = Array.Empty(), - Signers = new Signer[] { new Signer() { Account = UInt160.Zero } }, - Witnesses = new[] - { - new Witness - { - InvocationScript = new byte[0], - VerificationScript = new byte[0] - } - } - }; - } - public static void FillMemoryPool(DataCache snapshot, NeoSystem system, NEP6Wallet wallet, WalletAccount account) { for (int i = 0; i < system.Settings.MemoryPoolMaxTransactions; i++)