From afa99ca807336644f8da2a3aacafecf1c77086dc Mon Sep 17 00:00:00 2001 From: Jimmy Date: Fri, 15 Nov 2024 23:39:50 +0800 Subject: [PATCH 01/36] adopt light gc --- benchmarks/Neo.VM.Benchmarks/TestArray.cs | 26 +---- benchmarks/Neo.VM.Benchmarks/TestStruct.cs | 18 +-- .../VMTypes/Benchmarks_Convert.cs | 14 +-- .../VMTypes/Benchmarks_DeepCopy.cs | 28 ++--- src/Neo.VM/ExecutionEngine.cs | 5 +- src/Neo.VM/JumpTable/JumpTable.Compound.cs | 46 ++++++-- src/Neo.VM/ReferenceCounterV2.cs | 105 ++++++++++++++++++ src/Neo.VM/Types/Array.cs | 35 +----- src/Neo.VM/Types/CompoundType.cs | 2 - src/Neo.VM/Types/Map.cs | 22 +--- src/Neo.VM/Types/Struct.cs | 6 +- .../P2P/Payloads/Conditions/AndCondition.cs | 2 +- .../P2P/Payloads/Conditions/OrCondition.cs | 2 +- .../Payloads/Conditions/WitnessCondition.cs | 2 +- src/Neo/Network/P2P/Payloads/Signer.cs | 8 +- src/Neo/Network/P2P/Payloads/Transaction.cs | 2 +- src/Neo/Network/P2P/Payloads/WitnessRule.cs | 2 +- .../ApplicationEngine.Runtime.cs | 2 +- src/Neo/SmartContract/ApplicationEngine.cs | 4 +- src/Neo/SmartContract/BinarySerializer.cs | 6 +- src/Neo/SmartContract/ContractState.cs | 2 +- .../Iterators/StorageIterator.cs | 2 +- src/Neo/SmartContract/JsonSerializer.cs | 4 +- src/Neo/SmartContract/Manifest/ContractAbi.cs | 6 +- .../Manifest/ContractEventDescriptor.cs | 4 +- .../SmartContract/Manifest/ContractGroup.cs | 2 +- .../Manifest/ContractManifest.cs | 12 +- .../Manifest/ContractParameterDefinition.cs | 2 +- .../Manifest/ContractPermission.cs | 4 +- src/Neo/SmartContract/Native/AccountState.cs | 2 +- .../Native/ContractManagement.cs | 6 +- src/Neo/SmartContract/Native/FungibleToken.cs | 2 +- .../SmartContract/Native/HashIndexState.cs | 2 +- .../SmartContract/Native/InteroperableList.cs | 2 +- src/Neo/SmartContract/Native/NeoToken.cs | 16 +-- .../SmartContract/Native/OracleContract.cs | 4 +- src/Neo/SmartContract/Native/OracleRequest.cs | 2 +- .../SmartContract/Native/RoleManagement.cs | 2 +- .../SmartContract/Native/TransactionState.cs | 4 +- src/Neo/SmartContract/Native/TrimmedBlock.cs | 2 +- src/Neo/SmartContract/NotifyEventArgs.cs | 6 +- .../Manifest/UT_ContractManifest.cs | 4 +- .../SmartContract/UT_NotifyEventArgs.cs | 6 +- tests/Neo.VM.Tests/UT_EvaluationStack.cs | 12 +- tests/Neo.VM.Tests/UT_ExecutionContext.cs | 2 +- tests/Neo.VM.Tests/UT_ReferenceCounter.cs | 23 ++-- tests/Neo.VM.Tests/UT_Slot.cs | 2 +- 47 files changed, 263 insertions(+), 211 deletions(-) create mode 100644 src/Neo.VM/ReferenceCounterV2.cs diff --git a/benchmarks/Neo.VM.Benchmarks/TestArray.cs b/benchmarks/Neo.VM.Benchmarks/TestArray.cs index 8a0d84a9e1..8398127e5e 100644 --- a/benchmarks/Neo.VM.Benchmarks/TestArray.cs +++ b/benchmarks/Neo.VM.Benchmarks/TestArray.cs @@ -29,9 +29,7 @@ public StackItem this[int index] set { if (IsReadOnly) throw new InvalidOperationException("The object is readonly."); - ReferenceCounter?.RemoveReference(_array[index], this); _array[index] = value; - ReferenceCounter?.AddReference(value, this); } } @@ -43,22 +41,14 @@ public StackItem this[int index] public override int SubItemsCount => _array.Count; public override StackItemType Type => StackItemType.Array; - /// - /// Create an array containing the specified items. - /// - /// The items to be included in the array. - public TestArray(IEnumerable? items = null) - : this(null, items) - { - } /// /// Create an array containing the specified items. And make the array use the specified . /// /// The to be used by this array. /// The items to be included in the array. - public TestArray(IReferenceCounter? referenceCounter, IEnumerable? items = null) - : base(referenceCounter) + public TestArray(IEnumerable? items = null) + : base() { _array = items switch { @@ -66,9 +56,6 @@ public TestArray(IReferenceCounter? referenceCounter, IEnumerable? it List list => list, _ => new List(items) }; - if (referenceCounter != null) - foreach (StackItem item in _array) - referenceCounter.AddReference(item, this); } /// @@ -79,29 +66,25 @@ public void Add(StackItem item) { if (IsReadOnly) throw new InvalidOperationException("The object is readonly."); _array.Add(item); - ReferenceCounter?.AddReference(item, this); } public override void Clear() { if (IsReadOnly) throw new InvalidOperationException("The object is readonly."); - if (ReferenceCounter != null) - foreach (StackItem item in _array) - ReferenceCounter.RemoveReference(item, this); _array.Clear(); } public override StackItem ConvertTo(StackItemType type) { if (Type == StackItemType.Array && type == StackItemType.Struct) - return new Struct(ReferenceCounter, new List(_array)); + return new Struct(new List(_array)); return base.ConvertTo(type); } internal sealed override StackItem DeepCopy(Dictionary refMap, bool asImmutable) { if (refMap.TryGetValue(this, out StackItem? mappedItem)) return mappedItem; - var result = this is TestStruct ? new TestStruct(ReferenceCounter) : new TestArray(ReferenceCounter); + var result = this is TestStruct ? new TestStruct() : new TestArray(); refMap.Add(this, result); foreach (StackItem item in _array) result.Add(item.DeepCopy(refMap, asImmutable)); @@ -126,7 +109,6 @@ public IEnumerator GetEnumerator() public void RemoveAt(int index) { if (IsReadOnly) throw new InvalidOperationException("The object is readonly."); - ReferenceCounter?.RemoveReference(_array[index], this); _array.RemoveAt(index); } diff --git a/benchmarks/Neo.VM.Benchmarks/TestStruct.cs b/benchmarks/Neo.VM.Benchmarks/TestStruct.cs index 24b32530b5..baaae23e71 100644 --- a/benchmarks/Neo.VM.Benchmarks/TestStruct.cs +++ b/benchmarks/Neo.VM.Benchmarks/TestStruct.cs @@ -17,22 +17,14 @@ public class TestStruct : TestArray { public override StackItemType Type => StackItemType.Struct; - /// - /// Create a structure with the specified fields. - /// - /// The fields to be included in the structure. - public TestStruct(IEnumerable? fields = null) - : this(null, fields) - { - } /// /// Create a structure with the specified fields. And make the structure use the specified . /// /// The to be used by this structure. /// The fields to be included in the structure. - public TestStruct(IReferenceCounter? referenceCounter, IEnumerable? fields = null) - : base(referenceCounter, fields) + public TestStruct(IEnumerable? fields = null) + : base(fields) { } @@ -44,7 +36,7 @@ public TestStruct(IReferenceCounter? referenceCounter, IEnumerable? f public TestStruct Clone(ExecutionEngineLimits limits) { int count = (int)(limits.MaxStackSize - 1); - TestStruct result = new(ReferenceCounter); + TestStruct result = new(); Queue queue = new(); queue.Enqueue(result); queue.Enqueue(this); @@ -58,7 +50,7 @@ public TestStruct Clone(ExecutionEngineLimits limits) if (count < 0) throw new InvalidOperationException("Beyond clone limits!"); if (item is TestStruct sb) { - TestStruct sa = new(ReferenceCounter); + TestStruct sa = new(); a.Add(sa); queue.Enqueue(sa); queue.Enqueue(sb); @@ -75,7 +67,7 @@ public TestStruct Clone(ExecutionEngineLimits limits) public override StackItem ConvertTo(StackItemType type) { if (type == StackItemType.Array) - return new TestArray(ReferenceCounter, new List(_array)); + return new TestArray(new List(_array)); return base.ConvertTo(type); } diff --git a/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_Convert.cs b/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_Convert.cs index de71f3332d..5e2653c27b 100644 --- a/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_Convert.cs +++ b/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_Convert.cs @@ -60,7 +60,7 @@ public IEnumerable GetTypeConversionPairs() private Dictionary> CreateTestItemsByType() { - var referenceCounter = new ReferenceCounter(); + var referenceCounter = new ReferenceCounterV2(); var result = new Dictionary>(); foreach (StackItemType type in Enum.GetValues(typeof(StackItemType))) @@ -84,22 +84,22 @@ private Dictionary> CreateTestItemsByType() result[StackItemType.Buffer].Add(new Buffer(new byte[128])); // Another 128-byte buffer, all zeros // Create an array with 10 items - var longArray = new Array(referenceCounter); + var longArray = new Array(); for (int i = 0; i < 10; i++) longArray.Add(new Integer(i)); result[StackItemType.Array].Add(longArray); - result[StackItemType.Array].Add(new Array(referenceCounter) { StackItem.True, new ByteString(new byte[] { 3, 4, 5 }) }); + result[StackItemType.Array].Add(new Array() { StackItem.True, new ByteString(new byte[] { 3, 4, 5 }) }); // Create a struct with 10 items - var longStruct = new Struct(referenceCounter); + var longStruct = new Struct(); for (int i = 0; i < 10; i++) longStruct.Add(new Integer(i * 10)); result[StackItemType.Struct].Add(longStruct); - result[StackItemType.Struct].Add(new Struct(referenceCounter) { StackItem.False, new Buffer(new byte[] { 6, 7, 8 }) }); + result[StackItemType.Struct].Add(new Struct() { StackItem.False, new Buffer(new byte[] { 6, 7, 8 }) }); // Create a map with 10 items - var longMap = new Map(referenceCounter); + var longMap = new Map(); for (int i = 0; i < 10; i++) longMap[new Integer(i)] = new ByteString(new byte[] { (byte)(i * 20) }); result[StackItemType.Map].Add(longMap); - result[StackItemType.Map].Add(new Map(referenceCounter) { [new ByteString(new byte[] { 9 })] = StackItem.True }); + result[StackItemType.Map].Add(new Map() { [new ByteString(new byte[] { 9 })] = StackItem.True }); result[StackItemType.InteropInterface].Add(new InteropInterface(new object())); result[StackItemType.InteropInterface].Add(new InteropInterface("test string")); diff --git a/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopy.cs b/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopy.cs index 4cef2e555f..89c2732c73 100644 --- a/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopy.cs +++ b/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopy.cs @@ -39,7 +39,7 @@ public class Benchmarks_DeepCopy [Benchmark] public void BenchNestedArrayDeepCopy() { - var root = new Array(new ReferenceCounter()); + var root = new Array(); CreateNestedArray(root, Params.Depth, Params.ElementsPerLevel); _ = root.DeepCopy(); } @@ -47,16 +47,16 @@ public void BenchNestedArrayDeepCopy() [Benchmark] public void BenchNestedArrayDeepCopyWithReferenceCounter() { - var referenceCounter = new ReferenceCounter(); - var root = new Array(referenceCounter); - CreateNestedArray(root, Params.Depth, Params.ElementsPerLevel, referenceCounter); + var referenceCounter = new ReferenceCounterV2(); + var root = new Array(); + CreateNestedArray(root, Params.Depth, Params.ElementsPerLevel); _ = root.DeepCopy(); } [Benchmark] public void BenchNestedTestArrayDeepCopy() { - var root = new TestArray(new ReferenceCounter()); + var root = new TestArray(); CreateNestedTestArray(root, Params.Depth, Params.ElementsPerLevel); _ = root.DeepCopy(); } @@ -64,13 +64,13 @@ public void BenchNestedTestArrayDeepCopy() [Benchmark] public void BenchNestedTestArrayDeepCopyWithReferenceCounter() { - var referenceCounter = new ReferenceCounter(); - var root = new TestArray(referenceCounter); - CreateNestedTestArray(root, Params.Depth, Params.ElementsPerLevel, referenceCounter); + var referenceCounter = new ReferenceCounterV2(); + var root = new TestArray(); + CreateNestedTestArray(root, Params.Depth, Params.ElementsPerLevel); _ = root.DeepCopy(); } - private static void CreateNestedArray(Array? rootArray, int depth, int elementsPerLevel = 1, IReferenceCounter? referenceCounter = null) + private static void CreateNestedArray(Array? rootArray, int depth, int elementsPerLevel = 1) { if (depth < 0) { @@ -89,13 +89,13 @@ private static void CreateNestedArray(Array? rootArray, int depth, int elementsP for (var i = 0; i < elementsPerLevel; i++) { - var childArray = new Array(referenceCounter); + var childArray = new Array(); rootArray.Add(childArray); - CreateNestedArray(childArray, depth - 1, elementsPerLevel, referenceCounter); + CreateNestedArray(childArray, depth - 1, elementsPerLevel); } } - private static void CreateNestedTestArray(TestArray rootArray, int depth, int elementsPerLevel = 1, IReferenceCounter? referenceCounter = null) + private static void CreateNestedTestArray(TestArray rootArray, int depth, int elementsPerLevel = 1) { if (depth < 0) { @@ -114,9 +114,9 @@ private static void CreateNestedTestArray(TestArray rootArray, int depth, int el for (var i = 0; i < elementsPerLevel; i++) { - var childArray = new TestArray(referenceCounter); + var childArray = new TestArray(); rootArray.Add(childArray); - CreateNestedTestArray(childArray, depth - 1, elementsPerLevel, referenceCounter); + CreateNestedTestArray(childArray, depth - 1, elementsPerLevel); } } } diff --git a/src/Neo.VM/ExecutionEngine.cs b/src/Neo.VM/ExecutionEngine.cs index 8a3167b4c8..bd04826d4d 100644 --- a/src/Neo.VM/ExecutionEngine.cs +++ b/src/Neo.VM/ExecutionEngine.cs @@ -84,7 +84,7 @@ protected internal set /// Initializes a new instance of the class. /// /// The jump table to be used. - public ExecutionEngine(JumpTable? jumpTable = null) : this(jumpTable, new ReferenceCounter(), ExecutionEngineLimits.Default) + public ExecutionEngine(JumpTable? jumpTable = null) : this(jumpTable, new ReferenceCounterV2(), ExecutionEngineLimits.Default) { } @@ -289,8 +289,7 @@ public T Pop() where T : StackItem /// protected virtual void PostExecuteInstruction(Instruction instruction) { - if (ReferenceCounter.Count < Limits.MaxStackSize) return; - if (ReferenceCounter.CheckZeroReferred() > Limits.MaxStackSize) + if (ReferenceCounter.Count > Limits.MaxStackSize) throw new InvalidOperationException($"MaxStackSize exceed: {ReferenceCounter.Count}"); } diff --git a/src/Neo.VM/JumpTable/JumpTable.Compound.cs b/src/Neo.VM/JumpTable/JumpTable.Compound.cs index 2447edfa35..c97ae7769f 100644 --- a/src/Neo.VM/JumpTable/JumpTable.Compound.cs +++ b/src/Neo.VM/JumpTable/JumpTable.Compound.cs @@ -37,7 +37,7 @@ public virtual void PackMap(ExecutionEngine engine, Instruction instruction) var size = (int)engine.Pop().GetInteger(); if (size < 0 || size * 2 > engine.CurrentContext!.EvaluationStack.Count) throw new InvalidOperationException($"The value {size} is out of range."); - Map map = new(engine.ReferenceCounter); + Map map = new(); for (var i = 0; i < size; i++) { var key = engine.Pop(); @@ -60,7 +60,7 @@ public virtual void PackStruct(ExecutionEngine engine, Instruction instruction) var size = (int)engine.Pop().GetInteger(); if (size < 0 || size > engine.CurrentContext!.EvaluationStack.Count) throw new InvalidOperationException($"The value {size} is out of range."); - Struct @struct = new(engine.ReferenceCounter); + Struct @struct = new(); for (var i = 0; i < size; i++) { var item = engine.Pop(); @@ -82,7 +82,7 @@ public virtual void Pack(ExecutionEngine engine, Instruction instruction) var size = (int)engine.Pop().GetInteger(); if (size < 0 || size > engine.CurrentContext!.EvaluationStack.Count) throw new InvalidOperationException($"The value {size} is out of range."); - VMArray array = new(engine.ReferenceCounter); + VMArray array = new(); for (var i = 0; i < size; i++) { var item = engine.Pop(); @@ -136,7 +136,7 @@ public virtual void Unpack(ExecutionEngine engine, Instruction instruction) [MethodImpl(MethodImplOptions.AggressiveInlining)] public virtual void NewArray0(ExecutionEngine engine, Instruction instruction) { - engine.Push(new VMArray(engine.ReferenceCounter)); + engine.Push(new VMArray()); } /// @@ -154,7 +154,7 @@ public virtual void NewArray(ExecutionEngine engine, Instruction instruction) throw new InvalidOperationException($"MaxStackSize exceed: {n}"); var nullArray = new StackItem[n]; Array.Fill(nullArray, StackItem.Null); - engine.Push(new VMArray(engine.ReferenceCounter, nullArray)); + engine.Push(new VMArray(nullArray)); } /// @@ -184,7 +184,7 @@ public virtual void NewArray_T(ExecutionEngine engine, Instruction instruction) }; var itemArray = new StackItem[n]; Array.Fill(itemArray, item); - engine.Push(new VMArray(engine.ReferenceCounter, itemArray)); + engine.Push(new VMArray(itemArray)); } /// @@ -197,7 +197,7 @@ public virtual void NewArray_T(ExecutionEngine engine, Instruction instruction) [MethodImpl(MethodImplOptions.AggressiveInlining)] public virtual void NewStruct0(ExecutionEngine engine, Instruction instruction) { - engine.Push(new Struct(engine.ReferenceCounter)); + engine.Push(new Struct()); } /// @@ -216,7 +216,7 @@ public virtual void NewStruct(ExecutionEngine engine, Instruction instruction) var nullArray = new StackItem[n]; Array.Fill(nullArray, StackItem.Null); - engine.Push(new Struct(engine.ReferenceCounter, nullArray)); + engine.Push(new Struct(nullArray)); } /// @@ -229,7 +229,7 @@ public virtual void NewStruct(ExecutionEngine engine, Instruction instruction) [MethodImpl(MethodImplOptions.AggressiveInlining)] public virtual void NewMap(ExecutionEngine engine, Instruction instruction) { - engine.Push(new Map(engine.ReferenceCounter)); + engine.Push(new Map()); } /// @@ -327,7 +327,7 @@ public virtual void HasKey(ExecutionEngine engine, Instruction instruction) public virtual void Keys(ExecutionEngine engine, Instruction instruction) { var map = engine.Pop(); - engine.Push(new VMArray(engine.ReferenceCounter, map.Keys)); + engine.Push(new VMArray(map.Keys)); } /// @@ -347,7 +347,7 @@ public virtual void Values(ExecutionEngine engine, Instruction instruction) Map map => map.Values, _ => throw new InvalidOperationException($"Invalid type for {instruction.OpCode}: {x.Type}"), }; - VMArray newArray = new(engine.ReferenceCounter); + VMArray newArray = new(); foreach (var item in values) if (item is Struct s) newArray.Add(s.Clone(engine.Limits)); @@ -422,6 +422,7 @@ public virtual void Append(ExecutionEngine engine, Instruction instruction) var array = engine.Pop(); if (newItem is Struct s) newItem = s.Clone(engine.Limits); array.Add(newItem); + engine.ReferenceCounter.AddStackReference(newItem); } /// @@ -445,12 +446,23 @@ public virtual void SetItem(ExecutionEngine engine, Instruction instruction) var index = (int)key.GetInteger(); if (index < 0 || index >= array.Count) throw new CatchableException($"The value {index} is out of range."); + engine.ReferenceCounter.RemoveStackReference(array[index]); array[index] = value; + engine.ReferenceCounter.AddStackReference(array[index]); break; } case Map map: { + if (!map.TryGetValue(key, out var value1)) + { + engine.ReferenceCounter.AddStackReference(key); + } + else + { + engine.ReferenceCounter.RemoveStackReference(value1); + } map[key] = value; + engine.ReferenceCounter.AddStackReference(value); break; } case Types.Buffer buffer: @@ -515,9 +527,13 @@ public virtual void Remove(ExecutionEngine engine, Instruction instruction) var index = (int)key.GetInteger(); if (index < 0 || index >= array.Count) throw new InvalidOperationException($"The value {index} is out of range."); + var item = array[index]; array.RemoveAt(index); + engine.ReferenceCounter.RemoveStackReference(item); break; case Map map: + engine.ReferenceCounter.RemoveStackReference(key); + engine.ReferenceCounter.RemoveStackReference(map[key]); map.Remove(key); break; default: @@ -536,6 +552,10 @@ public virtual void Remove(ExecutionEngine engine, Instruction instruction) public virtual void ClearItems(ExecutionEngine engine, Instruction instruction) { var x = engine.Pop(); + foreach (var xSubItem in x.SubItems) + { + engine.ReferenceCounter.RemoveStackReference(xSubItem); + } x.Clear(); } @@ -551,7 +571,9 @@ public virtual void PopItem(ExecutionEngine engine, Instruction instruction) { var x = engine.Pop(); var index = x.Count - 1; - engine.Push(x[index]); + var item = x[index]; + engine.Push(item); + engine.ReferenceCounter.RemoveStackReference(item); x.RemoveAt(index); } } diff --git a/src/Neo.VM/ReferenceCounterV2.cs b/src/Neo.VM/ReferenceCounterV2.cs new file mode 100644 index 0000000000..7d7430da95 --- /dev/null +++ b/src/Neo.VM/ReferenceCounterV2.cs @@ -0,0 +1,105 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// ReferenceCounterV2.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.VM.StronglyConnectedComponents; +using Neo.VM.Types; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using Array = Neo.VM.Types.Array; +using Buffer = Neo.VM.Types.Buffer; + +namespace Neo.VM +{ + /// + /// Used for reference counting of objects in the VM. + /// + public sealed class ReferenceCounterV2 : IReferenceCounter + { + // Keeps the total count of references. + private int _referencesCount = 0; + + /// + public int Count => _referencesCount; + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool NeedTrack(StackItem item) + { + throw new NotImplementedException(); + } + + /// + public void AddReference(StackItem item, CompoundType parent) + { + throw new NotImplementedException(); + } + + /// + public void AddStackReference(StackItem item, int count = 1) + { + // Increment the reference count by the specified count. + _referencesCount += count; + + if (item is CompoundType compoundType) + { + // Increment the item's stack references by the specified count. + compoundType.StackReferences += count; + if (compoundType.StackReferences == count) + { + foreach (var subItem in compoundType.SubItems) + { + AddStackReference(subItem); + } + } + } + } + + /// + public void AddZeroReferred(StackItem item) + { + throw new NotImplementedException(); + } + + /// + public int CheckZeroReferred() + { + throw new NotImplementedException(); + } + + /// + public void RemoveReference(StackItem item, CompoundType parent) + { + throw new NotImplementedException(); + } + + /// + public void RemoveStackReference(StackItem item) + { + // Increment the reference count by the specified count. + _referencesCount--; + + if (item is CompoundType compoundType) + { + // Increment the item's stack references by the specified count. + compoundType.StackReferences--; + if (compoundType.StackReferences == 0) + { + foreach (var subItem in compoundType.SubItems) + { + RemoveStackReference(subItem); + } + } + } + } + } +} diff --git a/src/Neo.VM/Types/Array.cs b/src/Neo.VM/Types/Array.cs index 903613c228..0c3ed2c9ff 100644 --- a/src/Neo.VM/Types/Array.cs +++ b/src/Neo.VM/Types/Array.cs @@ -33,14 +33,7 @@ public StackItem this[int index] set { if (IsReadOnly) throw new InvalidOperationException("The object is readonly."); - ReferenceCounter?.RemoveReference(_array[index], this); _array[index] = value; - if (ReferenceCounter != null && value is CompoundType { ReferenceCounter: null }) - { - throw new InvalidOperationException("Can not set a CompoundType without a ReferenceCounter."); - } - - ReferenceCounter?.AddReference(value, this); } } @@ -75,18 +68,6 @@ public Array(IReferenceCounter? referenceCounter, IEnumerable? items List list => list, _ => new List(items) }; - - if (referenceCounter == null) return; - - foreach (var item in _array) - { - if (item is CompoundType { ReferenceCounter: null }) - { - throw new InvalidOperationException("Can not set a CompoundType without a ReferenceCounter."); - } - - referenceCounter.AddReference(item, this); - } } /// @@ -97,36 +78,25 @@ public void Add(StackItem item) { if (IsReadOnly) throw new InvalidOperationException("The object is readonly."); _array.Add(item); - - if (ReferenceCounter == null) return; - - if (item is CompoundType { ReferenceCounter: null }) - { - throw new InvalidOperationException("Can not set a CompoundType without a ReferenceCounter."); - } - ReferenceCounter.AddReference(item, this); } public override void Clear() { if (IsReadOnly) throw new InvalidOperationException("The object is readonly."); - if (ReferenceCounter != null) - foreach (StackItem item in _array) - ReferenceCounter.RemoveReference(item, this); _array.Clear(); } public override StackItem ConvertTo(StackItemType type) { if (Type == StackItemType.Array && type == StackItemType.Struct) - return new Struct(ReferenceCounter, new List(_array)); + return new Struct(new List(_array)); return base.ConvertTo(type); } internal sealed override StackItem DeepCopy(Dictionary refMap, bool asImmutable) { if (refMap.TryGetValue(this, out StackItem? mappedItem)) return mappedItem; - Array result = this is Struct ? new Struct(ReferenceCounter) : new Array(ReferenceCounter); + Array result = this is Struct ? new Struct() : new Array(); refMap.Add(this, result); foreach (StackItem item in _array) result.Add(item.DeepCopy(refMap, asImmutable)); @@ -151,7 +121,6 @@ public IEnumerator GetEnumerator() public void RemoveAt(int index) { if (IsReadOnly) throw new InvalidOperationException("The object is readonly."); - ReferenceCounter?.RemoveReference(_array[index], this); _array.RemoveAt(index); } diff --git a/src/Neo.VM/Types/CompoundType.cs b/src/Neo.VM/Types/CompoundType.cs index 33f670bfcb..e30502f43d 100644 --- a/src/Neo.VM/Types/CompoundType.cs +++ b/src/Neo.VM/Types/CompoundType.cs @@ -32,8 +32,6 @@ public abstract class CompoundType : StackItem /// The reference counter to be used. protected CompoundType(IReferenceCounter? referenceCounter) { - ReferenceCounter = referenceCounter; - referenceCounter?.AddZeroReferred(this); } /// diff --git a/src/Neo.VM/Types/Map.cs b/src/Neo.VM/Types/Map.cs index 2986399d59..c7153b79cb 100644 --- a/src/Neo.VM/Types/Map.cs +++ b/src/Neo.VM/Types/Map.cs @@ -48,18 +48,6 @@ public StackItem this[PrimitiveType key] if (key.Size > MaxKeySize) throw new ArgumentException($"MaxKeySize exceed: {key.Size}"); if (IsReadOnly) throw new InvalidOperationException("The object is readonly."); - if (ReferenceCounter != null) - { - if (dictionary.TryGetValue(key, out StackItem? old_value)) - ReferenceCounter.RemoveReference(old_value, this); - else - ReferenceCounter.AddReference(key, this); - if (value is CompoundType { ReferenceCounter: null }) - { - throw new InvalidOperationException("Can not set a Map without a ReferenceCounter."); - } - ReferenceCounter.AddReference(value, this); - } dictionary[key] = value; } } @@ -94,12 +82,6 @@ public Map(IReferenceCounter? referenceCounter = null) public override void Clear() { if (IsReadOnly) throw new InvalidOperationException("The object is readonly."); - if (ReferenceCounter != null) - foreach (var pair in dictionary) - { - ReferenceCounter.RemoveReference(pair.Key, this); - ReferenceCounter.RemoveReference(pair.Value, this); - } dictionary.Clear(); } @@ -121,7 +103,7 @@ public bool ContainsKey(PrimitiveType key) internal override StackItem DeepCopy(Dictionary refMap, bool asImmutable) { if (refMap.TryGetValue(this, out StackItem? mappedItem)) return mappedItem; - Map result = new(ReferenceCounter); + Map result = new(); refMap.Add(this, result); foreach (var (k, v) in dictionary) result[k] = v.DeepCopy(refMap, asImmutable); @@ -155,8 +137,6 @@ public bool Remove(PrimitiveType key) if (IsReadOnly) throw new InvalidOperationException("The object is readonly."); if (!dictionary.Remove(key, out StackItem? old_value)) return false; - ReferenceCounter?.RemoveReference(key, this); - ReferenceCounter?.RemoveReference(old_value, this); return true; } diff --git a/src/Neo.VM/Types/Struct.cs b/src/Neo.VM/Types/Struct.cs index 344147b5ed..c8406687e3 100644 --- a/src/Neo.VM/Types/Struct.cs +++ b/src/Neo.VM/Types/Struct.cs @@ -48,7 +48,7 @@ public Struct(IReferenceCounter? referenceCounter, IEnumerable? field public Struct Clone(ExecutionEngineLimits limits) { int count = (int)(limits.MaxStackSize - 1); - Struct result = new(ReferenceCounter); + Struct result = new(); Queue queue = new(); queue.Enqueue(result); queue.Enqueue(this); @@ -62,7 +62,7 @@ public Struct Clone(ExecutionEngineLimits limits) if (count < 0) throw new InvalidOperationException("Beyond clone limits!"); if (item is Struct sb) { - Struct sa = new(ReferenceCounter); + Struct sa = new(); a.Add(sa); queue.Enqueue(sa); queue.Enqueue(sb); @@ -79,7 +79,7 @@ public Struct Clone(ExecutionEngineLimits limits) public override StackItem ConvertTo(StackItemType type) { if (type == StackItemType.Array) - return new Array(ReferenceCounter, new List(_array)); + return new Array(new List(_array)); return base.ConvertTo(type); } diff --git a/src/Neo/Network/P2P/Payloads/Conditions/AndCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/AndCondition.cs index 0c8df2ddb7..636d0869a9 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/AndCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/AndCondition.cs @@ -94,7 +94,7 @@ public override JObject ToJson() public override StackItem ToStackItem(IReferenceCounter referenceCounter) { var result = (VM.Types.Array)base.ToStackItem(referenceCounter); - result.Add(new VM.Types.Array(referenceCounter, Expressions.Select(p => p.ToStackItem(referenceCounter)))); + result.Add(new VM.Types.Array(Expressions.Select(p => p.ToStackItem(referenceCounter)))); return result; } diff --git a/src/Neo/Network/P2P/Payloads/Conditions/OrCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/OrCondition.cs index 177fb949fe..9bee1916f6 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/OrCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/OrCondition.cs @@ -94,7 +94,7 @@ public override JObject ToJson() public override StackItem ToStackItem(IReferenceCounter referenceCounter) { var result = (VM.Types.Array)base.ToStackItem(referenceCounter); - result.Add(new VM.Types.Array(referenceCounter, Expressions.Select(p => p.ToStackItem(referenceCounter)))); + result.Add(new VM.Types.Array(Expressions.Select(p => p.ToStackItem(referenceCounter)))); return result; } diff --git a/src/Neo/Network/P2P/Payloads/Conditions/WitnessCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/WitnessCondition.cs index 5fb5808714..b939749afd 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/WitnessCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/WitnessCondition.cs @@ -134,7 +134,7 @@ void IInteroperable.FromStackItem(StackItem stackItem) public virtual StackItem ToStackItem(IReferenceCounter referenceCounter) { - return new VM.Types.Array(referenceCounter, new StackItem[] { (byte)Type }); + return new VM.Types.Array(new StackItem[] { (byte)Type }); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/Neo/Network/P2P/Payloads/Signer.cs b/src/Neo/Network/P2P/Payloads/Signer.cs index 40496dfe74..6096af0f5f 100644 --- a/src/Neo/Network/P2P/Payloads/Signer.cs +++ b/src/Neo/Network/P2P/Payloads/Signer.cs @@ -193,13 +193,13 @@ void IInteroperable.FromStackItem(VM.Types.StackItem stackItem) VM.Types.StackItem IInteroperable.ToStackItem(IReferenceCounter referenceCounter) { - return new VM.Types.Array(referenceCounter, + return new VM.Types.Array( [ Account.ToArray(), (byte)Scopes, - Scopes.HasFlag(WitnessScope.CustomContracts) ? new VM.Types.Array(referenceCounter, AllowedContracts.Select(u => new VM.Types.ByteString(u.ToArray()))) : new VM.Types.Array(referenceCounter), - Scopes.HasFlag(WitnessScope.CustomGroups) ? new VM.Types.Array(referenceCounter, AllowedGroups.Select(u => new VM.Types.ByteString(u.ToArray()))) : new VM.Types.Array(referenceCounter), - Scopes.HasFlag(WitnessScope.WitnessRules) ? new VM.Types.Array(referenceCounter, Rules.Select(u => u.ToStackItem(referenceCounter))) : new VM.Types.Array(referenceCounter) + Scopes.HasFlag(WitnessScope.CustomContracts) ? new VM.Types.Array(AllowedContracts.Select(u => new VM.Types.ByteString(u.ToArray()))) : new VM.Types.Array(), + Scopes.HasFlag(WitnessScope.CustomGroups) ? new VM.Types.Array(AllowedGroups.Select(u => new VM.Types.ByteString(u.ToArray()))) : new VM.Types.Array(), + Scopes.HasFlag(WitnessScope.WitnessRules) ? new VM.Types.Array(Rules.Select(u => u.ToStackItem(referenceCounter))) : new VM.Types.Array() ]); } } diff --git a/src/Neo/Network/P2P/Payloads/Transaction.cs b/src/Neo/Network/P2P/Payloads/Transaction.cs index b5139f1c7c..632a9d6b72 100644 --- a/src/Neo/Network/P2P/Payloads/Transaction.cs +++ b/src/Neo/Network/P2P/Payloads/Transaction.cs @@ -462,7 +462,7 @@ public virtual VerifyResult VerifyStateIndependent(ProtocolSettings settings) public StackItem ToStackItem(IReferenceCounter referenceCounter) { if (_signers == null || _signers.Length == 0) throw new ArgumentException("Sender is not specified in the transaction."); - return new Array(referenceCounter, new StackItem[] + return new Array(new StackItem[] { // Computed properties Hash.ToArray(), diff --git a/src/Neo/Network/P2P/Payloads/WitnessRule.cs b/src/Neo/Network/P2P/Payloads/WitnessRule.cs index 08ab3911b2..c0ec8ac3dc 100644 --- a/src/Neo/Network/P2P/Payloads/WitnessRule.cs +++ b/src/Neo/Network/P2P/Payloads/WitnessRule.cs @@ -112,7 +112,7 @@ void IInteroperable.FromStackItem(StackItem stackItem) public StackItem ToStackItem(IReferenceCounter referenceCounter) { - return new VM.Types.Array(referenceCounter, new StackItem[] + return new VM.Types.Array(new StackItem[] { (byte)Action, Condition.ToStackItem(referenceCounter) diff --git a/src/Neo/SmartContract/ApplicationEngine.Runtime.cs b/src/Neo/SmartContract/ApplicationEngine.Runtime.cs index 3771278839..e880068572 100644 --- a/src/Neo/SmartContract/ApplicationEngine.Runtime.cs +++ b/src/Neo/SmartContract/ApplicationEngine.Runtime.cs @@ -414,7 +414,7 @@ protected internal Array GetNotifications(UInt160 hash) notifications = notifications.Where(p => p.ScriptHash == hash); var array = notifications.ToArray(); if (array.Length > Limits.MaxStackSize) throw new InvalidOperationException(); - Array notifyArray = new(ReferenceCounter); + Array notifyArray = new(); foreach (var notify in array) { notifyArray.Add(notify.ToStackItem(ReferenceCounter, this)); diff --git a/src/Neo/SmartContract/ApplicationEngine.cs b/src/Neo/SmartContract/ApplicationEngine.cs index 7808baae5e..54a0465069 100644 --- a/src/Neo/SmartContract/ApplicationEngine.cs +++ b/src/Neo/SmartContract/ApplicationEngine.cs @@ -502,8 +502,8 @@ protected internal StackItem Convert(object value) IInteroperable interoperable => interoperable.ToStackItem(ReferenceCounter), ISerializable i => i.ToArray(), StackItem item => item, - (object a, object b) => new Struct(ReferenceCounter) { Convert(a), Convert(b) }, - Array array => new VMArray(ReferenceCounter, array.OfType().Select(p => Convert(p))), + (object a, object b) => new Struct() { Convert(a), Convert(b) }, + Array array => new VMArray(array.OfType().Select(p => Convert(p))), _ => StackItem.FromInterface(value) }; } diff --git a/src/Neo/SmartContract/BinarySerializer.cs b/src/Neo/SmartContract/BinarySerializer.cs index b77a998d6e..39a9404933 100644 --- a/src/Neo/SmartContract/BinarySerializer.cs +++ b/src/Neo/SmartContract/BinarySerializer.cs @@ -134,19 +134,19 @@ public static StackItem Deserialize(ref MemoryReader reader, uint maxSize, uint switch (placeholder.Type) { case StackItemType.Array: - Array array = new(referenceCounter); + Array array = new(); for (int i = 0; i < placeholder.ElementCount; i++) array.Add(stack_temp.Pop()); item = array; break; case StackItemType.Struct: - Struct @struct = new(referenceCounter); + Struct @struct = new(); for (int i = 0; i < placeholder.ElementCount; i++) @struct.Add(stack_temp.Pop()); item = @struct; break; case StackItemType.Map: - Map map = new(referenceCounter); + Map map = new(); for (int i = 0; i < placeholder.ElementCount; i++) { StackItem key = stack_temp.Pop(); diff --git a/src/Neo/SmartContract/ContractState.cs b/src/Neo/SmartContract/ContractState.cs index cd065cb8c3..90846b0c92 100644 --- a/src/Neo/SmartContract/ContractState.cs +++ b/src/Neo/SmartContract/ContractState.cs @@ -121,7 +121,7 @@ public JObject ToJson() public StackItem ToStackItem(IReferenceCounter referenceCounter) { - return new Array(referenceCounter, new StackItem[] { Id, (int)UpdateCounter, Hash.ToArray(), Nef.ToArray(), Manifest.ToStackItem(referenceCounter) }); + return new Array(new StackItem[] { Id, (int)UpdateCounter, Hash.ToArray(), Nef.ToArray(), Manifest.ToStackItem(referenceCounter) }); } } } diff --git a/src/Neo/SmartContract/Iterators/StorageIterator.cs b/src/Neo/SmartContract/Iterators/StorageIterator.cs index b66998c9dc..44d23a5be5 100644 --- a/src/Neo/SmartContract/Iterators/StorageIterator.cs +++ b/src/Neo/SmartContract/Iterators/StorageIterator.cs @@ -60,7 +60,7 @@ public StackItem Value(IReferenceCounter referenceCounter) return key; if (options.HasFlag(FindOptions.ValuesOnly)) return item; - return new Struct(referenceCounter) { key, item }; + return new Struct() { key, item }; } } } diff --git a/src/Neo/SmartContract/JsonSerializer.cs b/src/Neo/SmartContract/JsonSerializer.cs index d2055be7d8..e30e73a034 100644 --- a/src/Neo/SmartContract/JsonSerializer.cs +++ b/src/Neo/SmartContract/JsonSerializer.cs @@ -185,7 +185,7 @@ private static StackItem Deserialize(ApplicationEngine engine, JToken json, ref List list = new(array.Count); foreach (JToken obj in array) list.Add(Deserialize(engine, obj, ref maxStackSize, referenceCounter)); - return new Array(referenceCounter, list); + return new Array(list); } case JString str: { @@ -206,7 +206,7 @@ private static StackItem Deserialize(ApplicationEngine engine, JToken json, ref } case JObject obj: { - var item = new Map(referenceCounter); + var item = new Map(); foreach (var entry in obj.Properties) { diff --git a/src/Neo/SmartContract/Manifest/ContractAbi.cs b/src/Neo/SmartContract/Manifest/ContractAbi.cs index 4517ffeed2..d67b98baea 100644 --- a/src/Neo/SmartContract/Manifest/ContractAbi.cs +++ b/src/Neo/SmartContract/Manifest/ContractAbi.cs @@ -46,10 +46,10 @@ void IInteroperable.FromStackItem(StackItem stackItem) public StackItem ToStackItem(IReferenceCounter referenceCounter) { - return new Struct(referenceCounter) + return new Struct() { - new Array(referenceCounter, Methods.Select(p => p.ToStackItem(referenceCounter))), - new Array(referenceCounter, Events.Select(p => p.ToStackItem(referenceCounter))), + new Array( Methods.Select(p => p.ToStackItem(referenceCounter))), + new Array( Events.Select(p => p.ToStackItem(referenceCounter))), }; } diff --git a/src/Neo/SmartContract/Manifest/ContractEventDescriptor.cs b/src/Neo/SmartContract/Manifest/ContractEventDescriptor.cs index 9a3eabab06..9820f0e4f5 100644 --- a/src/Neo/SmartContract/Manifest/ContractEventDescriptor.cs +++ b/src/Neo/SmartContract/Manifest/ContractEventDescriptor.cs @@ -43,10 +43,10 @@ public virtual void FromStackItem(StackItem stackItem) public virtual StackItem ToStackItem(IReferenceCounter referenceCounter) { - return new Struct(referenceCounter) + return new Struct() { Name, - new Array(referenceCounter, Parameters.Select(p => p.ToStackItem(referenceCounter))) + new Array(Parameters.Select(p => p.ToStackItem(referenceCounter))) }; } diff --git a/src/Neo/SmartContract/Manifest/ContractGroup.cs b/src/Neo/SmartContract/Manifest/ContractGroup.cs index 8796c0f07a..2ed3540d39 100644 --- a/src/Neo/SmartContract/Manifest/ContractGroup.cs +++ b/src/Neo/SmartContract/Manifest/ContractGroup.cs @@ -45,7 +45,7 @@ void IInteroperable.FromStackItem(StackItem stackItem) public StackItem ToStackItem(IReferenceCounter referenceCounter) { - return new Struct(referenceCounter) { PubKey.ToArray(), Signature }; + return new Struct() { PubKey.ToArray(), Signature }; } /// diff --git a/src/Neo/SmartContract/Manifest/ContractManifest.cs b/src/Neo/SmartContract/Manifest/ContractManifest.cs index 17722eb48a..6e048673ac 100644 --- a/src/Neo/SmartContract/Manifest/ContractManifest.cs +++ b/src/Neo/SmartContract/Manifest/ContractManifest.cs @@ -90,15 +90,15 @@ void IInteroperable.FromStackItem(StackItem stackItem) public StackItem ToStackItem(IReferenceCounter referenceCounter) { - return new Struct(referenceCounter) + return new Struct() { Name, - new Array(referenceCounter, Groups.Select(p => p.ToStackItem(referenceCounter))), - new Map(referenceCounter), - new Array(referenceCounter, SupportedStandards.Select(p => (StackItem)p)), + new Array(Groups.Select(p => p.ToStackItem(referenceCounter))), + new Map(), + new Array(SupportedStandards.Select(p => (StackItem)p)), Abi.ToStackItem(referenceCounter), - new Array(referenceCounter, Permissions.Select(p => p.ToStackItem(referenceCounter))), - Trusts.IsWildcard ? StackItem.Null : new Array(referenceCounter, Trusts.Select(p => p.ToArray()?? StackItem.Null)), + new Array(Permissions.Select(p => p.ToStackItem(referenceCounter))), + Trusts.IsWildcard ? StackItem.Null : new Array(Trusts.Select(p => p.ToArray()?? StackItem.Null)), Extra is null ? "null" : Extra.ToByteArray(false) }; } diff --git a/src/Neo/SmartContract/Manifest/ContractParameterDefinition.cs b/src/Neo/SmartContract/Manifest/ContractParameterDefinition.cs index 7579dd54e6..16a4d8b9f1 100644 --- a/src/Neo/SmartContract/Manifest/ContractParameterDefinition.cs +++ b/src/Neo/SmartContract/Manifest/ContractParameterDefinition.cs @@ -41,7 +41,7 @@ void IInteroperable.FromStackItem(StackItem stackItem) public StackItem ToStackItem(IReferenceCounter referenceCounter) { - return new Struct(referenceCounter) { Name, (byte)Type }; + return new Struct() { Name, (byte)Type }; } /// diff --git a/src/Neo/SmartContract/Manifest/ContractPermission.cs b/src/Neo/SmartContract/Manifest/ContractPermission.cs index cf4d5078c5..33462989b3 100644 --- a/src/Neo/SmartContract/Manifest/ContractPermission.cs +++ b/src/Neo/SmartContract/Manifest/ContractPermission.cs @@ -70,10 +70,10 @@ void IInteroperable.FromStackItem(StackItem stackItem) public StackItem ToStackItem(IReferenceCounter referenceCounter) { - return new Struct(referenceCounter) + return new Struct() { Contract.IsWildcard ? StackItem.Null : Contract.IsHash ? Contract.Hash.ToArray() : Contract.Group.ToArray(), - Methods.IsWildcard ? StackItem.Null : new Array(referenceCounter, Methods.Select(p => (StackItem)p)), + Methods.IsWildcard ? StackItem.Null : new Array(Methods.Select(p => (StackItem)p)), }; } diff --git a/src/Neo/SmartContract/Native/AccountState.cs b/src/Neo/SmartContract/Native/AccountState.cs index 4e8944ab73..8c433612dd 100644 --- a/src/Neo/SmartContract/Native/AccountState.cs +++ b/src/Neo/SmartContract/Native/AccountState.cs @@ -32,7 +32,7 @@ public virtual void FromStackItem(StackItem stackItem) public virtual StackItem ToStackItem(IReferenceCounter referenceCounter) { - return new Struct(referenceCounter) { Balance }; + return new Struct() { Balance }; } } } diff --git a/src/Neo/SmartContract/Native/ContractManagement.cs b/src/Neo/SmartContract/Native/ContractManagement.cs index 6fefd2d05f..844002844f 100644 --- a/src/Neo/SmartContract/Native/ContractManagement.cs +++ b/src/Neo/SmartContract/Native/ContractManagement.cs @@ -63,7 +63,7 @@ private async ContractTask OnDeployAsync(ApplicationEngine engine, ContractState ContractMethodDescriptor md = contract.Manifest.Abi.GetMethod(ContractBasicMethod.Deploy, ContractBasicMethod.DeployPCount); if (md is not null) await engine.CallFromNativeContractAsync(Hash, contract.Hash, md.Name, data, update); - engine.SendNotification(Hash, update ? "Update" : "Deploy", new VM.Types.Array(engine.ReferenceCounter) { contract.Hash.ToArray() }); + engine.SendNotification(Hash, update ? "Update" : "Deploy", new VM.Types.Array() { contract.Hash.ToArray() }); } internal override async ContractTask OnPersistAsync(ApplicationEngine engine) @@ -110,7 +110,7 @@ internal override async ContractTask OnPersistAsync(ApplicationEngine engine) } // Emit native contract notification - engine.SendNotification(Hash, state is null ? "Deploy" : "Update", new VM.Types.Array(engine.ReferenceCounter) { contract.Hash.ToArray() }); + engine.SendNotification(Hash, state is null ? "Deploy" : "Update", new VM.Types.Array() { contract.Hash.ToArray() }); } } } @@ -309,7 +309,7 @@ private void Destroy(ApplicationEngine engine) // lock contract Policy.BlockAccount(engine.SnapshotCache, hash); // emit event - engine.SendNotification(Hash, "Destroy", new VM.Types.Array(engine.ReferenceCounter) { hash.ToArray() }); + engine.SendNotification(Hash, "Destroy", new VM.Types.Array() { hash.ToArray() }); } } } diff --git a/src/Neo/SmartContract/Native/FungibleToken.cs b/src/Neo/SmartContract/Native/FungibleToken.cs index 21de0a5644..d9db52fd75 100644 --- a/src/Neo/SmartContract/Native/FungibleToken.cs +++ b/src/Neo/SmartContract/Native/FungibleToken.cs @@ -182,7 +182,7 @@ private protected virtual async ContractTask PostTransferAsync(ApplicationEngine // Send notification engine.SendNotification(Hash, "Transfer", - new Array(engine.ReferenceCounter) { from?.ToArray() ?? StackItem.Null, to?.ToArray() ?? StackItem.Null, amount }); + new Array() { from?.ToArray() ?? StackItem.Null, to?.ToArray() ?? StackItem.Null, amount }); // Check if it's a wallet or smart contract diff --git a/src/Neo/SmartContract/Native/HashIndexState.cs b/src/Neo/SmartContract/Native/HashIndexState.cs index 4ab7a991cf..d6752d5193 100644 --- a/src/Neo/SmartContract/Native/HashIndexState.cs +++ b/src/Neo/SmartContract/Native/HashIndexState.cs @@ -29,7 +29,7 @@ void IInteroperable.FromStackItem(StackItem stackItem) StackItem IInteroperable.ToStackItem(IReferenceCounter referenceCounter) { - return new Struct(referenceCounter) { Hash.ToArray(), Index }; + return new Struct() { Hash.ToArray(), Index }; } } } diff --git a/src/Neo/SmartContract/Native/InteroperableList.cs b/src/Neo/SmartContract/Native/InteroperableList.cs index 09088f6156..0eb9c50e44 100644 --- a/src/Neo/SmartContract/Native/InteroperableList.cs +++ b/src/Neo/SmartContract/Native/InteroperableList.cs @@ -53,7 +53,7 @@ public void FromStackItem(StackItem stackItem) public StackItem ToStackItem(IReferenceCounter referenceCounter) { - return new Array(referenceCounter, this.Select(p => ElementToStackItem(p, referenceCounter))); + return new Array(this.Select(p => ElementToStackItem(p, referenceCounter))); } } } diff --git a/src/Neo/SmartContract/Native/NeoToken.cs b/src/Neo/SmartContract/Native/NeoToken.cs index 85309b4246..fe42b550da 100644 --- a/src/Neo/SmartContract/Native/NeoToken.cs +++ b/src/Neo/SmartContract/Native/NeoToken.cs @@ -216,9 +216,9 @@ internal override ContractTask OnPersistAsync(ApplicationEngine engine) if (!newCommittee.SequenceEqual(prevCommittee)) { - engine.SendNotification(Hash, "CommitteeChanged", new VM.Types.Array(engine.ReferenceCounter) { - new VM.Types.Array(engine.ReferenceCounter, prevCommittee.Select(u => (ByteString)u.ToArray())) , - new VM.Types.Array(engine.ReferenceCounter, newCommittee.Select(u => (ByteString)u.ToArray())) + engine.SendNotification(Hash, "CommitteeChanged", new VM.Types.Array() { + new VM.Types.Array( prevCommittee.Select(u => (ByteString)u.ToArray())) , + new VM.Types.Array(newCommittee.Select(u => (ByteString)u.ToArray())) }); } } @@ -340,7 +340,7 @@ private bool RegisterCandidate(ApplicationEngine engine, ECPoint pubkey) if (state.Registered) return true; state.Registered = true; engine.SendNotification(Hash, "CandidateStateChanged", - new VM.Types.Array(engine.ReferenceCounter) { pubkey.ToArray(), true, state.Votes }); + new VM.Types.Array() { pubkey.ToArray(), true, state.Votes }); return true; } @@ -357,7 +357,7 @@ private bool UnregisterCandidate(ApplicationEngine engine, ECPoint pubkey) state.Registered = false; CheckCandidate(engine.SnapshotCache, pubkey, state); engine.SendNotification(Hash, "CandidateStateChanged", - new VM.Types.Array(engine.ReferenceCounter) { pubkey.ToArray(), false, state.Votes }); + new VM.Types.Array() { pubkey.ToArray(), false, state.Votes }); return true; } @@ -410,7 +410,7 @@ private async ContractTask Vote(ApplicationEngine engine, UInt160 account, state_account.LastGasPerVote = 0; } engine.SendNotification(Hash, "Vote", - new VM.Types.Array(engine.ReferenceCounter) { account.ToArray(), from?.ToArray() ?? StackItem.Null, voteTo?.ToArray() ?? StackItem.Null, state_account.Balance }); + new VM.Types.Array() { account.ToArray(), from?.ToArray() ?? StackItem.Null, voteTo?.ToArray() ?? StackItem.Null, state_account.Balance }); if (gasDistribution is not null) await GAS.Mint(engine, gasDistribution.Account, gasDistribution.Amount, true); return true; @@ -605,7 +605,7 @@ public void FromStackItem(StackItem stackItem) public StackItem ToStackItem(IReferenceCounter referenceCounter) { - return new Struct(referenceCounter) { Registered, Votes }; + return new Struct() { Registered, Votes }; } } @@ -622,7 +622,7 @@ protected override (ECPoint, BigInteger) ElementFromStackItem(StackItem item) protected override StackItem ElementToStackItem((ECPoint PublicKey, BigInteger Votes) element, IReferenceCounter referenceCounter) { - return new Struct(referenceCounter) { element.PublicKey.ToArray(), element.Votes }; + return new Struct() { element.PublicKey.ToArray(), element.Votes }; } } diff --git a/src/Neo/SmartContract/Native/OracleContract.cs b/src/Neo/SmartContract/Native/OracleContract.cs index 54156a0029..1a02ec33b1 100644 --- a/src/Neo/SmartContract/Native/OracleContract.cs +++ b/src/Neo/SmartContract/Native/OracleContract.cs @@ -80,7 +80,7 @@ private ContractTask Finish(ApplicationEngine engine) if (response == null) throw new ArgumentException("Oracle response was not found"); 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() }); + engine.SendNotification(Hash, "OracleResponse", new VM.Types.Array() { response.Id, request.OriginalTxid.ToArray() }); StackItem userData = BinarySerializer.Deserialize(request.UserData, engine.Limits, engine.ReferenceCounter); return engine.CallFromNativeContractAsync(Hash, request.CallbackContract, request.CallbackMethod, request.Url, userData, (int)response.Code, response.Result); } @@ -224,7 +224,7 @@ private async ContractTask Request(ApplicationEngine engine, string url, string throw new InvalidOperationException("There are too many pending responses for this url"); list.Add(id); - engine.SendNotification(Hash, "OracleRequest", new VM.Types.Array(engine.ReferenceCounter) { id, engine.CallingScriptHash.ToArray(), url, filter ?? StackItem.Null }); + engine.SendNotification(Hash, "OracleRequest", new VM.Types.Array() { id, engine.CallingScriptHash.ToArray(), url, filter ?? StackItem.Null }); } [ContractMethod(CpuFee = 1 << 15)] diff --git a/src/Neo/SmartContract/Native/OracleRequest.cs b/src/Neo/SmartContract/Native/OracleRequest.cs index cd4962b1cb..82c342761c 100644 --- a/src/Neo/SmartContract/Native/OracleRequest.cs +++ b/src/Neo/SmartContract/Native/OracleRequest.cs @@ -70,7 +70,7 @@ public void FromStackItem(StackItem stackItem) public StackItem ToStackItem(IReferenceCounter referenceCounter) { - return new Array(referenceCounter) + return new Array() { OriginalTxid.ToArray(), GasForResponse, diff --git a/src/Neo/SmartContract/Native/RoleManagement.cs b/src/Neo/SmartContract/Native/RoleManagement.cs index e57f3f3e83..691f052eab 100644 --- a/src/Neo/SmartContract/Native/RoleManagement.cs +++ b/src/Neo/SmartContract/Native/RoleManagement.cs @@ -69,7 +69,7 @@ private void DesignateAsRole(ApplicationEngine engine, Role role, ECPoint[] node list.AddRange(nodes); list.Sort(); engine.SnapshotCache.Add(key, new StorageItem(list)); - engine.SendNotification(Hash, "Designation", new VM.Types.Array(engine.ReferenceCounter, new StackItem[] { (int)role, engine.PersistingBlock.Index })); + engine.SendNotification(Hash, "Designation", new VM.Types.Array(new StackItem[] { (int)role, engine.PersistingBlock.Index })); } private class NodeList : InteroperableList diff --git a/src/Neo/SmartContract/Native/TransactionState.cs b/src/Neo/SmartContract/Native/TransactionState.cs index 9e3eb2527a..9844aeb70a 100644 --- a/src/Neo/SmartContract/Native/TransactionState.cs +++ b/src/Neo/SmartContract/Native/TransactionState.cs @@ -79,10 +79,10 @@ void IInteroperable.FromStackItem(StackItem stackItem) StackItem IInteroperable.ToStackItem(IReferenceCounter referenceCounter) { if (Transaction is null) - return new Struct(referenceCounter) { BlockIndex }; + return new Struct() { BlockIndex }; if (_rawTransaction.IsEmpty) _rawTransaction = Transaction.ToArray(); - return new Struct(referenceCounter) { BlockIndex, _rawTransaction, (byte)State }; + return new Struct() { BlockIndex, _rawTransaction, (byte)State }; } } } diff --git a/src/Neo/SmartContract/Native/TrimmedBlock.cs b/src/Neo/SmartContract/Native/TrimmedBlock.cs index 69dd55fdbb..8b3b72c91d 100644 --- a/src/Neo/SmartContract/Native/TrimmedBlock.cs +++ b/src/Neo/SmartContract/Native/TrimmedBlock.cs @@ -82,7 +82,7 @@ void IInteroperable.FromStackItem(StackItem stackItem) StackItem IInteroperable.ToStackItem(IReferenceCounter referenceCounter) { - return new VM.Types.Array(referenceCounter, new StackItem[] + return new VM.Types.Array(new StackItem[] { // Computed properties Header.Hash.ToArray(), diff --git a/src/Neo/SmartContract/NotifyEventArgs.cs b/src/Neo/SmartContract/NotifyEventArgs.cs index 8d8542bca9..25650c4d15 100644 --- a/src/Neo/SmartContract/NotifyEventArgs.cs +++ b/src/Neo/SmartContract/NotifyEventArgs.cs @@ -65,7 +65,7 @@ public void FromStackItem(StackItem stackItem) public StackItem ToStackItem(IReferenceCounter referenceCounter) { - return new Array(referenceCounter) + return new Array() { ScriptHash.ToArray(), EventName, @@ -77,7 +77,7 @@ public StackItem ToStackItem(IReferenceCounter referenceCounter, ApplicationEngi { if (engine.IsHardforkEnabled(Hardfork.HF_Domovoi)) { - return new Array(referenceCounter) + return new Array() { ScriptHash.ToArray(), EventName, @@ -85,7 +85,7 @@ public StackItem ToStackItem(IReferenceCounter referenceCounter, ApplicationEngi }; } - return new Array(referenceCounter) + return new Array() { ScriptHash.ToArray(), EventName, diff --git a/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs b/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs index 7a44517b87..80ce2a1b54 100644 --- a/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs +++ b/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs @@ -32,7 +32,7 @@ public void TestMainnetContract() var json = @"{""name"":""Test"",""groups"":[],""features"":{},""supportedstandards"":[],""abi"":{""methods"":[{""name"":""a"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":0,""safe"":false},{""name"":""a0"",""parameters"":[],""returntype"":""Integer"",""offset"":77,""safe"":false},{""name"":""a10"",""parameters"":[],""returntype"":""Void"",""offset"":378,""safe"":false},{""name"":""a11"",""parameters"":[],""returntype"":""Void"",""offset"":398,""safe"":false},{""name"":""a12"",""parameters"":[],""returntype"":""Void"",""offset"":418,""safe"":false},{""name"":""a13"",""parameters"":[],""returntype"":""Void"",""offset"":438,""safe"":false},{""name"":""a14"",""parameters"":[],""returntype"":""Void"",""offset"":458,""safe"":false},{""name"":""a15"",""parameters"":[],""returntype"":""Void"",""offset"":478,""safe"":false},{""name"":""a16"",""parameters"":[],""returntype"":""Void"",""offset"":498,""safe"":false},{""name"":""a17"",""parameters"":[],""returntype"":""Void"",""offset"":518,""safe"":false},{""name"":""a18"",""parameters"":[],""returntype"":""Void"",""offset"":539,""safe"":false},{""name"":""a19"",""parameters"":[],""returntype"":""Void"",""offset"":560,""safe"":false},{""name"":""a20"",""parameters"":[],""returntype"":""Void"",""offset"":581,""safe"":false},{""name"":""a21"",""parameters"":[],""returntype"":""Void"",""offset"":602,""safe"":false},{""name"":""a22"",""parameters"":[],""returntype"":""Void"",""offset"":623,""safe"":false},{""name"":""a23"",""parameters"":[],""returntype"":""Void"",""offset"":644,""safe"":false},{""name"":""a24"",""parameters"":[],""returntype"":""Void"",""offset"":665,""safe"":false},{""name"":""a25"",""parameters"":[],""returntype"":""Void"",""offset"":686,""safe"":false},{""name"":""a26"",""parameters"":[],""returntype"":""Void"",""offset"":707,""safe"":false},{""name"":""a27"",""parameters"":[],""returntype"":""Void"",""offset"":728,""safe"":false},{""name"":""a28"",""parameters"":[],""returntype"":""Void"",""offset"":749,""safe"":false},{""name"":""a29"",""parameters"":[],""returntype"":""Void"",""offset"":770,""safe"":false},{""name"":""a30"",""parameters"":[],""returntype"":""Void"",""offset"":791,""safe"":false},{""name"":""a31"",""parameters"":[],""returntype"":""Void"",""offset"":812,""safe"":false},{""name"":""a32"",""parameters"":[],""returntype"":""Void"",""offset"":833,""safe"":false},{""name"":""a33"",""parameters"":[],""returntype"":""Void"",""offset"":854,""safe"":false},{""name"":""a34"",""parameters"":[],""returntype"":""Void"",""offset"":875,""safe"":false},{""name"":""a35"",""parameters"":[],""returntype"":""Void"",""offset"":896,""safe"":false},{""name"":""a36"",""parameters"":[],""returntype"":""Void"",""offset"":917,""safe"":false},{""name"":""a37"",""parameters"":[],""returntype"":""Void"",""offset"":938,""safe"":false},{""name"":""a38"",""parameters"":[],""returntype"":""Void"",""offset"":959,""safe"":false},{""name"":""a39"",""parameters"":[],""returntype"":""Void"",""offset"":980,""safe"":false},{""name"":""a40"",""parameters"":[],""returntype"":""Void"",""offset"":1001,""safe"":false},{""name"":""a41"",""parameters"":[],""returntype"":""Void"",""offset"":1022,""safe"":false},{""name"":""a42"",""parameters"":[],""returntype"":""Void"",""offset"":1043,""safe"":false},{""name"":""a43"",""parameters"":[],""returntype"":""Void"",""offset"":1064,""safe"":false},{""name"":""a44"",""parameters"":[],""returntype"":""Void"",""offset"":1085,""safe"":false},{""name"":""a45"",""parameters"":[],""returntype"":""Void"",""offset"":1106,""safe"":false},{""name"":""a46"",""parameters"":[],""returntype"":""Void"",""offset"":1127,""safe"":false},{""name"":""a47"",""parameters"":[],""returntype"":""Void"",""offset"":1148,""safe"":false},{""name"":""a48"",""parameters"":[],""returntype"":""Void"",""offset"":1169,""safe"":false},{""name"":""a49"",""parameters"":[],""returntype"":""Void"",""offset"":1190,""safe"":false},{""name"":""a50"",""parameters"":[],""returntype"":""Void"",""offset"":1211,""safe"":false},{""name"":""b"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":1232,""safe"":false},{""name"":""b0"",""parameters"":[],""returntype"":""Integer"",""offset"":1251,""safe"":false},{""name"":""b10"",""parameters"":[],""returntype"":""Void"",""offset"":1275,""safe"":false},{""name"":""b11"",""parameters"":[],""returntype"":""Void"",""offset"":1295,""safe"":false},{""name"":""b12"",""parameters"":[],""returntype"":""Void"",""offset"":1315,""safe"":false},{""name"":""b13"",""parameters"":[],""returntype"":""Void"",""offset"":1335,""safe"":false},{""name"":""b14"",""parameters"":[],""returntype"":""Void"",""offset"":1355,""safe"":false},{""name"":""b15"",""parameters"":[],""returntype"":""Void"",""offset"":1375,""safe"":false},{""name"":""b16"",""parameters"":[],""returntype"":""Void"",""offset"":1395,""safe"":false},{""name"":""b17"",""parameters"":[],""returntype"":""Void"",""offset"":1415,""safe"":false},{""name"":""b18"",""parameters"":[],""returntype"":""Void"",""offset"":1436,""safe"":false},{""name"":""b19"",""parameters"":[],""returntype"":""Void"",""offset"":1457,""safe"":false},{""name"":""b20"",""parameters"":[],""returntype"":""Void"",""offset"":1478,""safe"":false},{""name"":""b21"",""parameters"":[],""returntype"":""Void"",""offset"":1499,""safe"":false},{""name"":""b22"",""parameters"":[],""returntype"":""Void"",""offset"":1520,""safe"":false},{""name"":""b23"",""parameters"":[],""returntype"":""Void"",""offset"":1541,""safe"":false},{""name"":""b24"",""parameters"":[],""returntype"":""Void"",""offset"":1562,""safe"":false},{""name"":""b25"",""parameters"":[],""returntype"":""Void"",""offset"":1583,""safe"":false},{""name"":""b26"",""parameters"":[],""returntype"":""Void"",""offset"":1604,""safe"":false},{""name"":""b27"",""parameters"":[],""returntype"":""Void"",""offset"":1625,""safe"":false},{""name"":""b28"",""parameters"":[],""returntype"":""Void"",""offset"":1646,""safe"":false},{""name"":""b29"",""parameters"":[],""returntype"":""Void"",""offset"":1667,""safe"":false},{""name"":""b30"",""parameters"":[],""returntype"":""Void"",""offset"":1688,""safe"":false},{""name"":""b31"",""parameters"":[],""returntype"":""Void"",""offset"":1709,""safe"":false},{""name"":""b32"",""parameters"":[],""returntype"":""Void"",""offset"":1730,""safe"":false},{""name"":""b33"",""parameters"":[],""returntype"":""Void"",""offset"":1751,""safe"":false},{""name"":""b34"",""parameters"":[],""returntype"":""Void"",""offset"":1772,""safe"":false},{""name"":""b35"",""parameters"":[],""returntype"":""Void"",""offset"":1793,""safe"":false},{""name"":""b36"",""parameters"":[],""returntype"":""Void"",""offset"":1814,""safe"":false},{""name"":""b37"",""parameters"":[],""returntype"":""Void"",""offset"":1835,""safe"":false},{""name"":""b38"",""parameters"":[],""returntype"":""Void"",""offset"":1856,""safe"":false},{""name"":""b39"",""parameters"":[],""returntype"":""Void"",""offset"":1877,""safe"":false},{""name"":""b40"",""parameters"":[],""returntype"":""Void"",""offset"":1898,""safe"":false},{""name"":""b41"",""parameters"":[],""returntype"":""Void"",""offset"":1919,""safe"":false},{""name"":""b42"",""parameters"":[],""returntype"":""Void"",""offset"":1940,""safe"":false},{""name"":""b43"",""parameters"":[],""returntype"":""Void"",""offset"":1961,""safe"":false},{""name"":""b44"",""parameters"":[],""returntype"":""Void"",""offset"":1982,""safe"":false},{""name"":""b45"",""parameters"":[],""returntype"":""Void"",""offset"":2003,""safe"":false},{""name"":""b46"",""parameters"":[],""returntype"":""Void"",""offset"":2024,""safe"":false},{""name"":""b47"",""parameters"":[],""returntype"":""Void"",""offset"":2045,""safe"":false},{""name"":""b48"",""parameters"":[],""returntype"":""Void"",""offset"":2066,""safe"":false},{""name"":""b49"",""parameters"":[],""returntype"":""Void"",""offset"":2087,""safe"":false},{""name"":""b50"",""parameters"":[],""returntype"":""Void"",""offset"":2108,""safe"":false},{""name"":""c"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":2129,""safe"":false},{""name"":""c0"",""parameters"":[],""returntype"":""Integer"",""offset"":2148,""safe"":false},{""name"":""c10"",""parameters"":[],""returntype"":""Void"",""offset"":2172,""safe"":false},{""name"":""c11"",""parameters"":[],""returntype"":""Void"",""offset"":2192,""safe"":false},{""name"":""c12"",""parameters"":[],""returntype"":""Void"",""offset"":2212,""safe"":false},{""name"":""c13"",""parameters"":[],""returntype"":""Void"",""offset"":2232,""safe"":false},{""name"":""c14"",""parameters"":[],""returntype"":""Void"",""offset"":2252,""safe"":false},{""name"":""c15"",""parameters"":[],""returntype"":""Void"",""offset"":2272,""safe"":false},{""name"":""c16"",""parameters"":[],""returntype"":""Void"",""offset"":2292,""safe"":false},{""name"":""c17"",""parameters"":[],""returntype"":""Void"",""offset"":2312,""safe"":false},{""name"":""c18"",""parameters"":[],""returntype"":""Void"",""offset"":2333,""safe"":false},{""name"":""c19"",""parameters"":[],""returntype"":""Void"",""offset"":2354,""safe"":false},{""name"":""c20"",""parameters"":[],""returntype"":""Void"",""offset"":2375,""safe"":false},{""name"":""c21"",""parameters"":[],""returntype"":""Void"",""offset"":2396,""safe"":false},{""name"":""c22"",""parameters"":[],""returntype"":""Void"",""offset"":2417,""safe"":false},{""name"":""c23"",""parameters"":[],""returntype"":""Void"",""offset"":2438,""safe"":false},{""name"":""c24"",""parameters"":[],""returntype"":""Void"",""offset"":2459,""safe"":false},{""name"":""c25"",""parameters"":[],""returntype"":""Void"",""offset"":2480,""safe"":false},{""name"":""c26"",""parameters"":[],""returntype"":""Void"",""offset"":2501,""safe"":false},{""name"":""c27"",""parameters"":[],""returntype"":""Void"",""offset"":2522,""safe"":false},{""name"":""c28"",""parameters"":[],""returntype"":""Void"",""offset"":2543,""safe"":false},{""name"":""c29"",""parameters"":[],""returntype"":""Void"",""offset"":2564,""safe"":false},{""name"":""c30"",""parameters"":[],""returntype"":""Void"",""offset"":2585,""safe"":false},{""name"":""c31"",""parameters"":[],""returntype"":""Void"",""offset"":2606,""safe"":false},{""name"":""c32"",""parameters"":[],""returntype"":""Void"",""offset"":2627,""safe"":false},{""name"":""c33"",""parameters"":[],""returntype"":""Void"",""offset"":2648,""safe"":false},{""name"":""c34"",""parameters"":[],""returntype"":""Void"",""offset"":2669,""safe"":false},{""name"":""c35"",""parameters"":[],""returntype"":""Void"",""offset"":2690,""safe"":false},{""name"":""c36"",""parameters"":[],""returntype"":""Void"",""offset"":2711,""safe"":false},{""name"":""c37"",""parameters"":[],""returntype"":""Void"",""offset"":2732,""safe"":false},{""name"":""c38"",""parameters"":[],""returntype"":""Void"",""offset"":2753,""safe"":false},{""name"":""c39"",""parameters"":[],""returntype"":""Void"",""offset"":2774,""safe"":false},{""name"":""c40"",""parameters"":[],""returntype"":""Void"",""offset"":2795,""safe"":false},{""name"":""c41"",""parameters"":[],""returntype"":""Void"",""offset"":2816,""safe"":false},{""name"":""c42"",""parameters"":[],""returntype"":""Void"",""offset"":2837,""safe"":false},{""name"":""c43"",""parameters"":[],""returntype"":""Void"",""offset"":2858,""safe"":false},{""name"":""c44"",""parameters"":[],""returntype"":""Void"",""offset"":2879,""safe"":false},{""name"":""c45"",""parameters"":[],""returntype"":""Void"",""offset"":2900,""safe"":false},{""name"":""c46"",""parameters"":[],""returntype"":""Void"",""offset"":2921,""safe"":false},{""name"":""c47"",""parameters"":[],""returntype"":""Void"",""offset"":2942,""safe"":false},{""name"":""c48"",""parameters"":[],""returntype"":""Void"",""offset"":2963,""safe"":false},{""name"":""c49"",""parameters"":[],""returntype"":""Void"",""offset"":2984,""safe"":false},{""name"":""c50"",""parameters"":[],""returntype"":""Void"",""offset"":3005,""safe"":false},{""name"":""verify"",""parameters"":[],""returntype"":""Boolean"",""offset"":3026,""safe"":false},{""name"":""d"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":3039,""safe"":false},{""name"":""d0"",""parameters"":[],""returntype"":""Integer"",""offset"":3058,""safe"":false},{""name"":""d10"",""parameters"":[],""returntype"":""Void"",""offset"":3082,""safe"":false},{""name"":""d11"",""parameters"":[],""returntype"":""Void"",""offset"":3102,""safe"":false},{""name"":""d12"",""parameters"":[],""returntype"":""Void"",""offset"":3122,""safe"":false},{""name"":""d13"",""parameters"":[],""returntype"":""Void"",""offset"":3142,""safe"":false},{""name"":""d14"",""parameters"":[],""returntype"":""Void"",""offset"":3162,""safe"":false},{""name"":""d15"",""parameters"":[],""returntype"":""Void"",""offset"":3182,""safe"":false},{""name"":""d16"",""parameters"":[],""returntype"":""Void"",""offset"":3202,""safe"":false},{""name"":""d17"",""parameters"":[],""returntype"":""Void"",""offset"":3222,""safe"":false},{""name"":""d18"",""parameters"":[],""returntype"":""Void"",""offset"":3243,""safe"":false},{""name"":""d19"",""parameters"":[],""returntype"":""Void"",""offset"":3264,""safe"":false},{""name"":""d20"",""parameters"":[],""returntype"":""Void"",""offset"":3285,""safe"":false},{""name"":""d21"",""parameters"":[],""returntype"":""Void"",""offset"":3306,""safe"":false},{""name"":""d22"",""parameters"":[],""returntype"":""Void"",""offset"":3327,""safe"":false},{""name"":""d23"",""parameters"":[],""returntype"":""Void"",""offset"":3348,""safe"":false},{""name"":""d24"",""parameters"":[],""returntype"":""Void"",""offset"":3369,""safe"":false},{""name"":""d25"",""parameters"":[],""returntype"":""Void"",""offset"":3390,""safe"":false},{""name"":""d26"",""parameters"":[],""returntype"":""Void"",""offset"":3411,""safe"":false},{""name"":""d27"",""parameters"":[],""returntype"":""Void"",""offset"":3432,""safe"":false},{""name"":""d28"",""parameters"":[],""returntype"":""Void"",""offset"":3453,""safe"":false},{""name"":""d29"",""parameters"":[],""returntype"":""Void"",""offset"":3474,""safe"":false},{""name"":""d30"",""parameters"":[],""returntype"":""Void"",""offset"":3495,""safe"":false},{""name"":""d31"",""parameters"":[],""returntype"":""Void"",""offset"":3516,""safe"":false},{""name"":""d32"",""parameters"":[],""returntype"":""Void"",""offset"":3537,""safe"":false},{""name"":""d33"",""parameters"":[],""returntype"":""Void"",""offset"":3558,""safe"":false},{""name"":""d34"",""parameters"":[],""returntype"":""Void"",""offset"":3579,""safe"":false},{""name"":""d35"",""parameters"":[],""returntype"":""Void"",""offset"":3600,""safe"":false},{""name"":""d36"",""parameters"":[],""returntype"":""Void"",""offset"":3621,""safe"":false},{""name"":""d37"",""parameters"":[],""returntype"":""Void"",""offset"":3642,""safe"":false},{""name"":""d38"",""parameters"":[],""returntype"":""Void"",""offset"":3663,""safe"":false},{""name"":""d39"",""parameters"":[],""returntype"":""Void"",""offset"":3684,""safe"":false},{""name"":""d40"",""parameters"":[],""returntype"":""Void"",""offset"":3705,""safe"":false},{""name"":""d41"",""parameters"":[],""returntype"":""Void"",""offset"":3726,""safe"":false},{""name"":""d42"",""parameters"":[],""returntype"":""Void"",""offset"":3747,""safe"":false},{""name"":""d43"",""parameters"":[],""returntype"":""Void"",""offset"":3768,""safe"":false},{""name"":""d44"",""parameters"":[],""returntype"":""Void"",""offset"":3789,""safe"":false},{""name"":""d45"",""parameters"":[],""returntype"":""Void"",""offset"":3810,""safe"":false},{""name"":""d46"",""parameters"":[],""returntype"":""Void"",""offset"":3831,""safe"":false},{""name"":""d47"",""parameters"":[],""returntype"":""Void"",""offset"":3852,""safe"":false},{""name"":""d48"",""parameters"":[],""returntype"":""Void"",""offset"":3873,""safe"":false},{""name"":""d49"",""parameters"":[],""returntype"":""Void"",""offset"":3894,""safe"":false},{""name"":""d50"",""parameters"":[],""returntype"":""Void"",""offset"":3915,""safe"":false},{""name"":""e"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":3936,""safe"":false},{""name"":""e0"",""parameters"":[],""returntype"":""Integer"",""offset"":3955,""safe"":false},{""name"":""e10"",""parameters"":[],""returntype"":""Void"",""offset"":3979,""safe"":false},{""name"":""e11"",""parameters"":[],""returntype"":""Void"",""offset"":3999,""safe"":false},{""name"":""e12"",""parameters"":[],""returntype"":""Void"",""offset"":4019,""safe"":false},{""name"":""e13"",""parameters"":[],""returntype"":""Void"",""offset"":4039,""safe"":false},{""name"":""e14"",""parameters"":[],""returntype"":""Void"",""offset"":4059,""safe"":false},{""name"":""e15"",""parameters"":[],""returntype"":""Void"",""offset"":4079,""safe"":false},{""name"":""e16"",""parameters"":[],""returntype"":""Void"",""offset"":4099,""safe"":false},{""name"":""e17"",""parameters"":[],""returntype"":""Void"",""offset"":4119,""safe"":false},{""name"":""e18"",""parameters"":[],""returntype"":""Void"",""offset"":4140,""safe"":false},{""name"":""e19"",""parameters"":[],""returntype"":""Void"",""offset"":4161,""safe"":false},{""name"":""e20"",""parameters"":[],""returntype"":""Void"",""offset"":4182,""safe"":false},{""name"":""e21"",""parameters"":[],""returntype"":""Void"",""offset"":4203,""safe"":false},{""name"":""e22"",""parameters"":[],""returntype"":""Void"",""offset"":4224,""safe"":false},{""name"":""e23"",""parameters"":[],""returntype"":""Void"",""offset"":4245,""safe"":false},{""name"":""e24"",""parameters"":[],""returntype"":""Void"",""offset"":4266,""safe"":false},{""name"":""e25"",""parameters"":[],""returntype"":""Void"",""offset"":4287,""safe"":false},{""name"":""e26"",""parameters"":[],""returntype"":""Void"",""offset"":4308,""safe"":false},{""name"":""e27"",""parameters"":[],""returntype"":""Void"",""offset"":4329,""safe"":false},{""name"":""e28"",""parameters"":[],""returntype"":""Void"",""offset"":4350,""safe"":false},{""name"":""e29"",""parameters"":[],""returntype"":""Void"",""offset"":4371,""safe"":false},{""name"":""e30"",""parameters"":[],""returntype"":""Void"",""offset"":4392,""safe"":false},{""name"":""e31"",""parameters"":[],""returntype"":""Void"",""offset"":4413,""safe"":false},{""name"":""e32"",""parameters"":[],""returntype"":""Void"",""offset"":4434,""safe"":false},{""name"":""e33"",""parameters"":[],""returntype"":""Void"",""offset"":4455,""safe"":false},{""name"":""e34"",""parameters"":[],""returntype"":""Void"",""offset"":4476,""safe"":false},{""name"":""e35"",""parameters"":[],""returntype"":""Void"",""offset"":4497,""safe"":false},{""name"":""e36"",""parameters"":[],""returntype"":""Void"",""offset"":4518,""safe"":false},{""name"":""e37"",""parameters"":[],""returntype"":""Void"",""offset"":4539,""safe"":false},{""name"":""e38"",""parameters"":[],""returntype"":""Void"",""offset"":4560,""safe"":false},{""name"":""e39"",""parameters"":[],""returntype"":""Void"",""offset"":4581,""safe"":false},{""name"":""e40"",""parameters"":[],""returntype"":""Void"",""offset"":4602,""safe"":false},{""name"":""e41"",""parameters"":[],""returntype"":""Void"",""offset"":4623,""safe"":false},{""name"":""e42"",""parameters"":[],""returntype"":""Void"",""offset"":4644,""safe"":false},{""name"":""e43"",""parameters"":[],""returntype"":""Void"",""offset"":4665,""safe"":false},{""name"":""e44"",""parameters"":[],""returntype"":""Void"",""offset"":4686,""safe"":false},{""name"":""e45"",""parameters"":[],""returntype"":""Void"",""offset"":4707,""safe"":false},{""name"":""e46"",""parameters"":[],""returntype"":""Void"",""offset"":4728,""safe"":false},{""name"":""e47"",""parameters"":[],""returntype"":""Void"",""offset"":4749,""safe"":false},{""name"":""e48"",""parameters"":[],""returntype"":""Void"",""offset"":4770,""safe"":false},{""name"":""e49"",""parameters"":[],""returntype"":""Void"",""offset"":4791,""safe"":false},{""name"":""e50"",""parameters"":[],""returntype"":""Void"",""offset"":4812,""safe"":false},{""name"":""f"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":4833,""safe"":false},{""name"":""f0"",""parameters"":[],""returntype"":""Integer"",""offset"":4852,""safe"":false},{""name"":""f10"",""parameters"":[],""returntype"":""Void"",""offset"":4876,""safe"":false},{""name"":""f11"",""parameters"":[],""returntype"":""Void"",""offset"":4896,""safe"":false},{""name"":""f12"",""parameters"":[],""returntype"":""Void"",""offset"":4916,""safe"":false},{""name"":""f13"",""parameters"":[],""returntype"":""Void"",""offset"":4936,""safe"":false},{""name"":""f14"",""parameters"":[],""returntype"":""Void"",""offset"":4956,""safe"":false},{""name"":""f15"",""parameters"":[],""returntype"":""Void"",""offset"":4976,""safe"":false},{""name"":""f16"",""parameters"":[],""returntype"":""Void"",""offset"":4996,""safe"":false},{""name"":""f17"",""parameters"":[],""returntype"":""Void"",""offset"":5016,""safe"":false},{""name"":""f18"",""parameters"":[],""returntype"":""Void"",""offset"":5037,""safe"":false},{""name"":""f19"",""parameters"":[],""returntype"":""Void"",""offset"":5058,""safe"":false},{""name"":""f20"",""parameters"":[],""returntype"":""Void"",""offset"":5079,""safe"":false},{""name"":""f21"",""parameters"":[],""returntype"":""Void"",""offset"":5100,""safe"":false},{""name"":""f22"",""parameters"":[],""returntype"":""Void"",""offset"":5121,""safe"":false},{""name"":""f23"",""parameters"":[],""returntype"":""Void"",""offset"":5142,""safe"":false},{""name"":""f24"",""parameters"":[],""returntype"":""Void"",""offset"":5163,""safe"":false},{""name"":""f25"",""parameters"":[],""returntype"":""Void"",""offset"":5184,""safe"":false},{""name"":""f26"",""parameters"":[],""returntype"":""Void"",""offset"":5205,""safe"":false},{""name"":""f27"",""parameters"":[],""returntype"":""Void"",""offset"":5226,""safe"":false},{""name"":""f28"",""parameters"":[],""returntype"":""Void"",""offset"":5247,""safe"":false},{""name"":""f29"",""parameters"":[],""returntype"":""Void"",""offset"":5268,""safe"":false},{""name"":""f30"",""parameters"":[],""returntype"":""Void"",""offset"":5289,""safe"":false},{""name"":""f31"",""parameters"":[],""returntype"":""Void"",""offset"":5310,""safe"":false},{""name"":""f32"",""parameters"":[],""returntype"":""Void"",""offset"":5331,""safe"":false},{""name"":""f33"",""parameters"":[],""returntype"":""Void"",""offset"":5352,""safe"":false},{""name"":""f34"",""parameters"":[],""returntype"":""Void"",""offset"":5373,""safe"":false},{""name"":""f35"",""parameters"":[],""returntype"":""Void"",""offset"":5394,""safe"":false},{""name"":""f36"",""parameters"":[],""returntype"":""Void"",""offset"":5415,""safe"":false},{""name"":""f37"",""parameters"":[],""returntype"":""Void"",""offset"":5436,""safe"":false},{""name"":""f38"",""parameters"":[],""returntype"":""Void"",""offset"":5457,""safe"":false},{""name"":""f39"",""parameters"":[],""returntype"":""Void"",""offset"":5478,""safe"":false},{""name"":""f40"",""parameters"":[],""returntype"":""Void"",""offset"":5499,""safe"":false},{""name"":""f41"",""parameters"":[],""returntype"":""Void"",""offset"":5520,""safe"":false},{""name"":""f42"",""parameters"":[],""returntype"":""Void"",""offset"":5541,""safe"":false},{""name"":""f43"",""parameters"":[],""returntype"":""Void"",""offset"":5562,""safe"":false},{""name"":""f44"",""parameters"":[],""returntype"":""Void"",""offset"":5583,""safe"":false},{""name"":""f45"",""parameters"":[],""returntype"":""Void"",""offset"":5604,""safe"":false},{""name"":""f46"",""parameters"":[],""returntype"":""Void"",""offset"":5625,""safe"":false},{""name"":""f47"",""parameters"":[],""returntype"":""Void"",""offset"":5646,""safe"":false},{""name"":""f48"",""parameters"":[],""returntype"":""Void"",""offset"":5667,""safe"":false},{""name"":""f49"",""parameters"":[],""returntype"":""Void"",""offset"":5688,""safe"":false},{""name"":""f50"",""parameters"":[],""returntype"":""Void"",""offset"":5709,""safe"":false},{""name"":""g"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":5730,""safe"":false},{""name"":""g0"",""parameters"":[],""returntype"":""Integer"",""offset"":5749,""safe"":false},{""name"":""g10"",""parameters"":[],""returntype"":""Void"",""offset"":5773,""safe"":false},{""name"":""g11"",""parameters"":[],""returntype"":""Void"",""offset"":5793,""safe"":false},{""name"":""g12"",""parameters"":[],""returntype"":""Void"",""offset"":5813,""safe"":false},{""name"":""g13"",""parameters"":[],""returntype"":""Void"",""offset"":5833,""safe"":false},{""name"":""g14"",""parameters"":[],""returntype"":""Void"",""offset"":5853,""safe"":false},{""name"":""g15"",""parameters"":[],""returntype"":""Void"",""offset"":5873,""safe"":false},{""name"":""g16"",""parameters"":[],""returntype"":""Void"",""offset"":5893,""safe"":false},{""name"":""g17"",""parameters"":[],""returntype"":""Void"",""offset"":5913,""safe"":false},{""name"":""g18"",""parameters"":[],""returntype"":""Void"",""offset"":5934,""safe"":false},{""name"":""g19"",""parameters"":[],""returntype"":""Void"",""offset"":5955,""safe"":false},{""name"":""g20"",""parameters"":[],""returntype"":""Void"",""offset"":5976,""safe"":false},{""name"":""g21"",""parameters"":[],""returntype"":""Void"",""offset"":5997,""safe"":false},{""name"":""g22"",""parameters"":[],""returntype"":""Void"",""offset"":6018,""safe"":false},{""name"":""g23"",""parameters"":[],""returntype"":""Void"",""offset"":6039,""safe"":false},{""name"":""g24"",""parameters"":[],""returntype"":""Void"",""offset"":6060,""safe"":false},{""name"":""g25"",""parameters"":[],""returntype"":""Void"",""offset"":6081,""safe"":false},{""name"":""g26"",""parameters"":[],""returntype"":""Void"",""offset"":6102,""safe"":false},{""name"":""g27"",""parameters"":[],""returntype"":""Void"",""offset"":6123,""safe"":false},{""name"":""g28"",""parameters"":[],""returntype"":""Void"",""offset"":6144,""safe"":false},{""name"":""g29"",""parameters"":[],""returntype"":""Void"",""offset"":6165,""safe"":false},{""name"":""g30"",""parameters"":[],""returntype"":""Void"",""offset"":6186,""safe"":false},{""name"":""g31"",""parameters"":[],""returntype"":""Void"",""offset"":6207,""safe"":false},{""name"":""g32"",""parameters"":[],""returntype"":""Void"",""offset"":6228,""safe"":false},{""name"":""g33"",""parameters"":[],""returntype"":""Void"",""offset"":6249,""safe"":false},{""name"":""g34"",""parameters"":[],""returntype"":""Void"",""offset"":6270,""safe"":false},{""name"":""g35"",""parameters"":[],""returntype"":""Void"",""offset"":6291,""safe"":false},{""name"":""g36"",""parameters"":[],""returntype"":""Void"",""offset"":6312,""safe"":false},{""name"":""g37"",""parameters"":[],""returntype"":""Void"",""offset"":6333,""safe"":false},{""name"":""g38"",""parameters"":[],""returntype"":""Void"",""offset"":6354,""safe"":false},{""name"":""g39"",""parameters"":[],""returntype"":""Void"",""offset"":6375,""safe"":false},{""name"":""g40"",""parameters"":[],""returntype"":""Void"",""offset"":6396,""safe"":false},{""name"":""g41"",""parameters"":[],""returntype"":""Void"",""offset"":6417,""safe"":false},{""name"":""g42"",""parameters"":[],""returntype"":""Void"",""offset"":6438,""safe"":false},{""name"":""g43"",""parameters"":[],""returntype"":""Void"",""offset"":6459,""safe"":false},{""name"":""g44"",""parameters"":[],""returntype"":""Void"",""offset"":6480,""safe"":false},{""name"":""g45"",""parameters"":[],""returntype"":""Void"",""offset"":6501,""safe"":false},{""name"":""g46"",""parameters"":[],""returntype"":""Void"",""offset"":6522,""safe"":false},{""name"":""g47"",""parameters"":[],""returntype"":""Void"",""offset"":6543,""safe"":false},{""name"":""g48"",""parameters"":[],""returntype"":""Void"",""offset"":6564,""safe"":false},{""name"":""g49"",""parameters"":[],""returntype"":""Void"",""offset"":6585,""safe"":false},{""name"":""g50"",""parameters"":[],""returntype"":""Void"",""offset"":6606,""safe"":false},{""name"":""h"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":6627,""safe"":false},{""name"":""h0"",""parameters"":[],""returntype"":""Integer"",""offset"":6646,""safe"":false},{""name"":""h10"",""parameters"":[],""returntype"":""Void"",""offset"":6670,""safe"":false},{""name"":""h11"",""parameters"":[],""returntype"":""Void"",""offset"":6690,""safe"":false},{""name"":""h12"",""parameters"":[],""returntype"":""Void"",""offset"":6710,""safe"":false},{""name"":""h13"",""parameters"":[],""returntype"":""Void"",""offset"":6730,""safe"":false},{""name"":""h14"",""parameters"":[],""returntype"":""Void"",""offset"":6750,""safe"":false},{""name"":""h15"",""parameters"":[],""returntype"":""Void"",""offset"":6770,""safe"":false},{""name"":""h16"",""parameters"":[],""returntype"":""Void"",""offset"":6790,""safe"":false},{""name"":""h17"",""parameters"":[],""returntype"":""Void"",""offset"":6810,""safe"":false},{""name"":""h18"",""parameters"":[],""returntype"":""Void"",""offset"":6831,""safe"":false},{""name"":""h19"",""parameters"":[],""returntype"":""Void"",""offset"":6852,""safe"":false},{""name"":""h20"",""parameters"":[],""returntype"":""Void"",""offset"":6873,""safe"":false},{""name"":""h21"",""parameters"":[],""returntype"":""Void"",""offset"":6894,""safe"":false},{""name"":""h22"",""parameters"":[],""returntype"":""Void"",""offset"":6915,""safe"":false},{""name"":""h23"",""parameters"":[],""returntype"":""Void"",""offset"":6936,""safe"":false},{""name"":""h24"",""parameters"":[],""returntype"":""Void"",""offset"":6957,""safe"":false},{""name"":""h25"",""parameters"":[],""returntype"":""Void"",""offset"":6978,""safe"":false},{""name"":""h26"",""parameters"":[],""returntype"":""Void"",""offset"":6999,""safe"":false},{""name"":""h27"",""parameters"":[],""returntype"":""Void"",""offset"":7020,""safe"":false},{""name"":""h28"",""parameters"":[],""returntype"":""Void"",""offset"":7041,""safe"":false},{""name"":""h29"",""parameters"":[],""returntype"":""Void"",""offset"":7062,""safe"":false},{""name"":""h30"",""parameters"":[],""returntype"":""Void"",""offset"":7083,""safe"":false},{""name"":""h31"",""parameters"":[],""returntype"":""Void"",""offset"":7104,""safe"":false},{""name"":""h32"",""parameters"":[],""returntype"":""Void"",""offset"":7125,""safe"":false},{""name"":""h33"",""parameters"":[],""returntype"":""Void"",""offset"":7146,""safe"":false},{""name"":""h34"",""parameters"":[],""returntype"":""Void"",""offset"":7167,""safe"":false},{""name"":""h35"",""parameters"":[],""returntype"":""Void"",""offset"":7188,""safe"":false},{""name"":""h36"",""parameters"":[],""returntype"":""Void"",""offset"":7209,""safe"":false},{""name"":""h37"",""parameters"":[],""returntype"":""Void"",""offset"":7230,""safe"":false},{""name"":""h38"",""parameters"":[],""returntype"":""Void"",""offset"":7251,""safe"":false},{""name"":""h39"",""parameters"":[],""returntype"":""Void"",""offset"":7272,""safe"":false},{""name"":""h40"",""parameters"":[],""returntype"":""Void"",""offset"":7293,""safe"":false},{""name"":""h41"",""parameters"":[],""returntype"":""Void"",""offset"":7314,""safe"":false},{""name"":""h42"",""parameters"":[],""returntype"":""Void"",""offset"":7335,""safe"":false},{""name"":""h43"",""parameters"":[],""returntype"":""Void"",""offset"":7356,""safe"":false},{""name"":""h44"",""parameters"":[],""returntype"":""Void"",""offset"":7377,""safe"":false},{""name"":""h45"",""parameters"":[],""returntype"":""Void"",""offset"":7398,""safe"":false},{""name"":""h46"",""parameters"":[],""returntype"":""Void"",""offset"":7419,""safe"":false},{""name"":""h47"",""parameters"":[],""returntype"":""Void"",""offset"":7440,""safe"":false},{""name"":""h48"",""parameters"":[],""returntype"":""Void"",""offset"":7461,""safe"":false},{""name"":""h49"",""parameters"":[],""returntype"":""Void"",""offset"":7482,""safe"":false},{""name"":""h50"",""parameters"":[],""returntype"":""Void"",""offset"":7503,""safe"":false},{""name"":""i"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":7524,""safe"":false},{""name"":""i0"",""parameters"":[],""returntype"":""Integer"",""offset"":7545,""safe"":false},{""name"":""i10"",""parameters"":[],""returntype"":""Void"",""offset"":7571,""safe"":false},{""name"":""i11"",""parameters"":[],""returntype"":""Void"",""offset"":7593,""safe"":false},{""name"":""i12"",""parameters"":[],""returntype"":""Void"",""offset"":7615,""safe"":false},{""name"":""i13"",""parameters"":[],""returntype"":""Void"",""offset"":7637,""safe"":false},{""name"":""i14"",""parameters"":[],""returntype"":""Void"",""offset"":7659,""safe"":false},{""name"":""i15"",""parameters"":[],""returntype"":""Void"",""offset"":7681,""safe"":false},{""name"":""i16"",""parameters"":[],""returntype"":""Void"",""offset"":7703,""safe"":false},{""name"":""i17"",""parameters"":[],""returntype"":""Void"",""offset"":7725,""safe"":false},{""name"":""i18"",""parameters"":[],""returntype"":""Void"",""offset"":7748,""safe"":false},{""name"":""i19"",""parameters"":[],""returntype"":""Void"",""offset"":7771,""safe"":false},{""name"":""i20"",""parameters"":[],""returntype"":""Void"",""offset"":7794,""safe"":false},{""name"":""i21"",""parameters"":[],""returntype"":""Void"",""offset"":7817,""safe"":false},{""name"":""i22"",""parameters"":[],""returntype"":""Void"",""offset"":7840,""safe"":false},{""name"":""i23"",""parameters"":[],""returntype"":""Void"",""offset"":7863,""safe"":false},{""name"":""i24"",""parameters"":[],""returntype"":""Void"",""offset"":7886,""safe"":false},{""name"":""i25"",""parameters"":[],""returntype"":""Void"",""offset"":7909,""safe"":false},{""name"":""i26"",""parameters"":[],""returntype"":""Void"",""offset"":7932,""safe"":false},{""name"":""i27"",""parameters"":[],""returntype"":""Void"",""offset"":7955,""safe"":false},{""name"":""i28"",""parameters"":[],""returntype"":""Void"",""offset"":7978,""safe"":false},{""name"":""i29"",""parameters"":[],""returntype"":""Void"",""offset"":8001,""safe"":false},{""name"":""i30"",""parameters"":[],""returntype"":""Void"",""offset"":8024,""safe"":false},{""name"":""i31"",""parameters"":[],""returntype"":""Void"",""offset"":8047,""safe"":false},{""name"":""i32"",""parameters"":[],""returntype"":""Void"",""offset"":8070,""safe"":false},{""name"":""i33"",""parameters"":[],""returntype"":""Void"",""offset"":8093,""safe"":false},{""name"":""i34"",""parameters"":[],""returntype"":""Void"",""offset"":8116,""safe"":false},{""name"":""i35"",""parameters"":[],""returntype"":""Void"",""offset"":8139,""safe"":false},{""name"":""i36"",""parameters"":[],""returntype"":""Void"",""offset"":8162,""safe"":false},{""name"":""i37"",""parameters"":[],""returntype"":""Void"",""offset"":8185,""safe"":false},{""name"":""i38"",""parameters"":[],""returntype"":""Void"",""offset"":8208,""safe"":false},{""name"":""i39"",""parameters"":[],""returntype"":""Void"",""offset"":8231,""safe"":false},{""name"":""i40"",""parameters"":[],""returntype"":""Void"",""offset"":8254,""safe"":false},{""name"":""i41"",""parameters"":[],""returntype"":""Void"",""offset"":8277,""safe"":false},{""name"":""i42"",""parameters"":[],""returntype"":""Void"",""offset"":8300,""safe"":false},{""name"":""i43"",""parameters"":[],""returntype"":""Void"",""offset"":8323,""safe"":false},{""name"":""i44"",""parameters"":[],""returntype"":""Void"",""offset"":8346,""safe"":false},{""name"":""i45"",""parameters"":[],""returntype"":""Void"",""offset"":8369,""safe"":false},{""name"":""i46"",""parameters"":[],""returntype"":""Void"",""offset"":8392,""safe"":false},{""name"":""i47"",""parameters"":[],""returntype"":""Void"",""offset"":8415,""safe"":false},{""name"":""i48"",""parameters"":[],""returntype"":""Void"",""offset"":8438,""safe"":false},{""name"":""i49"",""parameters"":[],""returntype"":""Void"",""offset"":8461,""safe"":false},{""name"":""i50"",""parameters"":[],""returntype"":""Void"",""offset"":8484,""safe"":false},{""name"":""update"",""parameters"":[{""name"":""nefFile"",""type"":""ByteArray""},{""name"":""manifest"",""type"":""String""}],""returntype"":""Void"",""offset"":8511,""safe"":false},{""name"":""j"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":8578,""safe"":false},{""name"":""j0"",""parameters"":[],""returntype"":""Integer"",""offset"":8599,""safe"":false},{""name"":""j10"",""parameters"":[],""returntype"":""Void"",""offset"":8625,""safe"":false},{""name"":""j11"",""parameters"":[],""returntype"":""Void"",""offset"":8647,""safe"":false},{""name"":""j12"",""parameters"":[],""returntype"":""Void"",""offset"":8669,""safe"":false},{""name"":""j13"",""parameters"":[],""returntype"":""Void"",""offset"":8691,""safe"":false},{""name"":""j14"",""parameters"":[],""returntype"":""Void"",""offset"":8713,""safe"":false},{""name"":""j15"",""parameters"":[],""returntype"":""Void"",""offset"":8735,""safe"":false},{""name"":""j16"",""parameters"":[],""returntype"":""Void"",""offset"":8757,""safe"":false},{""name"":""j17"",""parameters"":[],""returntype"":""Void"",""offset"":8779,""safe"":false},{""name"":""j18"",""parameters"":[],""returntype"":""Void"",""offset"":8802,""safe"":false},{""name"":""j19"",""parameters"":[],""returntype"":""Void"",""offset"":8825,""safe"":false},{""name"":""j20"",""parameters"":[],""returntype"":""Void"",""offset"":8848,""safe"":false},{""name"":""j21"",""parameters"":[],""returntype"":""Void"",""offset"":8871,""safe"":false},{""name"":""j22"",""parameters"":[],""returntype"":""Void"",""offset"":8894,""safe"":false},{""name"":""j23"",""parameters"":[],""returntype"":""Void"",""offset"":8917,""safe"":false},{""name"":""j24"",""parameters"":[],""returntype"":""Void"",""offset"":8940,""safe"":false},{""name"":""j25"",""parameters"":[],""returntype"":""Void"",""offset"":8963,""safe"":false},{""name"":""j26"",""parameters"":[],""returntype"":""Void"",""offset"":8986,""safe"":false},{""name"":""j27"",""parameters"":[],""returntype"":""Void"",""offset"":9009,""safe"":false},{""name"":""j28"",""parameters"":[],""returntype"":""Void"",""offset"":9032,""safe"":false},{""name"":""j29"",""parameters"":[],""returntype"":""Void"",""offset"":9055,""safe"":false},{""name"":""j30"",""parameters"":[],""returntype"":""Void"",""offset"":9078,""safe"":false},{""name"":""j31"",""parameters"":[],""returntype"":""Void"",""offset"":9101,""safe"":false},{""name"":""j32"",""parameters"":[],""returntype"":""Void"",""offset"":9124,""safe"":false},{""name"":""j33"",""parameters"":[],""returntype"":""Void"",""offset"":9147,""safe"":false},{""name"":""j34"",""parameters"":[],""returntype"":""Void"",""offset"":9170,""safe"":false},{""name"":""j35"",""parameters"":[],""returntype"":""Void"",""offset"":9193,""safe"":false},{""name"":""j36"",""parameters"":[],""returntype"":""Void"",""offset"":9216,""safe"":false},{""name"":""j37"",""parameters"":[],""returntype"":""Void"",""offset"":9239,""safe"":false},{""name"":""j38"",""parameters"":[],""returntype"":""Void"",""offset"":9262,""safe"":false},{""name"":""j39"",""parameters"":[],""returntype"":""Void"",""offset"":9285,""safe"":false},{""name"":""j40"",""parameters"":[],""returntype"":""Void"",""offset"":9308,""safe"":false},{""name"":""j41"",""parameters"":[],""returntype"":""Void"",""offset"":9331,""safe"":false},{""name"":""j42"",""parameters"":[],""returntype"":""Void"",""offset"":9354,""safe"":false},{""name"":""j43"",""parameters"":[],""returntype"":""Void"",""offset"":9377,""safe"":false},{""name"":""j44"",""parameters"":[],""returntype"":""Void"",""offset"":9400,""safe"":false},{""name"":""j45"",""parameters"":[],""returntype"":""Void"",""offset"":9423,""safe"":false},{""name"":""j46"",""parameters"":[],""returntype"":""Void"",""offset"":9446,""safe"":false},{""name"":""j47"",""parameters"":[],""returntype"":""Void"",""offset"":9469,""safe"":false},{""name"":""j48"",""parameters"":[],""returntype"":""Void"",""offset"":9492,""safe"":false},{""name"":""j49"",""parameters"":[],""returntype"":""Void"",""offset"":9515,""safe"":false},{""name"":""j50"",""parameters"":[],""returntype"":""Void"",""offset"":9538,""safe"":false},{""name"":""k"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":9561,""safe"":false},{""name"":""k0"",""parameters"":[],""returntype"":""Integer"",""offset"":9601,""safe"":false},{""name"":""k10"",""parameters"":[],""returntype"":""Void"",""offset"":9646,""safe"":false},{""name"":""k11"",""parameters"":[],""returntype"":""Void"",""offset"":9687,""safe"":false},{""name"":""k12"",""parameters"":[],""returntype"":""Void"",""offset"":9728,""safe"":false},{""name"":""k13"",""parameters"":[],""returntype"":""Void"",""offset"":9769,""safe"":false},{""name"":""k14"",""parameters"":[],""returntype"":""Void"",""offset"":9810,""safe"":false},{""name"":""k15"",""parameters"":[],""returntype"":""Void"",""offset"":9851,""safe"":false},{""name"":""k16"",""parameters"":[],""returntype"":""Void"",""offset"":9892,""safe"":false},{""name"":""k17"",""parameters"":[],""returntype"":""Void"",""offset"":9933,""safe"":false},{""name"":""k18"",""parameters"":[],""returntype"":""Void"",""offset"":9975,""safe"":false},{""name"":""k19"",""parameters"":[],""returntype"":""Void"",""offset"":10017,""safe"":false},{""name"":""k20"",""parameters"":[],""returntype"":""Void"",""offset"":10059,""safe"":false},{""name"":""k21"",""parameters"":[],""returntype"":""Void"",""offset"":10101,""safe"":false},{""name"":""k22"",""parameters"":[],""returntype"":""Void"",""offset"":10143,""safe"":false},{""name"":""k23"",""parameters"":[],""returntype"":""Void"",""offset"":10185,""safe"":false},{""name"":""k24"",""parameters"":[],""returntype"":""Void"",""offset"":10227,""safe"":false},{""name"":""k25"",""parameters"":[],""returntype"":""Void"",""offset"":10269,""safe"":false},{""name"":""k26"",""parameters"":[],""returntype"":""Void"",""offset"":10311,""safe"":false},{""name"":""k27"",""parameters"":[],""returntype"":""Void"",""offset"":10353,""safe"":false},{""name"":""k28"",""parameters"":[],""returntype"":""Void"",""offset"":10395,""safe"":false},{""name"":""k29"",""parameters"":[],""returntype"":""Void"",""offset"":10437,""safe"":false},{""name"":""k30"",""parameters"":[],""returntype"":""Void"",""offset"":10479,""safe"":false},{""name"":""k31"",""parameters"":[],""returntype"":""Void"",""offset"":10521,""safe"":false},{""name"":""k32"",""parameters"":[],""returntype"":""Void"",""offset"":10563,""safe"":false},{""name"":""k33"",""parameters"":[],""returntype"":""Void"",""offset"":10605,""safe"":false},{""name"":""k34"",""parameters"":[],""returntype"":""Void"",""offset"":10647,""safe"":false},{""name"":""k35"",""parameters"":[],""returntype"":""Void"",""offset"":10689,""safe"":false},{""name"":""k36"",""parameters"":[],""returntype"":""Void"",""offset"":10731,""safe"":false},{""name"":""k37"",""parameters"":[],""returntype"":""Void"",""offset"":10773,""safe"":false},{""name"":""k38"",""parameters"":[],""returntype"":""Void"",""offset"":10815,""safe"":false},{""name"":""k39"",""parameters"":[],""returntype"":""Void"",""offset"":10857,""safe"":false},{""name"":""k40"",""parameters"":[],""returntype"":""Void"",""offset"":10899,""safe"":false},{""name"":""k41"",""parameters"":[],""returntype"":""Void"",""offset"":10941,""safe"":false},{""name"":""k42"",""parameters"":[],""returntype"":""Void"",""offset"":10983,""safe"":false},{""name"":""k43"",""parameters"":[],""returntype"":""Void"",""offset"":11025,""safe"":false},{""name"":""k44"",""parameters"":[],""returntype"":""Void"",""offset"":11067,""safe"":false},{""name"":""k45"",""parameters"":[],""returntype"":""Void"",""offset"":11109,""safe"":false},{""name"":""k46"",""parameters"":[],""returntype"":""Void"",""offset"":11151,""safe"":false},{""name"":""k47"",""parameters"":[],""returntype"":""Void"",""offset"":11193,""safe"":false},{""name"":""k48"",""parameters"":[],""returntype"":""Void"",""offset"":11235,""safe"":false},{""name"":""k49"",""parameters"":[],""returntype"":""Void"",""offset"":11277,""safe"":false},{""name"":""k50"",""parameters"":[],""returntype"":""Void"",""offset"":11319,""safe"":false},{""name"":""l"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":11361,""safe"":false},{""name"":""l0"",""parameters"":[],""returntype"":""Integer"",""offset"":11401,""safe"":false},{""name"":""l10"",""parameters"":[],""returntype"":""Void"",""offset"":11446,""safe"":false},{""name"":""l11"",""parameters"":[],""returntype"":""Void"",""offset"":11487,""safe"":false},{""name"":""l12"",""parameters"":[],""returntype"":""Void"",""offset"":11528,""safe"":false},{""name"":""l13"",""parameters"":[],""returntype"":""Void"",""offset"":11569,""safe"":false},{""name"":""l14"",""parameters"":[],""returntype"":""Void"",""offset"":11610,""safe"":false},{""name"":""l15"",""parameters"":[],""returntype"":""Void"",""offset"":11651,""safe"":false},{""name"":""l16"",""parameters"":[],""returntype"":""Void"",""offset"":11692,""safe"":false},{""name"":""l17"",""parameters"":[],""returntype"":""Void"",""offset"":11733,""safe"":false},{""name"":""l18"",""parameters"":[],""returntype"":""Void"",""offset"":11775,""safe"":false},{""name"":""l19"",""parameters"":[],""returntype"":""Void"",""offset"":11817,""safe"":false},{""name"":""l20"",""parameters"":[],""returntype"":""Void"",""offset"":11859,""safe"":false},{""name"":""l21"",""parameters"":[],""returntype"":""Void"",""offset"":11901,""safe"":false},{""name"":""l22"",""parameters"":[],""returntype"":""Void"",""offset"":11943,""safe"":false},{""name"":""l23"",""parameters"":[],""returntype"":""Void"",""offset"":11985,""safe"":false},{""name"":""l24"",""parameters"":[],""returntype"":""Void"",""offset"":12027,""safe"":false},{""name"":""l25"",""parameters"":[],""returntype"":""Void"",""offset"":12069,""safe"":false},{""name"":""l26"",""parameters"":[],""returntype"":""Void"",""offset"":12111,""safe"":false},{""name"":""l27"",""parameters"":[],""returntype"":""Void"",""offset"":12153,""safe"":false},{""name"":""l28"",""parameters"":[],""returntype"":""Void"",""offset"":12195,""safe"":false},{""name"":""l29"",""parameters"":[],""returntype"":""Void"",""offset"":12237,""safe"":false},{""name"":""l30"",""parameters"":[],""returntype"":""Void"",""offset"":12279,""safe"":false},{""name"":""l31"",""parameters"":[],""returntype"":""Void"",""offset"":12321,""safe"":false},{""name"":""l32"",""parameters"":[],""returntype"":""Void"",""offset"":12363,""safe"":false},{""name"":""l33"",""parameters"":[],""returntype"":""Void"",""offset"":12405,""safe"":false},{""name"":""l34"",""parameters"":[],""returntype"":""Void"",""offset"":12447,""safe"":false},{""name"":""l35"",""parameters"":[],""returntype"":""Void"",""offset"":12489,""safe"":false},{""name"":""l36"",""parameters"":[],""returntype"":""Void"",""offset"":12531,""safe"":false},{""name"":""l37"",""parameters"":[],""returntype"":""Void"",""offset"":12573,""safe"":false},{""name"":""l38"",""parameters"":[],""returntype"":""Void"",""offset"":12615,""safe"":false},{""name"":""l39"",""parameters"":[],""returntype"":""Void"",""offset"":12657,""safe"":false},{""name"":""l40"",""parameters"":[],""returntype"":""Void"",""offset"":12699,""safe"":false},{""name"":""l41"",""parameters"":[],""returntype"":""Void"",""offset"":12741,""safe"":false},{""name"":""l42"",""parameters"":[],""returntype"":""Void"",""offset"":12783,""safe"":false},{""name"":""l43"",""parameters"":[],""returntype"":""Void"",""offset"":12825,""safe"":false},{""name"":""l44"",""parameters"":[],""returntype"":""Void"",""offset"":12867,""safe"":false},{""name"":""l45"",""parameters"":[],""returntype"":""Void"",""offset"":12909,""safe"":false},{""name"":""l46"",""parameters"":[],""returntype"":""Void"",""offset"":12951,""safe"":false},{""name"":""l47"",""parameters"":[],""returntype"":""Void"",""offset"":12993,""safe"":false},{""name"":""l48"",""parameters"":[],""returntype"":""Void"",""offset"":13035,""safe"":false},{""name"":""l49"",""parameters"":[],""returntype"":""Void"",""offset"":13077,""safe"":false},{""name"":""l50"",""parameters"":[],""returntype"":""Void"",""offset"":13119,""safe"":false},{""name"":""m"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":13161,""safe"":false},{""name"":""m0"",""parameters"":[],""returntype"":""Integer"",""offset"":13181,""safe"":false},{""name"":""m10"",""parameters"":[],""returntype"":""Void"",""offset"":13206,""safe"":false},{""name"":""m11"",""parameters"":[],""returntype"":""Void"",""offset"":13227,""safe"":false},{""name"":""m12"",""parameters"":[],""returntype"":""Void"",""offset"":13248,""safe"":false},{""name"":""m13"",""parameters"":[],""returntype"":""Void"",""offset"":13269,""safe"":false},{""name"":""m14"",""parameters"":[],""returntype"":""Void"",""offset"":13290,""safe"":false},{""name"":""m15"",""parameters"":[],""returntype"":""Void"",""offset"":13311,""safe"":false},{""name"":""m16"",""parameters"":[],""returntype"":""Void"",""offset"":13332,""safe"":false},{""name"":""m17"",""parameters"":[],""returntype"":""Void"",""offset"":13353,""safe"":false},{""name"":""m18"",""parameters"":[],""returntype"":""Void"",""offset"":13375,""safe"":false},{""name"":""m19"",""parameters"":[],""returntype"":""Void"",""offset"":13397,""safe"":false},{""name"":""m20"",""parameters"":[],""returntype"":""Void"",""offset"":13419,""safe"":false},{""name"":""m21"",""parameters"":[],""returntype"":""Void"",""offset"":13441,""safe"":false},{""name"":""m22"",""parameters"":[],""returntype"":""Void"",""offset"":13463,""safe"":false},{""name"":""m23"",""parameters"":[],""returntype"":""Void"",""offset"":13485,""safe"":false},{""name"":""m24"",""parameters"":[],""returntype"":""Void"",""offset"":13507,""safe"":false},{""name"":""m25"",""parameters"":[],""returntype"":""Void"",""offset"":13529,""safe"":false},{""name"":""m26"",""parameters"":[],""returntype"":""Void"",""offset"":13551,""safe"":false},{""name"":""m27"",""parameters"":[],""returntype"":""Void"",""offset"":13573,""safe"":false},{""name"":""m28"",""parameters"":[],""returntype"":""Void"",""offset"":13595,""safe"":false},{""name"":""m29"",""parameters"":[],""returntype"":""Void"",""offset"":13617,""safe"":false},{""name"":""m30"",""parameters"":[],""returntype"":""Void"",""offset"":13639,""safe"":false},{""name"":""m31"",""parameters"":[],""returntype"":""Void"",""offset"":13661,""safe"":false},{""name"":""m32"",""parameters"":[],""returntype"":""Void"",""offset"":13683,""safe"":false},{""name"":""m33"",""parameters"":[],""returntype"":""Void"",""offset"":13705,""safe"":false},{""name"":""m34"",""parameters"":[],""returntype"":""Void"",""offset"":13727,""safe"":false},{""name"":""m35"",""parameters"":[],""returntype"":""Void"",""offset"":13749,""safe"":false},{""name"":""m36"",""parameters"":[],""returntype"":""Void"",""offset"":13771,""safe"":false},{""name"":""m37"",""parameters"":[],""returntype"":""Void"",""offset"":13793,""safe"":false},{""name"":""m38"",""parameters"":[],""returntype"":""Void"",""offset"":13815,""safe"":false},{""name"":""m39"",""parameters"":[],""returntype"":""Void"",""offset"":13837,""safe"":false},{""name"":""m40"",""parameters"":[],""returntype"":""Void"",""offset"":13859,""safe"":false},{""name"":""m41"",""parameters"":[],""returntype"":""Void"",""offset"":13881,""safe"":false},{""name"":""m42"",""parameters"":[],""returntype"":""Void"",""offset"":13903,""safe"":false},{""name"":""m43"",""parameters"":[],""returntype"":""Void"",""offset"":13925,""safe"":false},{""name"":""m44"",""parameters"":[],""returntype"":""Void"",""offset"":13947,""safe"":false},{""name"":""m45"",""parameters"":[],""returntype"":""Void"",""offset"":13969,""safe"":false},{""name"":""m46"",""parameters"":[],""returntype"":""Void"",""offset"":13991,""safe"":false},{""name"":""m47"",""parameters"":[],""returntype"":""Void"",""offset"":14013,""safe"":false},{""name"":""m48"",""parameters"":[],""returntype"":""Void"",""offset"":14035,""safe"":false},{""name"":""m49"",""parameters"":[],""returntype"":""Void"",""offset"":14057,""safe"":false},{""name"":""m50"",""parameters"":[],""returntype"":""Void"",""offset"":14079,""safe"":false},{""name"":""n"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":14101,""safe"":false},{""name"":""n0"",""parameters"":[],""returntype"":""Integer"",""offset"":14121,""safe"":false},{""name"":""n10"",""parameters"":[],""returntype"":""Void"",""offset"":14146,""safe"":false},{""name"":""n11"",""parameters"":[],""returntype"":""Void"",""offset"":14167,""safe"":false},{""name"":""n12"",""parameters"":[],""returntype"":""Void"",""offset"":14188,""safe"":false},{""name"":""n13"",""parameters"":[],""returntype"":""Void"",""offset"":14209,""safe"":false},{""name"":""n14"",""parameters"":[],""returntype"":""Void"",""offset"":14230,""safe"":false},{""name"":""n15"",""parameters"":[],""returntype"":""Void"",""offset"":14251,""safe"":false},{""name"":""n16"",""parameters"":[],""returntype"":""Void"",""offset"":14272,""safe"":false},{""name"":""n17"",""parameters"":[],""returntype"":""Void"",""offset"":14293,""safe"":false},{""name"":""n18"",""parameters"":[],""returntype"":""Void"",""offset"":14315,""safe"":false},{""name"":""n19"",""parameters"":[],""returntype"":""Void"",""offset"":14337,""safe"":false},{""name"":""n20"",""parameters"":[],""returntype"":""Void"",""offset"":14359,""safe"":false},{""name"":""n21"",""parameters"":[],""returntype"":""Void"",""offset"":14381,""safe"":false},{""name"":""n22"",""parameters"":[],""returntype"":""Void"",""offset"":14403,""safe"":false},{""name"":""n23"",""parameters"":[],""returntype"":""Void"",""offset"":14425,""safe"":false},{""name"":""n24"",""parameters"":[],""returntype"":""Void"",""offset"":14447,""safe"":false},{""name"":""n25"",""parameters"":[],""returntype"":""Void"",""offset"":14469,""safe"":false},{""name"":""n26"",""parameters"":[],""returntype"":""Void"",""offset"":14491,""safe"":false},{""name"":""n27"",""parameters"":[],""returntype"":""Void"",""offset"":14513,""safe"":false},{""name"":""n28"",""parameters"":[],""returntype"":""Void"",""offset"":14535,""safe"":false},{""name"":""n29"",""parameters"":[],""returntype"":""Void"",""offset"":14557,""safe"":false},{""name"":""n30"",""parameters"":[],""returntype"":""Void"",""offset"":14579,""safe"":false},{""name"":""n31"",""parameters"":[],""returntype"":""Void"",""offset"":14601,""safe"":false},{""name"":""n32"",""parameters"":[],""returntype"":""Void"",""offset"":14623,""safe"":false},{""name"":""n33"",""parameters"":[],""returntype"":""Void"",""offset"":14645,""safe"":false},{""name"":""n34"",""parameters"":[],""returntype"":""Void"",""offset"":14667,""safe"":false},{""name"":""n35"",""parameters"":[],""returntype"":""Void"",""offset"":14689,""safe"":false},{""name"":""n36"",""parameters"":[],""returntype"":""Void"",""offset"":14711,""safe"":false},{""name"":""n37"",""parameters"":[],""returntype"":""Void"",""offset"":14733,""safe"":false},{""name"":""n38"",""parameters"":[],""returntype"":""Void"",""offset"":14755,""safe"":false},{""name"":""n39"",""parameters"":[],""returntype"":""Void"",""offset"":14777,""safe"":false},{""name"":""n40"",""parameters"":[],""returntype"":""Void"",""offset"":14799,""safe"":false},{""name"":""n41"",""parameters"":[],""returntype"":""Void"",""offset"":14821,""safe"":false},{""name"":""n42"",""parameters"":[],""returntype"":""Void"",""offset"":14843,""safe"":false},{""name"":""n43"",""parameters"":[],""returntype"":""Void"",""offset"":14865,""safe"":false},{""name"":""n44"",""parameters"":[],""returntype"":""Void"",""offset"":14887,""safe"":false},{""name"":""n45"",""parameters"":[],""returntype"":""Void"",""offset"":14909,""safe"":false},{""name"":""n46"",""parameters"":[],""returntype"":""Void"",""offset"":14931,""safe"":false},{""name"":""n47"",""parameters"":[],""returntype"":""Void"",""offset"":14953,""safe"":false},{""name"":""n48"",""parameters"":[],""returntype"":""Void"",""offset"":14975,""safe"":false},{""name"":""n49"",""parameters"":[],""returntype"":""Void"",""offset"":14997,""safe"":false},{""name"":""n50"",""parameters"":[],""returntype"":""Void"",""offset"":15019,""safe"":false},{""name"":""_initialize"",""parameters"":[],""returntype"":""Void"",""offset"":15041,""safe"":false}],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""extra"":{""Author"":""Test"",""Email"":""Test@Test"",""Description"":""This is a Test Contract""}}"; var manifest = ContractManifest.Parse(json); - var counter = new ReferenceCounter(); + var counter = new ReferenceCounterV2(); var item = manifest.ToStackItem(counter); var data = BinarySerializer.Serialize(item, 1024 * 1024, 4096); @@ -118,7 +118,7 @@ public void ToInteroperable_Trust() { var json = @"{""name"":""CallOracleContract-6"",""groups"":[],""features"":{},""supportedstandards"":[],""abi"":{""methods"":[{""name"":""request"",""parameters"":[{""name"":""url"",""type"":""String""},{""name"":""filter"",""type"":""String""},{""name"":""gasForResponse"",""type"":""Integer""}],""returntype"":""Void"",""offset"":0,""safe"":false},{""name"":""callback"",""parameters"":[{""name"":""url"",""type"":""String""},{""name"":""userData"",""type"":""Any""},{""name"":""responseCode"",""type"":""Integer""},{""name"":""response"",""type"":""ByteArray""}],""returntype"":""Void"",""offset"":86,""safe"":false},{""name"":""getStoredUrl"",""parameters"":[],""returntype"":""String"",""offset"":129,""safe"":false},{""name"":""getStoredResponseCode"",""parameters"":[],""returntype"":""Integer"",""offset"":142,""safe"":false},{""name"":""getStoredResponse"",""parameters"":[],""returntype"":""ByteArray"",""offset"":165,""safe"":false}],""events"":[]},""permissions"":[{""contract"":""0xfe924b7cfe89ddd271abaf7210a80a7e11178758"",""methods"":""*""},{""contract"":""*"",""methods"":""*""}],""trusts"":[""0xfe924b7cfe89ddd271abaf7210a80a7e11178758"",""*""],""extra"":{}}"; var manifest = ContractManifest.Parse(json); - var s = (VM.Types.Struct)manifest.ToStackItem(new ReferenceCounter()); + var s = (VM.Types.Struct)manifest.ToStackItem(new ReferenceCounterV2()); manifest = s.ToInteroperable(); Assert.IsFalse(manifest.Permissions[0].Contract.IsWildcard); diff --git a/tests/Neo.UnitTests/SmartContract/UT_NotifyEventArgs.cs b/tests/Neo.UnitTests/SmartContract/UT_NotifyEventArgs.cs index 59afbbb760..6e80a93bb0 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_NotifyEventArgs.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_NotifyEventArgs.cs @@ -43,7 +43,7 @@ public void TestIssue3300() // https://github.com/neo-project/neo/issues/3300 engine.LoadScript(script.ToArray()); } - var ns = new Array(engine.ReferenceCounter); + var ns = new Array(); for (var i = 0; i < 500; i++) { ns.Add(""); @@ -54,12 +54,12 @@ public void TestIssue3300() // https://github.com/neo-project/neo/issues/3300 // This should have being 0, but we have optimized the vm to not clean the reference counter // unless it is necessary, so the reference counter will be 1000. // Same reason why its 1504 instead of 504. - Assert.AreEqual(1000, engine.ReferenceCounter.Count); + Assert.AreEqual(0, engine.ReferenceCounter.Count); // This will make a deepcopy for the notification, along with the 500 state items. engine.GetNotifications(hash); // With the fix of issue 3300, the reference counter calculates not only // the notifaction items, but also the subitems of the notification state. - Assert.AreEqual(1504, engine.ReferenceCounter.Count); + Assert.AreEqual(0, engine.ReferenceCounter.Count); } } } diff --git a/tests/Neo.VM.Tests/UT_EvaluationStack.cs b/tests/Neo.VM.Tests/UT_EvaluationStack.cs index fb1f5e5813..6aa15ea209 100644 --- a/tests/Neo.VM.Tests/UT_EvaluationStack.cs +++ b/tests/Neo.VM.Tests/UT_EvaluationStack.cs @@ -25,7 +25,7 @@ public class UT_EvaluationStack private static EvaluationStack CreateOrderedStack(int count) { var check = new Integer[count]; - var stack = new EvaluationStack(new ReferenceCounter()); + var stack = new EvaluationStack(new ReferenceCounterV2()); for (int x = 1; x <= count; x++) { @@ -56,7 +56,7 @@ public void TestClear() public void TestCopyTo() { var stack = CreateOrderedStack(3); - var copy = new EvaluationStack(new ReferenceCounter()); + var copy = new EvaluationStack(new ReferenceCounterV2()); Assert.ThrowsException(() => stack.CopyTo(copy, -2)); Assert.ThrowsException(() => stack.CopyTo(copy, 4)); @@ -93,7 +93,7 @@ public void TestCopyTo() public void TestMoveTo() { var stack = CreateOrderedStack(3); - var other = new EvaluationStack(new ReferenceCounter()); + var other = new EvaluationStack(new ReferenceCounterV2()); stack.MoveTo(other, 0); @@ -126,7 +126,7 @@ public void TestMoveTo() [TestMethod] public void TestInsertPeek() { - var stack = new EvaluationStack(new ReferenceCounter()); + var stack = new EvaluationStack(new ReferenceCounterV2()); stack.Insert(0, 3); stack.Insert(1, 1); @@ -203,7 +203,7 @@ public void TestReverse() [TestMethod] public void TestEvaluationStackPrint() { - var stack = new EvaluationStack(new ReferenceCounter()); + var stack = new EvaluationStack(new ReferenceCounterV2()); stack.Insert(0, 3); stack.Insert(1, 1); @@ -216,7 +216,7 @@ public void TestEvaluationStackPrint() [TestMethod] public void TestPrintInvalidUTF8() { - var stack = new EvaluationStack(new ReferenceCounter()); + var stack = new EvaluationStack(new ReferenceCounterV2()); stack.Insert(0, "4CC95219999D421243C8161E3FC0F4290C067845".FromHexString()); Assert.AreEqual("[ByteString(\"Base64: TMlSGZmdQhJDyBYeP8D0KQwGeEU=\")]", stack.ToString()); } diff --git a/tests/Neo.VM.Tests/UT_ExecutionContext.cs b/tests/Neo.VM.Tests/UT_ExecutionContext.cs index b53003a7e6..14c4e3235e 100644 --- a/tests/Neo.VM.Tests/UT_ExecutionContext.cs +++ b/tests/Neo.VM.Tests/UT_ExecutionContext.cs @@ -27,7 +27,7 @@ class TestState [TestMethod] public void TestStateTest() { - var context = new ExecutionContext(Array.Empty(), -1, new ReferenceCounter()); + var context = new ExecutionContext(Array.Empty(), -1, new ReferenceCounterV2()); // Test factory diff --git a/tests/Neo.VM.Tests/UT_ReferenceCounter.cs b/tests/Neo.VM.Tests/UT_ReferenceCounter.cs index 61f7788dd8..6ce0dae21f 100644 --- a/tests/Neo.VM.Tests/UT_ReferenceCounter.cs +++ b/tests/Neo.VM.Tests/UT_ReferenceCounter.cs @@ -158,9 +158,9 @@ public void TestRemoveReferrer() Assert.AreEqual(VMState.BREAK, debugger.StepInto()); Assert.AreEqual(3, engine.ReferenceCounter.Count); Assert.AreEqual(VMState.BREAK, debugger.StepInto()); - Assert.AreEqual(2, engine.ReferenceCounter.Count); - Assert.AreEqual(VMState.HALT, debugger.Execute()); Assert.AreEqual(1, engine.ReferenceCounter.Count); + Assert.AreEqual(VMState.HALT, debugger.Execute()); + Assert.AreEqual(0, engine.ReferenceCounter.Count); } [TestMethod] @@ -237,18 +237,18 @@ public void TestArrayNoPush() using ExecutionEngine engine = new(); engine.LoadScript(sb.ToArray()); Assert.AreEqual(0, engine.ReferenceCounter.Count); - Array array = new(engine.ReferenceCounter, new StackItem[] { 1, 2, 3, 4 }); - Assert.AreEqual(array.Count, engine.ReferenceCounter.Count); + Array array = new(new StackItem[] { 1, 2, 3, 4 }); + engine.CurrentContext.EvaluationStack.Push(array); + Assert.AreEqual(array.Count + 1, engine.ReferenceCounter.Count); Assert.AreEqual(VMState.HALT, engine.Execute()); - Assert.AreEqual(array.Count, engine.ReferenceCounter.Count); + Assert.AreEqual(array.Count + 1, engine.ReferenceCounter.Count); } [TestMethod] - [ExpectedException(typeof(InvalidOperationException))] public void TestInvalidReferenceStackItem() { - var reference = new ReferenceCounter(); - var arr = new Array(reference); + + var arr = new Array(); var arr2 = new Array(); for (var i = 0; i < 10; i++) @@ -257,7 +257,12 @@ public void TestInvalidReferenceStackItem() } arr.Add(arr2); - Assert.AreEqual(11, reference.Count); + + var engine = new ExecutionEngine(); + engine.LoadScript(new Script((byte[])[(byte)OpCode.NOP])); + + engine.CurrentContext.EvaluationStack.Push(arr); + Assert.AreEqual(12, engine.ReferenceCounter.Count); } } } diff --git a/tests/Neo.VM.Tests/UT_Slot.cs b/tests/Neo.VM.Tests/UT_Slot.cs index ea2f38029b..d175be1310 100644 --- a/tests/Neo.VM.Tests/UT_Slot.cs +++ b/tests/Neo.VM.Tests/UT_Slot.cs @@ -31,7 +31,7 @@ private static Slot CreateOrderedSlot(int count) check[x - 1] = x; } - var slot = new Slot(check, new ReferenceCounter()); + var slot = new Slot(check, new ReferenceCounterV2()); Assert.AreEqual(count, slot.Count); CollectionAssert.AreEqual(check, slot.ToArray()); From a6b3f697ce953096c9fd6f43a77887064c287c8e Mon Sep 17 00:00:00 2001 From: Jimmy Date: Fri, 15 Nov 2024 23:46:49 +0800 Subject: [PATCH 02/36] format --- src/Neo.VM/ReferenceCounterV2.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Neo.VM/ReferenceCounterV2.cs b/src/Neo.VM/ReferenceCounterV2.cs index 7d7430da95..0dad0f185f 100644 --- a/src/Neo.VM/ReferenceCounterV2.cs +++ b/src/Neo.VM/ReferenceCounterV2.cs @@ -1,4 +1,4 @@ -// Copyright (C) 2015-2024 The Neo Project. +// Copyright (C) 2015-2024 The Neo Project. // // ReferenceCounterV2.cs file belongs to the neo project and is free // software distributed under the MIT software license, see the From 4874a6ec2b5af41297599d831647c351f9f4bd71 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Sat, 16 Nov 2024 10:03:26 +0800 Subject: [PATCH 03/36] fix building issue in benchmark --- src/Neo.VM/Types/CompoundType.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Neo.VM/Types/CompoundType.cs b/src/Neo.VM/Types/CompoundType.cs index e30502f43d..0fc15568c8 100644 --- a/src/Neo.VM/Types/CompoundType.cs +++ b/src/Neo.VM/Types/CompoundType.cs @@ -30,7 +30,7 @@ public abstract class CompoundType : StackItem /// Create a new with the specified reference counter. /// /// The reference counter to be used. - protected CompoundType(IReferenceCounter? referenceCounter) + protected CompoundType(IReferenceCounter? referenceCounter = null) { } From a8fd5873382e3ba9e463e224df39a672bc68f7d2 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Sun, 17 Nov 2024 01:05:20 +0800 Subject: [PATCH 04/36] fix popitem --- src/Neo.VM/JumpTable/JumpTable.Compound.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Neo.VM/JumpTable/JumpTable.Compound.cs b/src/Neo.VM/JumpTable/JumpTable.Compound.cs index c97ae7769f..a9b0793d66 100644 --- a/src/Neo.VM/JumpTable/JumpTable.Compound.cs +++ b/src/Neo.VM/JumpTable/JumpTable.Compound.cs @@ -573,7 +573,6 @@ public virtual void PopItem(ExecutionEngine engine, Instruction instruction) var index = x.Count - 1; var item = x[index]; engine.Push(item); - engine.ReferenceCounter.RemoveStackReference(item); x.RemoveAt(index); } } From 4de3809c5c01026a18895258ae5c5c90c6fa7cd2 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Sun, 17 Nov 2024 13:07:11 +0800 Subject: [PATCH 05/36] revert change --- src/Neo.VM/JumpTable/JumpTable.Compound.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Neo.VM/JumpTable/JumpTable.Compound.cs b/src/Neo.VM/JumpTable/JumpTable.Compound.cs index a9b0793d66..ce5e314385 100644 --- a/src/Neo.VM/JumpTable/JumpTable.Compound.cs +++ b/src/Neo.VM/JumpTable/JumpTable.Compound.cs @@ -571,8 +571,7 @@ public virtual void PopItem(ExecutionEngine engine, Instruction instruction) { var x = engine.Pop(); var index = x.Count - 1; - var item = x[index]; - engine.Push(item); + engine.Push(x[index]); x.RemoveAt(index); } } From d7cde616447f2a1a57ddf9ab9263f5eab5966248 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Sun, 17 Nov 2024 20:00:42 +0800 Subject: [PATCH 06/36] revert to fix compatibillity --- benchmarks/Neo.VM.Benchmarks/TestArray.cs | 26 ++++++++++-- benchmarks/Neo.VM.Benchmarks/TestStruct.cs | 18 +++++--- .../VMTypes/Benchmarks_Convert.cs | 14 +++---- .../VMTypes/Benchmarks_DeepCopy.cs | 28 ++++++------- src/Neo.VM/ExecutionEngine.cs | 5 ++- src/Neo.VM/JumpTable/JumpTable.Compound.cs | 42 +++++-------------- src/Neo.VM/Types/Array.cs | 35 +++++++++++++++- src/Neo.VM/Types/CompoundType.cs | 2 + src/Neo.VM/Types/Map.cs | 22 +++++++++- src/Neo.VM/Types/Struct.cs | 6 +-- .../P2P/Payloads/Conditions/AndCondition.cs | 4 +- .../Payloads/Conditions/BooleanCondition.cs | 2 +- .../Conditions/CalledByContractCondition.cs | 2 +- .../Conditions/CalledByGroupCondition.cs | 2 +- .../P2P/Payloads/Conditions/GroupCondition.cs | 2 +- .../P2P/Payloads/Conditions/NotCondition.cs | 2 +- .../P2P/Payloads/Conditions/OrCondition.cs | 4 +- .../Conditions/ScriptHashCondition.cs | 2 +- .../Payloads/Conditions/WitnessCondition.cs | 4 +- src/Neo/Network/P2P/Payloads/Signer.cs | 10 ++--- src/Neo/Network/P2P/Payloads/Transaction.cs | 4 +- src/Neo/Network/P2P/Payloads/WitnessRule.cs | 4 +- .../ApplicationEngine.Runtime.cs | 2 +- src/Neo/SmartContract/ApplicationEngine.cs | 4 +- src/Neo/SmartContract/BinarySerializer.cs | 6 +-- src/Neo/SmartContract/ContractState.cs | 4 +- src/Neo/SmartContract/IInteroperable.cs | 2 +- .../Iterators/StorageIterator.cs | 2 +- src/Neo/SmartContract/JsonSerializer.cs | 4 +- src/Neo/SmartContract/Manifest/ContractAbi.cs | 8 ++-- .../Manifest/ContractEventDescriptor.cs | 6 +-- .../SmartContract/Manifest/ContractGroup.cs | 4 +- .../Manifest/ContractManifest.cs | 14 +++---- .../Manifest/ContractMethodDescriptor.cs | 2 +- .../Manifest/ContractParameterDefinition.cs | 4 +- .../Manifest/ContractPermission.cs | 6 +-- src/Neo/SmartContract/Native/AccountState.cs | 4 +- .../Native/ContractManagement.cs | 6 +-- src/Neo/SmartContract/Native/FungibleToken.cs | 2 +- .../SmartContract/Native/HashIndexState.cs | 4 +- .../SmartContract/Native/InteroperableList.cs | 4 +- src/Neo/SmartContract/Native/NeoToken.cs | 20 ++++----- .../SmartContract/Native/OracleContract.cs | 4 +- src/Neo/SmartContract/Native/OracleRequest.cs | 4 +- .../SmartContract/Native/RoleManagement.cs | 2 +- .../SmartContract/Native/TransactionState.cs | 6 +-- src/Neo/SmartContract/Native/TrimmedBlock.cs | 4 +- src/Neo/SmartContract/NotifyEventArgs.cs | 8 ++-- .../Manifest/UT_ContractManifest.cs | 4 +- .../SmartContract/UT_NotifyEventArgs.cs | 6 +-- tests/Neo.VM.Tests/UT_EvaluationStack.cs | 12 +++--- tests/Neo.VM.Tests/UT_ExecutionContext.cs | 2 +- tests/Neo.VM.Tests/UT_ReferenceCounter.cs | 23 ++++------ tests/Neo.VM.Tests/UT_Slot.cs | 2 +- 54 files changed, 240 insertions(+), 185 deletions(-) diff --git a/benchmarks/Neo.VM.Benchmarks/TestArray.cs b/benchmarks/Neo.VM.Benchmarks/TestArray.cs index 8398127e5e..8a0d84a9e1 100644 --- a/benchmarks/Neo.VM.Benchmarks/TestArray.cs +++ b/benchmarks/Neo.VM.Benchmarks/TestArray.cs @@ -29,7 +29,9 @@ public StackItem this[int index] set { if (IsReadOnly) throw new InvalidOperationException("The object is readonly."); + ReferenceCounter?.RemoveReference(_array[index], this); _array[index] = value; + ReferenceCounter?.AddReference(value, this); } } @@ -41,14 +43,22 @@ public StackItem this[int index] public override int SubItemsCount => _array.Count; public override StackItemType Type => StackItemType.Array; + /// + /// Create an array containing the specified items. + /// + /// The items to be included in the array. + public TestArray(IEnumerable? items = null) + : this(null, items) + { + } /// /// Create an array containing the specified items. And make the array use the specified . /// /// The to be used by this array. /// The items to be included in the array. - public TestArray(IEnumerable? items = null) - : base() + public TestArray(IReferenceCounter? referenceCounter, IEnumerable? items = null) + : base(referenceCounter) { _array = items switch { @@ -56,6 +66,9 @@ public TestArray(IEnumerable? items = null) List list => list, _ => new List(items) }; + if (referenceCounter != null) + foreach (StackItem item in _array) + referenceCounter.AddReference(item, this); } /// @@ -66,25 +79,29 @@ public void Add(StackItem item) { if (IsReadOnly) throw new InvalidOperationException("The object is readonly."); _array.Add(item); + ReferenceCounter?.AddReference(item, this); } public override void Clear() { if (IsReadOnly) throw new InvalidOperationException("The object is readonly."); + if (ReferenceCounter != null) + foreach (StackItem item in _array) + ReferenceCounter.RemoveReference(item, this); _array.Clear(); } public override StackItem ConvertTo(StackItemType type) { if (Type == StackItemType.Array && type == StackItemType.Struct) - return new Struct(new List(_array)); + return new Struct(ReferenceCounter, new List(_array)); return base.ConvertTo(type); } internal sealed override StackItem DeepCopy(Dictionary refMap, bool asImmutable) { if (refMap.TryGetValue(this, out StackItem? mappedItem)) return mappedItem; - var result = this is TestStruct ? new TestStruct() : new TestArray(); + var result = this is TestStruct ? new TestStruct(ReferenceCounter) : new TestArray(ReferenceCounter); refMap.Add(this, result); foreach (StackItem item in _array) result.Add(item.DeepCopy(refMap, asImmutable)); @@ -109,6 +126,7 @@ public IEnumerator GetEnumerator() public void RemoveAt(int index) { if (IsReadOnly) throw new InvalidOperationException("The object is readonly."); + ReferenceCounter?.RemoveReference(_array[index], this); _array.RemoveAt(index); } diff --git a/benchmarks/Neo.VM.Benchmarks/TestStruct.cs b/benchmarks/Neo.VM.Benchmarks/TestStruct.cs index baaae23e71..24b32530b5 100644 --- a/benchmarks/Neo.VM.Benchmarks/TestStruct.cs +++ b/benchmarks/Neo.VM.Benchmarks/TestStruct.cs @@ -17,14 +17,22 @@ public class TestStruct : TestArray { public override StackItemType Type => StackItemType.Struct; + /// + /// Create a structure with the specified fields. + /// + /// The fields to be included in the structure. + public TestStruct(IEnumerable? fields = null) + : this(null, fields) + { + } /// /// Create a structure with the specified fields. And make the structure use the specified . /// /// The to be used by this structure. /// The fields to be included in the structure. - public TestStruct(IEnumerable? fields = null) - : base(fields) + public TestStruct(IReferenceCounter? referenceCounter, IEnumerable? fields = null) + : base(referenceCounter, fields) { } @@ -36,7 +44,7 @@ public TestStruct(IEnumerable? fields = null) public TestStruct Clone(ExecutionEngineLimits limits) { int count = (int)(limits.MaxStackSize - 1); - TestStruct result = new(); + TestStruct result = new(ReferenceCounter); Queue queue = new(); queue.Enqueue(result); queue.Enqueue(this); @@ -50,7 +58,7 @@ public TestStruct Clone(ExecutionEngineLimits limits) if (count < 0) throw new InvalidOperationException("Beyond clone limits!"); if (item is TestStruct sb) { - TestStruct sa = new(); + TestStruct sa = new(ReferenceCounter); a.Add(sa); queue.Enqueue(sa); queue.Enqueue(sb); @@ -67,7 +75,7 @@ public TestStruct Clone(ExecutionEngineLimits limits) public override StackItem ConvertTo(StackItemType type) { if (type == StackItemType.Array) - return new TestArray(new List(_array)); + return new TestArray(ReferenceCounter, new List(_array)); return base.ConvertTo(type); } diff --git a/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_Convert.cs b/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_Convert.cs index 5e2653c27b..de71f3332d 100644 --- a/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_Convert.cs +++ b/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_Convert.cs @@ -60,7 +60,7 @@ public IEnumerable GetTypeConversionPairs() private Dictionary> CreateTestItemsByType() { - var referenceCounter = new ReferenceCounterV2(); + var referenceCounter = new ReferenceCounter(); var result = new Dictionary>(); foreach (StackItemType type in Enum.GetValues(typeof(StackItemType))) @@ -84,22 +84,22 @@ private Dictionary> CreateTestItemsByType() result[StackItemType.Buffer].Add(new Buffer(new byte[128])); // Another 128-byte buffer, all zeros // Create an array with 10 items - var longArray = new Array(); + var longArray = new Array(referenceCounter); for (int i = 0; i < 10; i++) longArray.Add(new Integer(i)); result[StackItemType.Array].Add(longArray); - result[StackItemType.Array].Add(new Array() { StackItem.True, new ByteString(new byte[] { 3, 4, 5 }) }); + result[StackItemType.Array].Add(new Array(referenceCounter) { StackItem.True, new ByteString(new byte[] { 3, 4, 5 }) }); // Create a struct with 10 items - var longStruct = new Struct(); + var longStruct = new Struct(referenceCounter); for (int i = 0; i < 10; i++) longStruct.Add(new Integer(i * 10)); result[StackItemType.Struct].Add(longStruct); - result[StackItemType.Struct].Add(new Struct() { StackItem.False, new Buffer(new byte[] { 6, 7, 8 }) }); + result[StackItemType.Struct].Add(new Struct(referenceCounter) { StackItem.False, new Buffer(new byte[] { 6, 7, 8 }) }); // Create a map with 10 items - var longMap = new Map(); + var longMap = new Map(referenceCounter); for (int i = 0; i < 10; i++) longMap[new Integer(i)] = new ByteString(new byte[] { (byte)(i * 20) }); result[StackItemType.Map].Add(longMap); - result[StackItemType.Map].Add(new Map() { [new ByteString(new byte[] { 9 })] = StackItem.True }); + result[StackItemType.Map].Add(new Map(referenceCounter) { [new ByteString(new byte[] { 9 })] = StackItem.True }); result[StackItemType.InteropInterface].Add(new InteropInterface(new object())); result[StackItemType.InteropInterface].Add(new InteropInterface("test string")); diff --git a/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopy.cs b/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopy.cs index 89c2732c73..4cef2e555f 100644 --- a/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopy.cs +++ b/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopy.cs @@ -39,7 +39,7 @@ public class Benchmarks_DeepCopy [Benchmark] public void BenchNestedArrayDeepCopy() { - var root = new Array(); + var root = new Array(new ReferenceCounter()); CreateNestedArray(root, Params.Depth, Params.ElementsPerLevel); _ = root.DeepCopy(); } @@ -47,16 +47,16 @@ public void BenchNestedArrayDeepCopy() [Benchmark] public void BenchNestedArrayDeepCopyWithReferenceCounter() { - var referenceCounter = new ReferenceCounterV2(); - var root = new Array(); - CreateNestedArray(root, Params.Depth, Params.ElementsPerLevel); + var referenceCounter = new ReferenceCounter(); + var root = new Array(referenceCounter); + CreateNestedArray(root, Params.Depth, Params.ElementsPerLevel, referenceCounter); _ = root.DeepCopy(); } [Benchmark] public void BenchNestedTestArrayDeepCopy() { - var root = new TestArray(); + var root = new TestArray(new ReferenceCounter()); CreateNestedTestArray(root, Params.Depth, Params.ElementsPerLevel); _ = root.DeepCopy(); } @@ -64,13 +64,13 @@ public void BenchNestedTestArrayDeepCopy() [Benchmark] public void BenchNestedTestArrayDeepCopyWithReferenceCounter() { - var referenceCounter = new ReferenceCounterV2(); - var root = new TestArray(); - CreateNestedTestArray(root, Params.Depth, Params.ElementsPerLevel); + var referenceCounter = new ReferenceCounter(); + var root = new TestArray(referenceCounter); + CreateNestedTestArray(root, Params.Depth, Params.ElementsPerLevel, referenceCounter); _ = root.DeepCopy(); } - private static void CreateNestedArray(Array? rootArray, int depth, int elementsPerLevel = 1) + private static void CreateNestedArray(Array? rootArray, int depth, int elementsPerLevel = 1, IReferenceCounter? referenceCounter = null) { if (depth < 0) { @@ -89,13 +89,13 @@ private static void CreateNestedArray(Array? rootArray, int depth, int elementsP for (var i = 0; i < elementsPerLevel; i++) { - var childArray = new Array(); + var childArray = new Array(referenceCounter); rootArray.Add(childArray); - CreateNestedArray(childArray, depth - 1, elementsPerLevel); + CreateNestedArray(childArray, depth - 1, elementsPerLevel, referenceCounter); } } - private static void CreateNestedTestArray(TestArray rootArray, int depth, int elementsPerLevel = 1) + private static void CreateNestedTestArray(TestArray rootArray, int depth, int elementsPerLevel = 1, IReferenceCounter? referenceCounter = null) { if (depth < 0) { @@ -114,9 +114,9 @@ private static void CreateNestedTestArray(TestArray rootArray, int depth, int el for (var i = 0; i < elementsPerLevel; i++) { - var childArray = new TestArray(); + var childArray = new TestArray(referenceCounter); rootArray.Add(childArray); - CreateNestedTestArray(childArray, depth - 1, elementsPerLevel); + CreateNestedTestArray(childArray, depth - 1, elementsPerLevel, referenceCounter); } } } diff --git a/src/Neo.VM/ExecutionEngine.cs b/src/Neo.VM/ExecutionEngine.cs index bd04826d4d..8a3167b4c8 100644 --- a/src/Neo.VM/ExecutionEngine.cs +++ b/src/Neo.VM/ExecutionEngine.cs @@ -84,7 +84,7 @@ protected internal set /// Initializes a new instance of the class. /// /// The jump table to be used. - public ExecutionEngine(JumpTable? jumpTable = null) : this(jumpTable, new ReferenceCounterV2(), ExecutionEngineLimits.Default) + public ExecutionEngine(JumpTable? jumpTable = null) : this(jumpTable, new ReferenceCounter(), ExecutionEngineLimits.Default) { } @@ -289,7 +289,8 @@ public T Pop() where T : StackItem /// protected virtual void PostExecuteInstruction(Instruction instruction) { - if (ReferenceCounter.Count > Limits.MaxStackSize) + if (ReferenceCounter.Count < Limits.MaxStackSize) return; + if (ReferenceCounter.CheckZeroReferred() > Limits.MaxStackSize) throw new InvalidOperationException($"MaxStackSize exceed: {ReferenceCounter.Count}"); } diff --git a/src/Neo.VM/JumpTable/JumpTable.Compound.cs b/src/Neo.VM/JumpTable/JumpTable.Compound.cs index ce5e314385..2447edfa35 100644 --- a/src/Neo.VM/JumpTable/JumpTable.Compound.cs +++ b/src/Neo.VM/JumpTable/JumpTable.Compound.cs @@ -37,7 +37,7 @@ public virtual void PackMap(ExecutionEngine engine, Instruction instruction) var size = (int)engine.Pop().GetInteger(); if (size < 0 || size * 2 > engine.CurrentContext!.EvaluationStack.Count) throw new InvalidOperationException($"The value {size} is out of range."); - Map map = new(); + Map map = new(engine.ReferenceCounter); for (var i = 0; i < size; i++) { var key = engine.Pop(); @@ -60,7 +60,7 @@ public virtual void PackStruct(ExecutionEngine engine, Instruction instruction) var size = (int)engine.Pop().GetInteger(); if (size < 0 || size > engine.CurrentContext!.EvaluationStack.Count) throw new InvalidOperationException($"The value {size} is out of range."); - Struct @struct = new(); + Struct @struct = new(engine.ReferenceCounter); for (var i = 0; i < size; i++) { var item = engine.Pop(); @@ -82,7 +82,7 @@ public virtual void Pack(ExecutionEngine engine, Instruction instruction) var size = (int)engine.Pop().GetInteger(); if (size < 0 || size > engine.CurrentContext!.EvaluationStack.Count) throw new InvalidOperationException($"The value {size} is out of range."); - VMArray array = new(); + VMArray array = new(engine.ReferenceCounter); for (var i = 0; i < size; i++) { var item = engine.Pop(); @@ -136,7 +136,7 @@ public virtual void Unpack(ExecutionEngine engine, Instruction instruction) [MethodImpl(MethodImplOptions.AggressiveInlining)] public virtual void NewArray0(ExecutionEngine engine, Instruction instruction) { - engine.Push(new VMArray()); + engine.Push(new VMArray(engine.ReferenceCounter)); } /// @@ -154,7 +154,7 @@ public virtual void NewArray(ExecutionEngine engine, Instruction instruction) throw new InvalidOperationException($"MaxStackSize exceed: {n}"); var nullArray = new StackItem[n]; Array.Fill(nullArray, StackItem.Null); - engine.Push(new VMArray(nullArray)); + engine.Push(new VMArray(engine.ReferenceCounter, nullArray)); } /// @@ -184,7 +184,7 @@ public virtual void NewArray_T(ExecutionEngine engine, Instruction instruction) }; var itemArray = new StackItem[n]; Array.Fill(itemArray, item); - engine.Push(new VMArray(itemArray)); + engine.Push(new VMArray(engine.ReferenceCounter, itemArray)); } /// @@ -197,7 +197,7 @@ public virtual void NewArray_T(ExecutionEngine engine, Instruction instruction) [MethodImpl(MethodImplOptions.AggressiveInlining)] public virtual void NewStruct0(ExecutionEngine engine, Instruction instruction) { - engine.Push(new Struct()); + engine.Push(new Struct(engine.ReferenceCounter)); } /// @@ -216,7 +216,7 @@ public virtual void NewStruct(ExecutionEngine engine, Instruction instruction) var nullArray = new StackItem[n]; Array.Fill(nullArray, StackItem.Null); - engine.Push(new Struct(nullArray)); + engine.Push(new Struct(engine.ReferenceCounter, nullArray)); } /// @@ -229,7 +229,7 @@ public virtual void NewStruct(ExecutionEngine engine, Instruction instruction) [MethodImpl(MethodImplOptions.AggressiveInlining)] public virtual void NewMap(ExecutionEngine engine, Instruction instruction) { - engine.Push(new Map()); + engine.Push(new Map(engine.ReferenceCounter)); } /// @@ -327,7 +327,7 @@ public virtual void HasKey(ExecutionEngine engine, Instruction instruction) public virtual void Keys(ExecutionEngine engine, Instruction instruction) { var map = engine.Pop(); - engine.Push(new VMArray(map.Keys)); + engine.Push(new VMArray(engine.ReferenceCounter, map.Keys)); } /// @@ -347,7 +347,7 @@ public virtual void Values(ExecutionEngine engine, Instruction instruction) Map map => map.Values, _ => throw new InvalidOperationException($"Invalid type for {instruction.OpCode}: {x.Type}"), }; - VMArray newArray = new(); + VMArray newArray = new(engine.ReferenceCounter); foreach (var item in values) if (item is Struct s) newArray.Add(s.Clone(engine.Limits)); @@ -422,7 +422,6 @@ public virtual void Append(ExecutionEngine engine, Instruction instruction) var array = engine.Pop(); if (newItem is Struct s) newItem = s.Clone(engine.Limits); array.Add(newItem); - engine.ReferenceCounter.AddStackReference(newItem); } /// @@ -446,23 +445,12 @@ public virtual void SetItem(ExecutionEngine engine, Instruction instruction) var index = (int)key.GetInteger(); if (index < 0 || index >= array.Count) throw new CatchableException($"The value {index} is out of range."); - engine.ReferenceCounter.RemoveStackReference(array[index]); array[index] = value; - engine.ReferenceCounter.AddStackReference(array[index]); break; } case Map map: { - if (!map.TryGetValue(key, out var value1)) - { - engine.ReferenceCounter.AddStackReference(key); - } - else - { - engine.ReferenceCounter.RemoveStackReference(value1); - } map[key] = value; - engine.ReferenceCounter.AddStackReference(value); break; } case Types.Buffer buffer: @@ -527,13 +515,9 @@ public virtual void Remove(ExecutionEngine engine, Instruction instruction) var index = (int)key.GetInteger(); if (index < 0 || index >= array.Count) throw new InvalidOperationException($"The value {index} is out of range."); - var item = array[index]; array.RemoveAt(index); - engine.ReferenceCounter.RemoveStackReference(item); break; case Map map: - engine.ReferenceCounter.RemoveStackReference(key); - engine.ReferenceCounter.RemoveStackReference(map[key]); map.Remove(key); break; default: @@ -552,10 +536,6 @@ public virtual void Remove(ExecutionEngine engine, Instruction instruction) public virtual void ClearItems(ExecutionEngine engine, Instruction instruction) { var x = engine.Pop(); - foreach (var xSubItem in x.SubItems) - { - engine.ReferenceCounter.RemoveStackReference(xSubItem); - } x.Clear(); } diff --git a/src/Neo.VM/Types/Array.cs b/src/Neo.VM/Types/Array.cs index 0c3ed2c9ff..903613c228 100644 --- a/src/Neo.VM/Types/Array.cs +++ b/src/Neo.VM/Types/Array.cs @@ -33,7 +33,14 @@ public StackItem this[int index] set { if (IsReadOnly) throw new InvalidOperationException("The object is readonly."); + ReferenceCounter?.RemoveReference(_array[index], this); _array[index] = value; + if (ReferenceCounter != null && value is CompoundType { ReferenceCounter: null }) + { + throw new InvalidOperationException("Can not set a CompoundType without a ReferenceCounter."); + } + + ReferenceCounter?.AddReference(value, this); } } @@ -68,6 +75,18 @@ public Array(IReferenceCounter? referenceCounter, IEnumerable? items List list => list, _ => new List(items) }; + + if (referenceCounter == null) return; + + foreach (var item in _array) + { + if (item is CompoundType { ReferenceCounter: null }) + { + throw new InvalidOperationException("Can not set a CompoundType without a ReferenceCounter."); + } + + referenceCounter.AddReference(item, this); + } } /// @@ -78,25 +97,36 @@ public void Add(StackItem item) { if (IsReadOnly) throw new InvalidOperationException("The object is readonly."); _array.Add(item); + + if (ReferenceCounter == null) return; + + if (item is CompoundType { ReferenceCounter: null }) + { + throw new InvalidOperationException("Can not set a CompoundType without a ReferenceCounter."); + } + ReferenceCounter.AddReference(item, this); } public override void Clear() { if (IsReadOnly) throw new InvalidOperationException("The object is readonly."); + if (ReferenceCounter != null) + foreach (StackItem item in _array) + ReferenceCounter.RemoveReference(item, this); _array.Clear(); } public override StackItem ConvertTo(StackItemType type) { if (Type == StackItemType.Array && type == StackItemType.Struct) - return new Struct(new List(_array)); + return new Struct(ReferenceCounter, new List(_array)); return base.ConvertTo(type); } internal sealed override StackItem DeepCopy(Dictionary refMap, bool asImmutable) { if (refMap.TryGetValue(this, out StackItem? mappedItem)) return mappedItem; - Array result = this is Struct ? new Struct() : new Array(); + Array result = this is Struct ? new Struct(ReferenceCounter) : new Array(ReferenceCounter); refMap.Add(this, result); foreach (StackItem item in _array) result.Add(item.DeepCopy(refMap, asImmutable)); @@ -121,6 +151,7 @@ public IEnumerator GetEnumerator() public void RemoveAt(int index) { if (IsReadOnly) throw new InvalidOperationException("The object is readonly."); + ReferenceCounter?.RemoveReference(_array[index], this); _array.RemoveAt(index); } diff --git a/src/Neo.VM/Types/CompoundType.cs b/src/Neo.VM/Types/CompoundType.cs index 0fc15568c8..59a30fcb42 100644 --- a/src/Neo.VM/Types/CompoundType.cs +++ b/src/Neo.VM/Types/CompoundType.cs @@ -32,6 +32,8 @@ public abstract class CompoundType : StackItem /// The reference counter to be used. protected CompoundType(IReferenceCounter? referenceCounter = null) { + ReferenceCounter = referenceCounter; + referenceCounter?.AddZeroReferred(this); } /// diff --git a/src/Neo.VM/Types/Map.cs b/src/Neo.VM/Types/Map.cs index c7153b79cb..2986399d59 100644 --- a/src/Neo.VM/Types/Map.cs +++ b/src/Neo.VM/Types/Map.cs @@ -48,6 +48,18 @@ public StackItem this[PrimitiveType key] if (key.Size > MaxKeySize) throw new ArgumentException($"MaxKeySize exceed: {key.Size}"); if (IsReadOnly) throw new InvalidOperationException("The object is readonly."); + if (ReferenceCounter != null) + { + if (dictionary.TryGetValue(key, out StackItem? old_value)) + ReferenceCounter.RemoveReference(old_value, this); + else + ReferenceCounter.AddReference(key, this); + if (value is CompoundType { ReferenceCounter: null }) + { + throw new InvalidOperationException("Can not set a Map without a ReferenceCounter."); + } + ReferenceCounter.AddReference(value, this); + } dictionary[key] = value; } } @@ -82,6 +94,12 @@ public Map(IReferenceCounter? referenceCounter = null) public override void Clear() { if (IsReadOnly) throw new InvalidOperationException("The object is readonly."); + if (ReferenceCounter != null) + foreach (var pair in dictionary) + { + ReferenceCounter.RemoveReference(pair.Key, this); + ReferenceCounter.RemoveReference(pair.Value, this); + } dictionary.Clear(); } @@ -103,7 +121,7 @@ public bool ContainsKey(PrimitiveType key) internal override StackItem DeepCopy(Dictionary refMap, bool asImmutable) { if (refMap.TryGetValue(this, out StackItem? mappedItem)) return mappedItem; - Map result = new(); + Map result = new(ReferenceCounter); refMap.Add(this, result); foreach (var (k, v) in dictionary) result[k] = v.DeepCopy(refMap, asImmutable); @@ -137,6 +155,8 @@ public bool Remove(PrimitiveType key) if (IsReadOnly) throw new InvalidOperationException("The object is readonly."); if (!dictionary.Remove(key, out StackItem? old_value)) return false; + ReferenceCounter?.RemoveReference(key, this); + ReferenceCounter?.RemoveReference(old_value, this); return true; } diff --git a/src/Neo.VM/Types/Struct.cs b/src/Neo.VM/Types/Struct.cs index c8406687e3..344147b5ed 100644 --- a/src/Neo.VM/Types/Struct.cs +++ b/src/Neo.VM/Types/Struct.cs @@ -48,7 +48,7 @@ public Struct(IReferenceCounter? referenceCounter, IEnumerable? field public Struct Clone(ExecutionEngineLimits limits) { int count = (int)(limits.MaxStackSize - 1); - Struct result = new(); + Struct result = new(ReferenceCounter); Queue queue = new(); queue.Enqueue(result); queue.Enqueue(this); @@ -62,7 +62,7 @@ public Struct Clone(ExecutionEngineLimits limits) if (count < 0) throw new InvalidOperationException("Beyond clone limits!"); if (item is Struct sb) { - Struct sa = new(); + Struct sa = new(ReferenceCounter); a.Add(sa); queue.Enqueue(sa); queue.Enqueue(sb); @@ -79,7 +79,7 @@ public Struct Clone(ExecutionEngineLimits limits) public override StackItem ConvertTo(StackItemType type) { if (type == StackItemType.Array) - return new Array(new List(_array)); + return new Array(ReferenceCounter, new List(_array)); return base.ConvertTo(type); } diff --git a/src/Neo/Network/P2P/Payloads/Conditions/AndCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/AndCondition.cs index 636d0869a9..975e2ec89d 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/AndCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/AndCondition.cs @@ -91,10 +91,10 @@ public override JObject ToJson() return json; } - public override StackItem ToStackItem(IReferenceCounter referenceCounter) + public override StackItem ToStackItem(IReferenceCounter referenceCounter = null) { var result = (VM.Types.Array)base.ToStackItem(referenceCounter); - result.Add(new VM.Types.Array(Expressions.Select(p => p.ToStackItem(referenceCounter)))); + result.Add(new VM.Types.Array(referenceCounter, Expressions.Select(p => p.ToStackItem(referenceCounter)))); return result; } diff --git a/src/Neo/Network/P2P/Payloads/Conditions/BooleanCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/BooleanCondition.cs index 4299bae04b..dcde0de28c 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/BooleanCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/BooleanCondition.cs @@ -80,7 +80,7 @@ public override JObject ToJson() return json; } - public override StackItem ToStackItem(IReferenceCounter referenceCounter) + public override StackItem ToStackItem(IReferenceCounter referenceCounter = null) { var result = (VM.Types.Array)base.ToStackItem(referenceCounter); result.Add(Expression); diff --git a/src/Neo/Network/P2P/Payloads/Conditions/CalledByContractCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/CalledByContractCondition.cs index 4ce1e2dc1f..08a26903f7 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/CalledByContractCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/CalledByContractCondition.cs @@ -80,7 +80,7 @@ public override JObject ToJson() return json; } - public override StackItem ToStackItem(IReferenceCounter referenceCounter) + public override StackItem ToStackItem(IReferenceCounter referenceCounter = null) { var result = (VM.Types.Array)base.ToStackItem(referenceCounter); result.Add(Hash.ToArray()); diff --git a/src/Neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs index ac233a156a..623fdc2e55 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs @@ -85,7 +85,7 @@ public override JObject ToJson() return json; } - public override StackItem ToStackItem(IReferenceCounter referenceCounter) + public override StackItem ToStackItem(IReferenceCounter referenceCounter = null) { var result = (VM.Types.Array)base.ToStackItem(referenceCounter); result.Add(Group.ToArray()); diff --git a/src/Neo/Network/P2P/Payloads/Conditions/GroupCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/GroupCondition.cs index 18e94fbc40..a9c3885c69 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/GroupCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/GroupCondition.cs @@ -85,7 +85,7 @@ public override JObject ToJson() return json; } - public override StackItem ToStackItem(IReferenceCounter referenceCounter) + public override StackItem ToStackItem(IReferenceCounter referenceCounter = null) { var result = (VM.Types.Array)base.ToStackItem(referenceCounter); result.Add(Group.ToArray()); diff --git a/src/Neo/Network/P2P/Payloads/Conditions/NotCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/NotCondition.cs index fd813c7230..0db660dadd 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/NotCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/NotCondition.cs @@ -85,7 +85,7 @@ public override JObject ToJson() return json; } - public override StackItem ToStackItem(IReferenceCounter referenceCounter) + public override StackItem ToStackItem(IReferenceCounter referenceCounter = null) { var result = (VM.Types.Array)base.ToStackItem(referenceCounter); result.Add(Expression.ToStackItem(referenceCounter)); diff --git a/src/Neo/Network/P2P/Payloads/Conditions/OrCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/OrCondition.cs index 9bee1916f6..624b5eac75 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/OrCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/OrCondition.cs @@ -91,10 +91,10 @@ public override JObject ToJson() return json; } - public override StackItem ToStackItem(IReferenceCounter referenceCounter) + public override StackItem ToStackItem(IReferenceCounter referenceCounter = null) { var result = (VM.Types.Array)base.ToStackItem(referenceCounter); - result.Add(new VM.Types.Array(Expressions.Select(p => p.ToStackItem(referenceCounter)))); + result.Add(new VM.Types.Array(referenceCounter, Expressions.Select(p => p.ToStackItem(referenceCounter)))); return result; } diff --git a/src/Neo/Network/P2P/Payloads/Conditions/ScriptHashCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/ScriptHashCondition.cs index a9cf1de0e9..dc06fb64a6 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/ScriptHashCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/ScriptHashCondition.cs @@ -80,7 +80,7 @@ public override JObject ToJson() return json; } - public override StackItem ToStackItem(IReferenceCounter referenceCounter) + public override StackItem ToStackItem(IReferenceCounter referenceCounter = null) { var result = (VM.Types.Array)base.ToStackItem(referenceCounter); result.Add(Hash.ToArray()); diff --git a/src/Neo/Network/P2P/Payloads/Conditions/WitnessCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/WitnessCondition.cs index b939749afd..05dcc8be03 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/WitnessCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/WitnessCondition.cs @@ -132,9 +132,9 @@ void IInteroperable.FromStackItem(StackItem stackItem) throw new NotSupportedException(); } - public virtual StackItem ToStackItem(IReferenceCounter referenceCounter) + public virtual StackItem ToStackItem(IReferenceCounter referenceCounter = null) { - return new VM.Types.Array(new StackItem[] { (byte)Type }); + return new VM.Types.Array(referenceCounter, new StackItem[] { (byte)Type }); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/Neo/Network/P2P/Payloads/Signer.cs b/src/Neo/Network/P2P/Payloads/Signer.cs index 6096af0f5f..ed87de9162 100644 --- a/src/Neo/Network/P2P/Payloads/Signer.cs +++ b/src/Neo/Network/P2P/Payloads/Signer.cs @@ -191,15 +191,15 @@ void IInteroperable.FromStackItem(VM.Types.StackItem stackItem) throw new NotSupportedException(); } - VM.Types.StackItem IInteroperable.ToStackItem(IReferenceCounter referenceCounter) + VM.Types.StackItem IInteroperable.ToStackItem(IReferenceCounter referenceCounter = null) { - return new VM.Types.Array( + return new VM.Types.Array(referenceCounter, [ Account.ToArray(), (byte)Scopes, - Scopes.HasFlag(WitnessScope.CustomContracts) ? new VM.Types.Array(AllowedContracts.Select(u => new VM.Types.ByteString(u.ToArray()))) : new VM.Types.Array(), - Scopes.HasFlag(WitnessScope.CustomGroups) ? new VM.Types.Array(AllowedGroups.Select(u => new VM.Types.ByteString(u.ToArray()))) : new VM.Types.Array(), - Scopes.HasFlag(WitnessScope.WitnessRules) ? new VM.Types.Array(Rules.Select(u => u.ToStackItem(referenceCounter))) : new VM.Types.Array() + Scopes.HasFlag(WitnessScope.CustomContracts) ? new VM.Types.Array(referenceCounter, AllowedContracts.Select(u => new VM.Types.ByteString(u.ToArray()))) : new VM.Types.Array(referenceCounter), + Scopes.HasFlag(WitnessScope.CustomGroups) ? new VM.Types.Array(referenceCounter, AllowedGroups.Select(u => new VM.Types.ByteString(u.ToArray()))) : new VM.Types.Array(referenceCounter), + Scopes.HasFlag(WitnessScope.WitnessRules) ? new VM.Types.Array(referenceCounter, Rules.Select(u => u.ToStackItem(referenceCounter))) : new VM.Types.Array(referenceCounter) ]); } } diff --git a/src/Neo/Network/P2P/Payloads/Transaction.cs b/src/Neo/Network/P2P/Payloads/Transaction.cs index 632a9d6b72..310ceb7c9d 100644 --- a/src/Neo/Network/P2P/Payloads/Transaction.cs +++ b/src/Neo/Network/P2P/Payloads/Transaction.cs @@ -459,10 +459,10 @@ public virtual VerifyResult VerifyStateIndependent(ProtocolSettings settings) return VerifyResult.Succeed; } - public StackItem ToStackItem(IReferenceCounter referenceCounter) + public StackItem ToStackItem(IReferenceCounter referenceCounter = null) { if (_signers == null || _signers.Length == 0) throw new ArgumentException("Sender is not specified in the transaction."); - return new Array(new StackItem[] + return new Array(referenceCounter, new StackItem[] { // Computed properties Hash.ToArray(), diff --git a/src/Neo/Network/P2P/Payloads/WitnessRule.cs b/src/Neo/Network/P2P/Payloads/WitnessRule.cs index c0ec8ac3dc..473d6d64ee 100644 --- a/src/Neo/Network/P2P/Payloads/WitnessRule.cs +++ b/src/Neo/Network/P2P/Payloads/WitnessRule.cs @@ -110,9 +110,9 @@ void IInteroperable.FromStackItem(StackItem stackItem) throw new NotSupportedException(); } - public StackItem ToStackItem(IReferenceCounter referenceCounter) + public StackItem ToStackItem(IReferenceCounter referenceCounter = null) { - return new VM.Types.Array(new StackItem[] + return new VM.Types.Array(referenceCounter, new StackItem[] { (byte)Action, Condition.ToStackItem(referenceCounter) diff --git a/src/Neo/SmartContract/ApplicationEngine.Runtime.cs b/src/Neo/SmartContract/ApplicationEngine.Runtime.cs index e880068572..3771278839 100644 --- a/src/Neo/SmartContract/ApplicationEngine.Runtime.cs +++ b/src/Neo/SmartContract/ApplicationEngine.Runtime.cs @@ -414,7 +414,7 @@ protected internal Array GetNotifications(UInt160 hash) notifications = notifications.Where(p => p.ScriptHash == hash); var array = notifications.ToArray(); if (array.Length > Limits.MaxStackSize) throw new InvalidOperationException(); - Array notifyArray = new(); + Array notifyArray = new(ReferenceCounter); foreach (var notify in array) { notifyArray.Add(notify.ToStackItem(ReferenceCounter, this)); diff --git a/src/Neo/SmartContract/ApplicationEngine.cs b/src/Neo/SmartContract/ApplicationEngine.cs index 54a0465069..7808baae5e 100644 --- a/src/Neo/SmartContract/ApplicationEngine.cs +++ b/src/Neo/SmartContract/ApplicationEngine.cs @@ -502,8 +502,8 @@ protected internal StackItem Convert(object value) IInteroperable interoperable => interoperable.ToStackItem(ReferenceCounter), ISerializable i => i.ToArray(), StackItem item => item, - (object a, object b) => new Struct() { Convert(a), Convert(b) }, - Array array => new VMArray(array.OfType().Select(p => Convert(p))), + (object a, object b) => new Struct(ReferenceCounter) { Convert(a), Convert(b) }, + Array array => new VMArray(ReferenceCounter, array.OfType().Select(p => Convert(p))), _ => StackItem.FromInterface(value) }; } diff --git a/src/Neo/SmartContract/BinarySerializer.cs b/src/Neo/SmartContract/BinarySerializer.cs index 39a9404933..b77a998d6e 100644 --- a/src/Neo/SmartContract/BinarySerializer.cs +++ b/src/Neo/SmartContract/BinarySerializer.cs @@ -134,19 +134,19 @@ public static StackItem Deserialize(ref MemoryReader reader, uint maxSize, uint switch (placeholder.Type) { case StackItemType.Array: - Array array = new(); + Array array = new(referenceCounter); for (int i = 0; i < placeholder.ElementCount; i++) array.Add(stack_temp.Pop()); item = array; break; case StackItemType.Struct: - Struct @struct = new(); + Struct @struct = new(referenceCounter); for (int i = 0; i < placeholder.ElementCount; i++) @struct.Add(stack_temp.Pop()); item = @struct; break; case StackItemType.Map: - Map map = new(); + Map map = new(referenceCounter); for (int i = 0; i < placeholder.ElementCount; i++) { StackItem key = stack_temp.Pop(); diff --git a/src/Neo/SmartContract/ContractState.cs b/src/Neo/SmartContract/ContractState.cs index 90846b0c92..c19e7a0fdc 100644 --- a/src/Neo/SmartContract/ContractState.cs +++ b/src/Neo/SmartContract/ContractState.cs @@ -119,9 +119,9 @@ public JObject ToJson() }; } - public StackItem ToStackItem(IReferenceCounter referenceCounter) + public StackItem ToStackItem(IReferenceCounter referenceCounter = null) { - return new Array(new StackItem[] { Id, (int)UpdateCounter, Hash.ToArray(), Nef.ToArray(), Manifest.ToStackItem(referenceCounter) }); + return new Array(referenceCounter, new StackItem[] { Id, (int)UpdateCounter, Hash.ToArray(), Nef.ToArray(), Manifest.ToStackItem(referenceCounter) }); } } } diff --git a/src/Neo/SmartContract/IInteroperable.cs b/src/Neo/SmartContract/IInteroperable.cs index f177b3f76f..a3c3e273ae 100644 --- a/src/Neo/SmartContract/IInteroperable.cs +++ b/src/Neo/SmartContract/IInteroperable.cs @@ -31,7 +31,7 @@ public interface IInteroperable /// /// The used by the . /// The converted . - StackItem ToStackItem(IReferenceCounter referenceCounter); + StackItem ToStackItem(IReferenceCounter referenceCounter = null); public IInteroperable Clone() { diff --git a/src/Neo/SmartContract/Iterators/StorageIterator.cs b/src/Neo/SmartContract/Iterators/StorageIterator.cs index 44d23a5be5..b66998c9dc 100644 --- a/src/Neo/SmartContract/Iterators/StorageIterator.cs +++ b/src/Neo/SmartContract/Iterators/StorageIterator.cs @@ -60,7 +60,7 @@ public StackItem Value(IReferenceCounter referenceCounter) return key; if (options.HasFlag(FindOptions.ValuesOnly)) return item; - return new Struct() { key, item }; + return new Struct(referenceCounter) { key, item }; } } } diff --git a/src/Neo/SmartContract/JsonSerializer.cs b/src/Neo/SmartContract/JsonSerializer.cs index e30e73a034..d2055be7d8 100644 --- a/src/Neo/SmartContract/JsonSerializer.cs +++ b/src/Neo/SmartContract/JsonSerializer.cs @@ -185,7 +185,7 @@ private static StackItem Deserialize(ApplicationEngine engine, JToken json, ref List list = new(array.Count); foreach (JToken obj in array) list.Add(Deserialize(engine, obj, ref maxStackSize, referenceCounter)); - return new Array(list); + return new Array(referenceCounter, list); } case JString str: { @@ -206,7 +206,7 @@ private static StackItem Deserialize(ApplicationEngine engine, JToken json, ref } case JObject obj: { - var item = new Map(); + var item = new Map(referenceCounter); foreach (var entry in obj.Properties) { diff --git a/src/Neo/SmartContract/Manifest/ContractAbi.cs b/src/Neo/SmartContract/Manifest/ContractAbi.cs index d67b98baea..ecbf9d9b41 100644 --- a/src/Neo/SmartContract/Manifest/ContractAbi.cs +++ b/src/Neo/SmartContract/Manifest/ContractAbi.cs @@ -44,12 +44,12 @@ void IInteroperable.FromStackItem(StackItem stackItem) Events = ((Array)@struct[1]).Select(p => p.ToInteroperable()).ToArray(); } - public StackItem ToStackItem(IReferenceCounter referenceCounter) + public StackItem ToStackItem(IReferenceCounter referenceCounter = null) { - return new Struct() + return new Struct(referenceCounter) { - new Array( Methods.Select(p => p.ToStackItem(referenceCounter))), - new Array( Events.Select(p => p.ToStackItem(referenceCounter))), + new Array(referenceCounter, Methods.Select(p => p.ToStackItem(referenceCounter))), + new Array(referenceCounter, Events.Select(p => p.ToStackItem(referenceCounter))), }; } diff --git a/src/Neo/SmartContract/Manifest/ContractEventDescriptor.cs b/src/Neo/SmartContract/Manifest/ContractEventDescriptor.cs index 9820f0e4f5..bbf60e86d2 100644 --- a/src/Neo/SmartContract/Manifest/ContractEventDescriptor.cs +++ b/src/Neo/SmartContract/Manifest/ContractEventDescriptor.cs @@ -41,12 +41,12 @@ public virtual void FromStackItem(StackItem stackItem) Parameters = ((Array)@struct[1]).Select(p => p.ToInteroperable()).ToArray(); } - public virtual StackItem ToStackItem(IReferenceCounter referenceCounter) + public virtual StackItem ToStackItem(IReferenceCounter referenceCounter = null) { - return new Struct() + return new Struct(referenceCounter) { Name, - new Array(Parameters.Select(p => p.ToStackItem(referenceCounter))) + new Array(referenceCounter, Parameters.Select(p => p.ToStackItem(referenceCounter))) }; } diff --git a/src/Neo/SmartContract/Manifest/ContractGroup.cs b/src/Neo/SmartContract/Manifest/ContractGroup.cs index 2ed3540d39..c7f378b032 100644 --- a/src/Neo/SmartContract/Manifest/ContractGroup.cs +++ b/src/Neo/SmartContract/Manifest/ContractGroup.cs @@ -43,9 +43,9 @@ void IInteroperable.FromStackItem(StackItem stackItem) Signature = @struct[1].GetSpan().ToArray(); } - public StackItem ToStackItem(IReferenceCounter referenceCounter) + public StackItem ToStackItem(IReferenceCounter referenceCounter = null) { - return new Struct() { PubKey.ToArray(), Signature }; + return new Struct(referenceCounter) { PubKey.ToArray(), Signature }; } /// diff --git a/src/Neo/SmartContract/Manifest/ContractManifest.cs b/src/Neo/SmartContract/Manifest/ContractManifest.cs index 6e048673ac..d48b95ee36 100644 --- a/src/Neo/SmartContract/Manifest/ContractManifest.cs +++ b/src/Neo/SmartContract/Manifest/ContractManifest.cs @@ -88,17 +88,17 @@ void IInteroperable.FromStackItem(StackItem stackItem) Extra = (JObject)JToken.Parse(@struct[7].GetSpan()); } - public StackItem ToStackItem(IReferenceCounter referenceCounter) + public StackItem ToStackItem(IReferenceCounter referenceCounter = null) { - return new Struct() + return new Struct(referenceCounter) { Name, - new Array(Groups.Select(p => p.ToStackItem(referenceCounter))), - new Map(), - new Array(SupportedStandards.Select(p => (StackItem)p)), + new Array(referenceCounter, Groups.Select(p => p.ToStackItem(referenceCounter))), + new Map(referenceCounter), + new Array(referenceCounter, SupportedStandards.Select(p => (StackItem)p)), Abi.ToStackItem(referenceCounter), - new Array(Permissions.Select(p => p.ToStackItem(referenceCounter))), - Trusts.IsWildcard ? StackItem.Null : new Array(Trusts.Select(p => p.ToArray()?? StackItem.Null)), + new Array(referenceCounter, Permissions.Select(p => p.ToStackItem(referenceCounter))), + Trusts.IsWildcard ? StackItem.Null : new Array(referenceCounter, Trusts.Select(p => p.ToArray()?? StackItem.Null)), Extra is null ? "null" : Extra.ToByteArray(false) }; } diff --git a/src/Neo/SmartContract/Manifest/ContractMethodDescriptor.cs b/src/Neo/SmartContract/Manifest/ContractMethodDescriptor.cs index 6c024dc179..b6b320fc84 100644 --- a/src/Neo/SmartContract/Manifest/ContractMethodDescriptor.cs +++ b/src/Neo/SmartContract/Manifest/ContractMethodDescriptor.cs @@ -48,7 +48,7 @@ public override void FromStackItem(StackItem stackItem) Safe = @struct[4].GetBoolean(); } - public override StackItem ToStackItem(IReferenceCounter referenceCounter) + public override StackItem ToStackItem(IReferenceCounter referenceCounter = null) { Struct @struct = (Struct)base.ToStackItem(referenceCounter); @struct.Add((byte)ReturnType); diff --git a/src/Neo/SmartContract/Manifest/ContractParameterDefinition.cs b/src/Neo/SmartContract/Manifest/ContractParameterDefinition.cs index 16a4d8b9f1..217f695cb2 100644 --- a/src/Neo/SmartContract/Manifest/ContractParameterDefinition.cs +++ b/src/Neo/SmartContract/Manifest/ContractParameterDefinition.cs @@ -39,9 +39,9 @@ void IInteroperable.FromStackItem(StackItem stackItem) Type = (ContractParameterType)(byte)@struct[1].GetInteger(); } - public StackItem ToStackItem(IReferenceCounter referenceCounter) + public StackItem ToStackItem(IReferenceCounter referenceCounter = null) { - return new Struct() { Name, (byte)Type }; + return new Struct(referenceCounter) { Name, (byte)Type }; } /// diff --git a/src/Neo/SmartContract/Manifest/ContractPermission.cs b/src/Neo/SmartContract/Manifest/ContractPermission.cs index 33462989b3..23362729f9 100644 --- a/src/Neo/SmartContract/Manifest/ContractPermission.cs +++ b/src/Neo/SmartContract/Manifest/ContractPermission.cs @@ -68,12 +68,12 @@ void IInteroperable.FromStackItem(StackItem stackItem) }; } - public StackItem ToStackItem(IReferenceCounter referenceCounter) + public StackItem ToStackItem(IReferenceCounter referenceCounter = null) { - return new Struct() + return new Struct(referenceCounter) { Contract.IsWildcard ? StackItem.Null : Contract.IsHash ? Contract.Hash.ToArray() : Contract.Group.ToArray(), - Methods.IsWildcard ? StackItem.Null : new Array(Methods.Select(p => (StackItem)p)), + Methods.IsWildcard ? StackItem.Null : new Array(referenceCounter, Methods.Select(p => (StackItem)p)), }; } diff --git a/src/Neo/SmartContract/Native/AccountState.cs b/src/Neo/SmartContract/Native/AccountState.cs index 8c433612dd..312a7cf414 100644 --- a/src/Neo/SmartContract/Native/AccountState.cs +++ b/src/Neo/SmartContract/Native/AccountState.cs @@ -30,9 +30,9 @@ public virtual void FromStackItem(StackItem stackItem) Balance = ((Struct)stackItem)[0].GetInteger(); } - public virtual StackItem ToStackItem(IReferenceCounter referenceCounter) + public virtual StackItem ToStackItem(IReferenceCounter referenceCounter = null) { - return new Struct() { Balance }; + return new Struct(referenceCounter) { Balance }; } } } diff --git a/src/Neo/SmartContract/Native/ContractManagement.cs b/src/Neo/SmartContract/Native/ContractManagement.cs index 844002844f..6fefd2d05f 100644 --- a/src/Neo/SmartContract/Native/ContractManagement.cs +++ b/src/Neo/SmartContract/Native/ContractManagement.cs @@ -63,7 +63,7 @@ private async ContractTask OnDeployAsync(ApplicationEngine engine, ContractState ContractMethodDescriptor md = contract.Manifest.Abi.GetMethod(ContractBasicMethod.Deploy, ContractBasicMethod.DeployPCount); if (md is not null) await engine.CallFromNativeContractAsync(Hash, contract.Hash, md.Name, data, update); - engine.SendNotification(Hash, update ? "Update" : "Deploy", new VM.Types.Array() { contract.Hash.ToArray() }); + engine.SendNotification(Hash, update ? "Update" : "Deploy", new VM.Types.Array(engine.ReferenceCounter) { contract.Hash.ToArray() }); } internal override async ContractTask OnPersistAsync(ApplicationEngine engine) @@ -110,7 +110,7 @@ internal override async ContractTask OnPersistAsync(ApplicationEngine engine) } // Emit native contract notification - engine.SendNotification(Hash, state is null ? "Deploy" : "Update", new VM.Types.Array() { contract.Hash.ToArray() }); + engine.SendNotification(Hash, state is null ? "Deploy" : "Update", new VM.Types.Array(engine.ReferenceCounter) { contract.Hash.ToArray() }); } } } @@ -309,7 +309,7 @@ private void Destroy(ApplicationEngine engine) // lock contract Policy.BlockAccount(engine.SnapshotCache, hash); // emit event - engine.SendNotification(Hash, "Destroy", new VM.Types.Array() { hash.ToArray() }); + 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 d9db52fd75..21de0a5644 100644 --- a/src/Neo/SmartContract/Native/FungibleToken.cs +++ b/src/Neo/SmartContract/Native/FungibleToken.cs @@ -182,7 +182,7 @@ private protected virtual async ContractTask PostTransferAsync(ApplicationEngine // Send notification engine.SendNotification(Hash, "Transfer", - new Array() { from?.ToArray() ?? StackItem.Null, to?.ToArray() ?? StackItem.Null, amount }); + new Array(engine.ReferenceCounter) { from?.ToArray() ?? StackItem.Null, to?.ToArray() ?? StackItem.Null, amount }); // Check if it's a wallet or smart contract diff --git a/src/Neo/SmartContract/Native/HashIndexState.cs b/src/Neo/SmartContract/Native/HashIndexState.cs index d6752d5193..c008c4bf27 100644 --- a/src/Neo/SmartContract/Native/HashIndexState.cs +++ b/src/Neo/SmartContract/Native/HashIndexState.cs @@ -27,9 +27,9 @@ void IInteroperable.FromStackItem(StackItem stackItem) Index = (uint)@struct[1].GetInteger(); } - StackItem IInteroperable.ToStackItem(IReferenceCounter referenceCounter) + StackItem IInteroperable.ToStackItem(IReferenceCounter referenceCounter = null) { - return new Struct() { Hash.ToArray(), Index }; + return new Struct(referenceCounter) { Hash.ToArray(), Index }; } } } diff --git a/src/Neo/SmartContract/Native/InteroperableList.cs b/src/Neo/SmartContract/Native/InteroperableList.cs index 0eb9c50e44..269710eefa 100644 --- a/src/Neo/SmartContract/Native/InteroperableList.cs +++ b/src/Neo/SmartContract/Native/InteroperableList.cs @@ -51,9 +51,9 @@ public void FromStackItem(StackItem stackItem) } } - public StackItem ToStackItem(IReferenceCounter referenceCounter) + public StackItem ToStackItem(IReferenceCounter referenceCounter = null) { - return new Array(this.Select(p => ElementToStackItem(p, referenceCounter))); + return new Array(referenceCounter, this.Select(p => ElementToStackItem(p, referenceCounter))); } } } diff --git a/src/Neo/SmartContract/Native/NeoToken.cs b/src/Neo/SmartContract/Native/NeoToken.cs index fe42b550da..ef3f8d5d2d 100644 --- a/src/Neo/SmartContract/Native/NeoToken.cs +++ b/src/Neo/SmartContract/Native/NeoToken.cs @@ -216,9 +216,9 @@ internal override ContractTask OnPersistAsync(ApplicationEngine engine) if (!newCommittee.SequenceEqual(prevCommittee)) { - engine.SendNotification(Hash, "CommitteeChanged", new VM.Types.Array() { - new VM.Types.Array( prevCommittee.Select(u => (ByteString)u.ToArray())) , - new VM.Types.Array(newCommittee.Select(u => (ByteString)u.ToArray())) + engine.SendNotification(Hash, "CommitteeChanged", new VM.Types.Array(engine.ReferenceCounter) { + new VM.Types.Array(engine.ReferenceCounter, prevCommittee.Select(u => (ByteString)u.ToArray())) , + new VM.Types.Array(engine.ReferenceCounter, newCommittee.Select(u => (ByteString)u.ToArray())) }); } } @@ -340,7 +340,7 @@ private bool RegisterCandidate(ApplicationEngine engine, ECPoint pubkey) if (state.Registered) return true; state.Registered = true; engine.SendNotification(Hash, "CandidateStateChanged", - new VM.Types.Array() { pubkey.ToArray(), true, state.Votes }); + new VM.Types.Array(engine.ReferenceCounter) { pubkey.ToArray(), true, state.Votes }); return true; } @@ -357,7 +357,7 @@ private bool UnregisterCandidate(ApplicationEngine engine, ECPoint pubkey) state.Registered = false; CheckCandidate(engine.SnapshotCache, pubkey, state); engine.SendNotification(Hash, "CandidateStateChanged", - new VM.Types.Array() { pubkey.ToArray(), false, state.Votes }); + new VM.Types.Array(engine.ReferenceCounter) { pubkey.ToArray(), false, state.Votes }); return true; } @@ -410,7 +410,7 @@ private async ContractTask Vote(ApplicationEngine engine, UInt160 account, state_account.LastGasPerVote = 0; } engine.SendNotification(Hash, "Vote", - new VM.Types.Array() { account.ToArray(), from?.ToArray() ?? StackItem.Null, voteTo?.ToArray() ?? StackItem.Null, state_account.Balance }); + new VM.Types.Array(engine.ReferenceCounter) { account.ToArray(), from?.ToArray() ?? StackItem.Null, voteTo?.ToArray() ?? StackItem.Null, state_account.Balance }); if (gasDistribution is not null) await GAS.Mint(engine, gasDistribution.Account, gasDistribution.Amount, true); return true; @@ -581,7 +581,7 @@ public override void FromStackItem(StackItem stackItem) LastGasPerVote = @struct[3].GetInteger(); } - public override StackItem ToStackItem(IReferenceCounter referenceCounter) + public override StackItem ToStackItem(IReferenceCounter referenceCounter = null) { Struct @struct = (Struct)base.ToStackItem(referenceCounter); @struct.Add(BalanceHeight); @@ -603,9 +603,9 @@ public void FromStackItem(StackItem stackItem) Votes = @struct[1].GetInteger(); } - public StackItem ToStackItem(IReferenceCounter referenceCounter) + public StackItem ToStackItem(IReferenceCounter referenceCounter = null) { - return new Struct() { Registered, Votes }; + return new Struct(referenceCounter) { Registered, Votes }; } } @@ -622,7 +622,7 @@ protected override (ECPoint, BigInteger) ElementFromStackItem(StackItem item) protected override StackItem ElementToStackItem((ECPoint PublicKey, BigInteger Votes) element, IReferenceCounter referenceCounter) { - return new Struct() { element.PublicKey.ToArray(), element.Votes }; + return new Struct(referenceCounter) { element.PublicKey.ToArray(), element.Votes }; } } diff --git a/src/Neo/SmartContract/Native/OracleContract.cs b/src/Neo/SmartContract/Native/OracleContract.cs index 1a02ec33b1..54156a0029 100644 --- a/src/Neo/SmartContract/Native/OracleContract.cs +++ b/src/Neo/SmartContract/Native/OracleContract.cs @@ -80,7 +80,7 @@ private ContractTask Finish(ApplicationEngine engine) if (response == null) throw new ArgumentException("Oracle response was not found"); 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() { response.Id, request.OriginalTxid.ToArray() }); + 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); return engine.CallFromNativeContractAsync(Hash, request.CallbackContract, request.CallbackMethod, request.Url, userData, (int)response.Code, response.Result); } @@ -224,7 +224,7 @@ private async ContractTask Request(ApplicationEngine engine, string url, string throw new InvalidOperationException("There are too many pending responses for this url"); list.Add(id); - engine.SendNotification(Hash, "OracleRequest", new VM.Types.Array() { id, engine.CallingScriptHash.ToArray(), url, filter ?? StackItem.Null }); + engine.SendNotification(Hash, "OracleRequest", new VM.Types.Array(engine.ReferenceCounter) { id, engine.CallingScriptHash.ToArray(), url, filter ?? StackItem.Null }); } [ContractMethod(CpuFee = 1 << 15)] diff --git a/src/Neo/SmartContract/Native/OracleRequest.cs b/src/Neo/SmartContract/Native/OracleRequest.cs index 82c342761c..864939f204 100644 --- a/src/Neo/SmartContract/Native/OracleRequest.cs +++ b/src/Neo/SmartContract/Native/OracleRequest.cs @@ -68,9 +68,9 @@ public void FromStackItem(StackItem stackItem) UserData = array[6].GetSpan().ToArray(); } - public StackItem ToStackItem(IReferenceCounter referenceCounter) + public StackItem ToStackItem(IReferenceCounter referenceCounter = null) { - return new Array() + return new Array(referenceCounter) { OriginalTxid.ToArray(), GasForResponse, diff --git a/src/Neo/SmartContract/Native/RoleManagement.cs b/src/Neo/SmartContract/Native/RoleManagement.cs index 691f052eab..e57f3f3e83 100644 --- a/src/Neo/SmartContract/Native/RoleManagement.cs +++ b/src/Neo/SmartContract/Native/RoleManagement.cs @@ -69,7 +69,7 @@ private void DesignateAsRole(ApplicationEngine engine, Role role, ECPoint[] node list.AddRange(nodes); list.Sort(); engine.SnapshotCache.Add(key, new StorageItem(list)); - engine.SendNotification(Hash, "Designation", new VM.Types.Array(new StackItem[] { (int)role, engine.PersistingBlock.Index })); + engine.SendNotification(Hash, "Designation", new VM.Types.Array(engine.ReferenceCounter, new StackItem[] { (int)role, engine.PersistingBlock.Index })); } private class NodeList : InteroperableList diff --git a/src/Neo/SmartContract/Native/TransactionState.cs b/src/Neo/SmartContract/Native/TransactionState.cs index 9844aeb70a..f27103c970 100644 --- a/src/Neo/SmartContract/Native/TransactionState.cs +++ b/src/Neo/SmartContract/Native/TransactionState.cs @@ -76,13 +76,13 @@ void IInteroperable.FromStackItem(StackItem stackItem) State = (VMState)(byte)@struct[2].GetInteger(); } - StackItem IInteroperable.ToStackItem(IReferenceCounter referenceCounter) + StackItem IInteroperable.ToStackItem(IReferenceCounter referenceCounter = null) { if (Transaction is null) - return new Struct() { BlockIndex }; + return new Struct(referenceCounter) { BlockIndex }; if (_rawTransaction.IsEmpty) _rawTransaction = Transaction.ToArray(); - return new Struct() { BlockIndex, _rawTransaction, (byte)State }; + return new Struct(referenceCounter) { BlockIndex, _rawTransaction, (byte)State }; } } } diff --git a/src/Neo/SmartContract/Native/TrimmedBlock.cs b/src/Neo/SmartContract/Native/TrimmedBlock.cs index 8b3b72c91d..a11880fc52 100644 --- a/src/Neo/SmartContract/Native/TrimmedBlock.cs +++ b/src/Neo/SmartContract/Native/TrimmedBlock.cs @@ -80,9 +80,9 @@ void IInteroperable.FromStackItem(StackItem stackItem) throw new NotSupportedException(); } - StackItem IInteroperable.ToStackItem(IReferenceCounter referenceCounter) + StackItem IInteroperable.ToStackItem(IReferenceCounter referenceCounter = null) { - return new VM.Types.Array(new StackItem[] + return new VM.Types.Array(referenceCounter, new StackItem[] { // Computed properties Header.Hash.ToArray(), diff --git a/src/Neo/SmartContract/NotifyEventArgs.cs b/src/Neo/SmartContract/NotifyEventArgs.cs index 25650c4d15..02441a8c55 100644 --- a/src/Neo/SmartContract/NotifyEventArgs.cs +++ b/src/Neo/SmartContract/NotifyEventArgs.cs @@ -63,9 +63,9 @@ public void FromStackItem(StackItem stackItem) throw new NotSupportedException(); } - public StackItem ToStackItem(IReferenceCounter referenceCounter) + public StackItem ToStackItem(IReferenceCounter referenceCounter = null) { - return new Array() + return new Array(referenceCounter) { ScriptHash.ToArray(), EventName, @@ -77,7 +77,7 @@ public StackItem ToStackItem(IReferenceCounter referenceCounter, ApplicationEngi { if (engine.IsHardforkEnabled(Hardfork.HF_Domovoi)) { - return new Array() + return new Array(referenceCounter) { ScriptHash.ToArray(), EventName, @@ -85,7 +85,7 @@ public StackItem ToStackItem(IReferenceCounter referenceCounter, ApplicationEngi }; } - return new Array() + return new Array(referenceCounter) { ScriptHash.ToArray(), EventName, diff --git a/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs b/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs index 80ce2a1b54..7a44517b87 100644 --- a/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs +++ b/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs @@ -32,7 +32,7 @@ public void TestMainnetContract() var json = @"{""name"":""Test"",""groups"":[],""features"":{},""supportedstandards"":[],""abi"":{""methods"":[{""name"":""a"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":0,""safe"":false},{""name"":""a0"",""parameters"":[],""returntype"":""Integer"",""offset"":77,""safe"":false},{""name"":""a10"",""parameters"":[],""returntype"":""Void"",""offset"":378,""safe"":false},{""name"":""a11"",""parameters"":[],""returntype"":""Void"",""offset"":398,""safe"":false},{""name"":""a12"",""parameters"":[],""returntype"":""Void"",""offset"":418,""safe"":false},{""name"":""a13"",""parameters"":[],""returntype"":""Void"",""offset"":438,""safe"":false},{""name"":""a14"",""parameters"":[],""returntype"":""Void"",""offset"":458,""safe"":false},{""name"":""a15"",""parameters"":[],""returntype"":""Void"",""offset"":478,""safe"":false},{""name"":""a16"",""parameters"":[],""returntype"":""Void"",""offset"":498,""safe"":false},{""name"":""a17"",""parameters"":[],""returntype"":""Void"",""offset"":518,""safe"":false},{""name"":""a18"",""parameters"":[],""returntype"":""Void"",""offset"":539,""safe"":false},{""name"":""a19"",""parameters"":[],""returntype"":""Void"",""offset"":560,""safe"":false},{""name"":""a20"",""parameters"":[],""returntype"":""Void"",""offset"":581,""safe"":false},{""name"":""a21"",""parameters"":[],""returntype"":""Void"",""offset"":602,""safe"":false},{""name"":""a22"",""parameters"":[],""returntype"":""Void"",""offset"":623,""safe"":false},{""name"":""a23"",""parameters"":[],""returntype"":""Void"",""offset"":644,""safe"":false},{""name"":""a24"",""parameters"":[],""returntype"":""Void"",""offset"":665,""safe"":false},{""name"":""a25"",""parameters"":[],""returntype"":""Void"",""offset"":686,""safe"":false},{""name"":""a26"",""parameters"":[],""returntype"":""Void"",""offset"":707,""safe"":false},{""name"":""a27"",""parameters"":[],""returntype"":""Void"",""offset"":728,""safe"":false},{""name"":""a28"",""parameters"":[],""returntype"":""Void"",""offset"":749,""safe"":false},{""name"":""a29"",""parameters"":[],""returntype"":""Void"",""offset"":770,""safe"":false},{""name"":""a30"",""parameters"":[],""returntype"":""Void"",""offset"":791,""safe"":false},{""name"":""a31"",""parameters"":[],""returntype"":""Void"",""offset"":812,""safe"":false},{""name"":""a32"",""parameters"":[],""returntype"":""Void"",""offset"":833,""safe"":false},{""name"":""a33"",""parameters"":[],""returntype"":""Void"",""offset"":854,""safe"":false},{""name"":""a34"",""parameters"":[],""returntype"":""Void"",""offset"":875,""safe"":false},{""name"":""a35"",""parameters"":[],""returntype"":""Void"",""offset"":896,""safe"":false},{""name"":""a36"",""parameters"":[],""returntype"":""Void"",""offset"":917,""safe"":false},{""name"":""a37"",""parameters"":[],""returntype"":""Void"",""offset"":938,""safe"":false},{""name"":""a38"",""parameters"":[],""returntype"":""Void"",""offset"":959,""safe"":false},{""name"":""a39"",""parameters"":[],""returntype"":""Void"",""offset"":980,""safe"":false},{""name"":""a40"",""parameters"":[],""returntype"":""Void"",""offset"":1001,""safe"":false},{""name"":""a41"",""parameters"":[],""returntype"":""Void"",""offset"":1022,""safe"":false},{""name"":""a42"",""parameters"":[],""returntype"":""Void"",""offset"":1043,""safe"":false},{""name"":""a43"",""parameters"":[],""returntype"":""Void"",""offset"":1064,""safe"":false},{""name"":""a44"",""parameters"":[],""returntype"":""Void"",""offset"":1085,""safe"":false},{""name"":""a45"",""parameters"":[],""returntype"":""Void"",""offset"":1106,""safe"":false},{""name"":""a46"",""parameters"":[],""returntype"":""Void"",""offset"":1127,""safe"":false},{""name"":""a47"",""parameters"":[],""returntype"":""Void"",""offset"":1148,""safe"":false},{""name"":""a48"",""parameters"":[],""returntype"":""Void"",""offset"":1169,""safe"":false},{""name"":""a49"",""parameters"":[],""returntype"":""Void"",""offset"":1190,""safe"":false},{""name"":""a50"",""parameters"":[],""returntype"":""Void"",""offset"":1211,""safe"":false},{""name"":""b"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":1232,""safe"":false},{""name"":""b0"",""parameters"":[],""returntype"":""Integer"",""offset"":1251,""safe"":false},{""name"":""b10"",""parameters"":[],""returntype"":""Void"",""offset"":1275,""safe"":false},{""name"":""b11"",""parameters"":[],""returntype"":""Void"",""offset"":1295,""safe"":false},{""name"":""b12"",""parameters"":[],""returntype"":""Void"",""offset"":1315,""safe"":false},{""name"":""b13"",""parameters"":[],""returntype"":""Void"",""offset"":1335,""safe"":false},{""name"":""b14"",""parameters"":[],""returntype"":""Void"",""offset"":1355,""safe"":false},{""name"":""b15"",""parameters"":[],""returntype"":""Void"",""offset"":1375,""safe"":false},{""name"":""b16"",""parameters"":[],""returntype"":""Void"",""offset"":1395,""safe"":false},{""name"":""b17"",""parameters"":[],""returntype"":""Void"",""offset"":1415,""safe"":false},{""name"":""b18"",""parameters"":[],""returntype"":""Void"",""offset"":1436,""safe"":false},{""name"":""b19"",""parameters"":[],""returntype"":""Void"",""offset"":1457,""safe"":false},{""name"":""b20"",""parameters"":[],""returntype"":""Void"",""offset"":1478,""safe"":false},{""name"":""b21"",""parameters"":[],""returntype"":""Void"",""offset"":1499,""safe"":false},{""name"":""b22"",""parameters"":[],""returntype"":""Void"",""offset"":1520,""safe"":false},{""name"":""b23"",""parameters"":[],""returntype"":""Void"",""offset"":1541,""safe"":false},{""name"":""b24"",""parameters"":[],""returntype"":""Void"",""offset"":1562,""safe"":false},{""name"":""b25"",""parameters"":[],""returntype"":""Void"",""offset"":1583,""safe"":false},{""name"":""b26"",""parameters"":[],""returntype"":""Void"",""offset"":1604,""safe"":false},{""name"":""b27"",""parameters"":[],""returntype"":""Void"",""offset"":1625,""safe"":false},{""name"":""b28"",""parameters"":[],""returntype"":""Void"",""offset"":1646,""safe"":false},{""name"":""b29"",""parameters"":[],""returntype"":""Void"",""offset"":1667,""safe"":false},{""name"":""b30"",""parameters"":[],""returntype"":""Void"",""offset"":1688,""safe"":false},{""name"":""b31"",""parameters"":[],""returntype"":""Void"",""offset"":1709,""safe"":false},{""name"":""b32"",""parameters"":[],""returntype"":""Void"",""offset"":1730,""safe"":false},{""name"":""b33"",""parameters"":[],""returntype"":""Void"",""offset"":1751,""safe"":false},{""name"":""b34"",""parameters"":[],""returntype"":""Void"",""offset"":1772,""safe"":false},{""name"":""b35"",""parameters"":[],""returntype"":""Void"",""offset"":1793,""safe"":false},{""name"":""b36"",""parameters"":[],""returntype"":""Void"",""offset"":1814,""safe"":false},{""name"":""b37"",""parameters"":[],""returntype"":""Void"",""offset"":1835,""safe"":false},{""name"":""b38"",""parameters"":[],""returntype"":""Void"",""offset"":1856,""safe"":false},{""name"":""b39"",""parameters"":[],""returntype"":""Void"",""offset"":1877,""safe"":false},{""name"":""b40"",""parameters"":[],""returntype"":""Void"",""offset"":1898,""safe"":false},{""name"":""b41"",""parameters"":[],""returntype"":""Void"",""offset"":1919,""safe"":false},{""name"":""b42"",""parameters"":[],""returntype"":""Void"",""offset"":1940,""safe"":false},{""name"":""b43"",""parameters"":[],""returntype"":""Void"",""offset"":1961,""safe"":false},{""name"":""b44"",""parameters"":[],""returntype"":""Void"",""offset"":1982,""safe"":false},{""name"":""b45"",""parameters"":[],""returntype"":""Void"",""offset"":2003,""safe"":false},{""name"":""b46"",""parameters"":[],""returntype"":""Void"",""offset"":2024,""safe"":false},{""name"":""b47"",""parameters"":[],""returntype"":""Void"",""offset"":2045,""safe"":false},{""name"":""b48"",""parameters"":[],""returntype"":""Void"",""offset"":2066,""safe"":false},{""name"":""b49"",""parameters"":[],""returntype"":""Void"",""offset"":2087,""safe"":false},{""name"":""b50"",""parameters"":[],""returntype"":""Void"",""offset"":2108,""safe"":false},{""name"":""c"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":2129,""safe"":false},{""name"":""c0"",""parameters"":[],""returntype"":""Integer"",""offset"":2148,""safe"":false},{""name"":""c10"",""parameters"":[],""returntype"":""Void"",""offset"":2172,""safe"":false},{""name"":""c11"",""parameters"":[],""returntype"":""Void"",""offset"":2192,""safe"":false},{""name"":""c12"",""parameters"":[],""returntype"":""Void"",""offset"":2212,""safe"":false},{""name"":""c13"",""parameters"":[],""returntype"":""Void"",""offset"":2232,""safe"":false},{""name"":""c14"",""parameters"":[],""returntype"":""Void"",""offset"":2252,""safe"":false},{""name"":""c15"",""parameters"":[],""returntype"":""Void"",""offset"":2272,""safe"":false},{""name"":""c16"",""parameters"":[],""returntype"":""Void"",""offset"":2292,""safe"":false},{""name"":""c17"",""parameters"":[],""returntype"":""Void"",""offset"":2312,""safe"":false},{""name"":""c18"",""parameters"":[],""returntype"":""Void"",""offset"":2333,""safe"":false},{""name"":""c19"",""parameters"":[],""returntype"":""Void"",""offset"":2354,""safe"":false},{""name"":""c20"",""parameters"":[],""returntype"":""Void"",""offset"":2375,""safe"":false},{""name"":""c21"",""parameters"":[],""returntype"":""Void"",""offset"":2396,""safe"":false},{""name"":""c22"",""parameters"":[],""returntype"":""Void"",""offset"":2417,""safe"":false},{""name"":""c23"",""parameters"":[],""returntype"":""Void"",""offset"":2438,""safe"":false},{""name"":""c24"",""parameters"":[],""returntype"":""Void"",""offset"":2459,""safe"":false},{""name"":""c25"",""parameters"":[],""returntype"":""Void"",""offset"":2480,""safe"":false},{""name"":""c26"",""parameters"":[],""returntype"":""Void"",""offset"":2501,""safe"":false},{""name"":""c27"",""parameters"":[],""returntype"":""Void"",""offset"":2522,""safe"":false},{""name"":""c28"",""parameters"":[],""returntype"":""Void"",""offset"":2543,""safe"":false},{""name"":""c29"",""parameters"":[],""returntype"":""Void"",""offset"":2564,""safe"":false},{""name"":""c30"",""parameters"":[],""returntype"":""Void"",""offset"":2585,""safe"":false},{""name"":""c31"",""parameters"":[],""returntype"":""Void"",""offset"":2606,""safe"":false},{""name"":""c32"",""parameters"":[],""returntype"":""Void"",""offset"":2627,""safe"":false},{""name"":""c33"",""parameters"":[],""returntype"":""Void"",""offset"":2648,""safe"":false},{""name"":""c34"",""parameters"":[],""returntype"":""Void"",""offset"":2669,""safe"":false},{""name"":""c35"",""parameters"":[],""returntype"":""Void"",""offset"":2690,""safe"":false},{""name"":""c36"",""parameters"":[],""returntype"":""Void"",""offset"":2711,""safe"":false},{""name"":""c37"",""parameters"":[],""returntype"":""Void"",""offset"":2732,""safe"":false},{""name"":""c38"",""parameters"":[],""returntype"":""Void"",""offset"":2753,""safe"":false},{""name"":""c39"",""parameters"":[],""returntype"":""Void"",""offset"":2774,""safe"":false},{""name"":""c40"",""parameters"":[],""returntype"":""Void"",""offset"":2795,""safe"":false},{""name"":""c41"",""parameters"":[],""returntype"":""Void"",""offset"":2816,""safe"":false},{""name"":""c42"",""parameters"":[],""returntype"":""Void"",""offset"":2837,""safe"":false},{""name"":""c43"",""parameters"":[],""returntype"":""Void"",""offset"":2858,""safe"":false},{""name"":""c44"",""parameters"":[],""returntype"":""Void"",""offset"":2879,""safe"":false},{""name"":""c45"",""parameters"":[],""returntype"":""Void"",""offset"":2900,""safe"":false},{""name"":""c46"",""parameters"":[],""returntype"":""Void"",""offset"":2921,""safe"":false},{""name"":""c47"",""parameters"":[],""returntype"":""Void"",""offset"":2942,""safe"":false},{""name"":""c48"",""parameters"":[],""returntype"":""Void"",""offset"":2963,""safe"":false},{""name"":""c49"",""parameters"":[],""returntype"":""Void"",""offset"":2984,""safe"":false},{""name"":""c50"",""parameters"":[],""returntype"":""Void"",""offset"":3005,""safe"":false},{""name"":""verify"",""parameters"":[],""returntype"":""Boolean"",""offset"":3026,""safe"":false},{""name"":""d"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":3039,""safe"":false},{""name"":""d0"",""parameters"":[],""returntype"":""Integer"",""offset"":3058,""safe"":false},{""name"":""d10"",""parameters"":[],""returntype"":""Void"",""offset"":3082,""safe"":false},{""name"":""d11"",""parameters"":[],""returntype"":""Void"",""offset"":3102,""safe"":false},{""name"":""d12"",""parameters"":[],""returntype"":""Void"",""offset"":3122,""safe"":false},{""name"":""d13"",""parameters"":[],""returntype"":""Void"",""offset"":3142,""safe"":false},{""name"":""d14"",""parameters"":[],""returntype"":""Void"",""offset"":3162,""safe"":false},{""name"":""d15"",""parameters"":[],""returntype"":""Void"",""offset"":3182,""safe"":false},{""name"":""d16"",""parameters"":[],""returntype"":""Void"",""offset"":3202,""safe"":false},{""name"":""d17"",""parameters"":[],""returntype"":""Void"",""offset"":3222,""safe"":false},{""name"":""d18"",""parameters"":[],""returntype"":""Void"",""offset"":3243,""safe"":false},{""name"":""d19"",""parameters"":[],""returntype"":""Void"",""offset"":3264,""safe"":false},{""name"":""d20"",""parameters"":[],""returntype"":""Void"",""offset"":3285,""safe"":false},{""name"":""d21"",""parameters"":[],""returntype"":""Void"",""offset"":3306,""safe"":false},{""name"":""d22"",""parameters"":[],""returntype"":""Void"",""offset"":3327,""safe"":false},{""name"":""d23"",""parameters"":[],""returntype"":""Void"",""offset"":3348,""safe"":false},{""name"":""d24"",""parameters"":[],""returntype"":""Void"",""offset"":3369,""safe"":false},{""name"":""d25"",""parameters"":[],""returntype"":""Void"",""offset"":3390,""safe"":false},{""name"":""d26"",""parameters"":[],""returntype"":""Void"",""offset"":3411,""safe"":false},{""name"":""d27"",""parameters"":[],""returntype"":""Void"",""offset"":3432,""safe"":false},{""name"":""d28"",""parameters"":[],""returntype"":""Void"",""offset"":3453,""safe"":false},{""name"":""d29"",""parameters"":[],""returntype"":""Void"",""offset"":3474,""safe"":false},{""name"":""d30"",""parameters"":[],""returntype"":""Void"",""offset"":3495,""safe"":false},{""name"":""d31"",""parameters"":[],""returntype"":""Void"",""offset"":3516,""safe"":false},{""name"":""d32"",""parameters"":[],""returntype"":""Void"",""offset"":3537,""safe"":false},{""name"":""d33"",""parameters"":[],""returntype"":""Void"",""offset"":3558,""safe"":false},{""name"":""d34"",""parameters"":[],""returntype"":""Void"",""offset"":3579,""safe"":false},{""name"":""d35"",""parameters"":[],""returntype"":""Void"",""offset"":3600,""safe"":false},{""name"":""d36"",""parameters"":[],""returntype"":""Void"",""offset"":3621,""safe"":false},{""name"":""d37"",""parameters"":[],""returntype"":""Void"",""offset"":3642,""safe"":false},{""name"":""d38"",""parameters"":[],""returntype"":""Void"",""offset"":3663,""safe"":false},{""name"":""d39"",""parameters"":[],""returntype"":""Void"",""offset"":3684,""safe"":false},{""name"":""d40"",""parameters"":[],""returntype"":""Void"",""offset"":3705,""safe"":false},{""name"":""d41"",""parameters"":[],""returntype"":""Void"",""offset"":3726,""safe"":false},{""name"":""d42"",""parameters"":[],""returntype"":""Void"",""offset"":3747,""safe"":false},{""name"":""d43"",""parameters"":[],""returntype"":""Void"",""offset"":3768,""safe"":false},{""name"":""d44"",""parameters"":[],""returntype"":""Void"",""offset"":3789,""safe"":false},{""name"":""d45"",""parameters"":[],""returntype"":""Void"",""offset"":3810,""safe"":false},{""name"":""d46"",""parameters"":[],""returntype"":""Void"",""offset"":3831,""safe"":false},{""name"":""d47"",""parameters"":[],""returntype"":""Void"",""offset"":3852,""safe"":false},{""name"":""d48"",""parameters"":[],""returntype"":""Void"",""offset"":3873,""safe"":false},{""name"":""d49"",""parameters"":[],""returntype"":""Void"",""offset"":3894,""safe"":false},{""name"":""d50"",""parameters"":[],""returntype"":""Void"",""offset"":3915,""safe"":false},{""name"":""e"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":3936,""safe"":false},{""name"":""e0"",""parameters"":[],""returntype"":""Integer"",""offset"":3955,""safe"":false},{""name"":""e10"",""parameters"":[],""returntype"":""Void"",""offset"":3979,""safe"":false},{""name"":""e11"",""parameters"":[],""returntype"":""Void"",""offset"":3999,""safe"":false},{""name"":""e12"",""parameters"":[],""returntype"":""Void"",""offset"":4019,""safe"":false},{""name"":""e13"",""parameters"":[],""returntype"":""Void"",""offset"":4039,""safe"":false},{""name"":""e14"",""parameters"":[],""returntype"":""Void"",""offset"":4059,""safe"":false},{""name"":""e15"",""parameters"":[],""returntype"":""Void"",""offset"":4079,""safe"":false},{""name"":""e16"",""parameters"":[],""returntype"":""Void"",""offset"":4099,""safe"":false},{""name"":""e17"",""parameters"":[],""returntype"":""Void"",""offset"":4119,""safe"":false},{""name"":""e18"",""parameters"":[],""returntype"":""Void"",""offset"":4140,""safe"":false},{""name"":""e19"",""parameters"":[],""returntype"":""Void"",""offset"":4161,""safe"":false},{""name"":""e20"",""parameters"":[],""returntype"":""Void"",""offset"":4182,""safe"":false},{""name"":""e21"",""parameters"":[],""returntype"":""Void"",""offset"":4203,""safe"":false},{""name"":""e22"",""parameters"":[],""returntype"":""Void"",""offset"":4224,""safe"":false},{""name"":""e23"",""parameters"":[],""returntype"":""Void"",""offset"":4245,""safe"":false},{""name"":""e24"",""parameters"":[],""returntype"":""Void"",""offset"":4266,""safe"":false},{""name"":""e25"",""parameters"":[],""returntype"":""Void"",""offset"":4287,""safe"":false},{""name"":""e26"",""parameters"":[],""returntype"":""Void"",""offset"":4308,""safe"":false},{""name"":""e27"",""parameters"":[],""returntype"":""Void"",""offset"":4329,""safe"":false},{""name"":""e28"",""parameters"":[],""returntype"":""Void"",""offset"":4350,""safe"":false},{""name"":""e29"",""parameters"":[],""returntype"":""Void"",""offset"":4371,""safe"":false},{""name"":""e30"",""parameters"":[],""returntype"":""Void"",""offset"":4392,""safe"":false},{""name"":""e31"",""parameters"":[],""returntype"":""Void"",""offset"":4413,""safe"":false},{""name"":""e32"",""parameters"":[],""returntype"":""Void"",""offset"":4434,""safe"":false},{""name"":""e33"",""parameters"":[],""returntype"":""Void"",""offset"":4455,""safe"":false},{""name"":""e34"",""parameters"":[],""returntype"":""Void"",""offset"":4476,""safe"":false},{""name"":""e35"",""parameters"":[],""returntype"":""Void"",""offset"":4497,""safe"":false},{""name"":""e36"",""parameters"":[],""returntype"":""Void"",""offset"":4518,""safe"":false},{""name"":""e37"",""parameters"":[],""returntype"":""Void"",""offset"":4539,""safe"":false},{""name"":""e38"",""parameters"":[],""returntype"":""Void"",""offset"":4560,""safe"":false},{""name"":""e39"",""parameters"":[],""returntype"":""Void"",""offset"":4581,""safe"":false},{""name"":""e40"",""parameters"":[],""returntype"":""Void"",""offset"":4602,""safe"":false},{""name"":""e41"",""parameters"":[],""returntype"":""Void"",""offset"":4623,""safe"":false},{""name"":""e42"",""parameters"":[],""returntype"":""Void"",""offset"":4644,""safe"":false},{""name"":""e43"",""parameters"":[],""returntype"":""Void"",""offset"":4665,""safe"":false},{""name"":""e44"",""parameters"":[],""returntype"":""Void"",""offset"":4686,""safe"":false},{""name"":""e45"",""parameters"":[],""returntype"":""Void"",""offset"":4707,""safe"":false},{""name"":""e46"",""parameters"":[],""returntype"":""Void"",""offset"":4728,""safe"":false},{""name"":""e47"",""parameters"":[],""returntype"":""Void"",""offset"":4749,""safe"":false},{""name"":""e48"",""parameters"":[],""returntype"":""Void"",""offset"":4770,""safe"":false},{""name"":""e49"",""parameters"":[],""returntype"":""Void"",""offset"":4791,""safe"":false},{""name"":""e50"",""parameters"":[],""returntype"":""Void"",""offset"":4812,""safe"":false},{""name"":""f"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":4833,""safe"":false},{""name"":""f0"",""parameters"":[],""returntype"":""Integer"",""offset"":4852,""safe"":false},{""name"":""f10"",""parameters"":[],""returntype"":""Void"",""offset"":4876,""safe"":false},{""name"":""f11"",""parameters"":[],""returntype"":""Void"",""offset"":4896,""safe"":false},{""name"":""f12"",""parameters"":[],""returntype"":""Void"",""offset"":4916,""safe"":false},{""name"":""f13"",""parameters"":[],""returntype"":""Void"",""offset"":4936,""safe"":false},{""name"":""f14"",""parameters"":[],""returntype"":""Void"",""offset"":4956,""safe"":false},{""name"":""f15"",""parameters"":[],""returntype"":""Void"",""offset"":4976,""safe"":false},{""name"":""f16"",""parameters"":[],""returntype"":""Void"",""offset"":4996,""safe"":false},{""name"":""f17"",""parameters"":[],""returntype"":""Void"",""offset"":5016,""safe"":false},{""name"":""f18"",""parameters"":[],""returntype"":""Void"",""offset"":5037,""safe"":false},{""name"":""f19"",""parameters"":[],""returntype"":""Void"",""offset"":5058,""safe"":false},{""name"":""f20"",""parameters"":[],""returntype"":""Void"",""offset"":5079,""safe"":false},{""name"":""f21"",""parameters"":[],""returntype"":""Void"",""offset"":5100,""safe"":false},{""name"":""f22"",""parameters"":[],""returntype"":""Void"",""offset"":5121,""safe"":false},{""name"":""f23"",""parameters"":[],""returntype"":""Void"",""offset"":5142,""safe"":false},{""name"":""f24"",""parameters"":[],""returntype"":""Void"",""offset"":5163,""safe"":false},{""name"":""f25"",""parameters"":[],""returntype"":""Void"",""offset"":5184,""safe"":false},{""name"":""f26"",""parameters"":[],""returntype"":""Void"",""offset"":5205,""safe"":false},{""name"":""f27"",""parameters"":[],""returntype"":""Void"",""offset"":5226,""safe"":false},{""name"":""f28"",""parameters"":[],""returntype"":""Void"",""offset"":5247,""safe"":false},{""name"":""f29"",""parameters"":[],""returntype"":""Void"",""offset"":5268,""safe"":false},{""name"":""f30"",""parameters"":[],""returntype"":""Void"",""offset"":5289,""safe"":false},{""name"":""f31"",""parameters"":[],""returntype"":""Void"",""offset"":5310,""safe"":false},{""name"":""f32"",""parameters"":[],""returntype"":""Void"",""offset"":5331,""safe"":false},{""name"":""f33"",""parameters"":[],""returntype"":""Void"",""offset"":5352,""safe"":false},{""name"":""f34"",""parameters"":[],""returntype"":""Void"",""offset"":5373,""safe"":false},{""name"":""f35"",""parameters"":[],""returntype"":""Void"",""offset"":5394,""safe"":false},{""name"":""f36"",""parameters"":[],""returntype"":""Void"",""offset"":5415,""safe"":false},{""name"":""f37"",""parameters"":[],""returntype"":""Void"",""offset"":5436,""safe"":false},{""name"":""f38"",""parameters"":[],""returntype"":""Void"",""offset"":5457,""safe"":false},{""name"":""f39"",""parameters"":[],""returntype"":""Void"",""offset"":5478,""safe"":false},{""name"":""f40"",""parameters"":[],""returntype"":""Void"",""offset"":5499,""safe"":false},{""name"":""f41"",""parameters"":[],""returntype"":""Void"",""offset"":5520,""safe"":false},{""name"":""f42"",""parameters"":[],""returntype"":""Void"",""offset"":5541,""safe"":false},{""name"":""f43"",""parameters"":[],""returntype"":""Void"",""offset"":5562,""safe"":false},{""name"":""f44"",""parameters"":[],""returntype"":""Void"",""offset"":5583,""safe"":false},{""name"":""f45"",""parameters"":[],""returntype"":""Void"",""offset"":5604,""safe"":false},{""name"":""f46"",""parameters"":[],""returntype"":""Void"",""offset"":5625,""safe"":false},{""name"":""f47"",""parameters"":[],""returntype"":""Void"",""offset"":5646,""safe"":false},{""name"":""f48"",""parameters"":[],""returntype"":""Void"",""offset"":5667,""safe"":false},{""name"":""f49"",""parameters"":[],""returntype"":""Void"",""offset"":5688,""safe"":false},{""name"":""f50"",""parameters"":[],""returntype"":""Void"",""offset"":5709,""safe"":false},{""name"":""g"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":5730,""safe"":false},{""name"":""g0"",""parameters"":[],""returntype"":""Integer"",""offset"":5749,""safe"":false},{""name"":""g10"",""parameters"":[],""returntype"":""Void"",""offset"":5773,""safe"":false},{""name"":""g11"",""parameters"":[],""returntype"":""Void"",""offset"":5793,""safe"":false},{""name"":""g12"",""parameters"":[],""returntype"":""Void"",""offset"":5813,""safe"":false},{""name"":""g13"",""parameters"":[],""returntype"":""Void"",""offset"":5833,""safe"":false},{""name"":""g14"",""parameters"":[],""returntype"":""Void"",""offset"":5853,""safe"":false},{""name"":""g15"",""parameters"":[],""returntype"":""Void"",""offset"":5873,""safe"":false},{""name"":""g16"",""parameters"":[],""returntype"":""Void"",""offset"":5893,""safe"":false},{""name"":""g17"",""parameters"":[],""returntype"":""Void"",""offset"":5913,""safe"":false},{""name"":""g18"",""parameters"":[],""returntype"":""Void"",""offset"":5934,""safe"":false},{""name"":""g19"",""parameters"":[],""returntype"":""Void"",""offset"":5955,""safe"":false},{""name"":""g20"",""parameters"":[],""returntype"":""Void"",""offset"":5976,""safe"":false},{""name"":""g21"",""parameters"":[],""returntype"":""Void"",""offset"":5997,""safe"":false},{""name"":""g22"",""parameters"":[],""returntype"":""Void"",""offset"":6018,""safe"":false},{""name"":""g23"",""parameters"":[],""returntype"":""Void"",""offset"":6039,""safe"":false},{""name"":""g24"",""parameters"":[],""returntype"":""Void"",""offset"":6060,""safe"":false},{""name"":""g25"",""parameters"":[],""returntype"":""Void"",""offset"":6081,""safe"":false},{""name"":""g26"",""parameters"":[],""returntype"":""Void"",""offset"":6102,""safe"":false},{""name"":""g27"",""parameters"":[],""returntype"":""Void"",""offset"":6123,""safe"":false},{""name"":""g28"",""parameters"":[],""returntype"":""Void"",""offset"":6144,""safe"":false},{""name"":""g29"",""parameters"":[],""returntype"":""Void"",""offset"":6165,""safe"":false},{""name"":""g30"",""parameters"":[],""returntype"":""Void"",""offset"":6186,""safe"":false},{""name"":""g31"",""parameters"":[],""returntype"":""Void"",""offset"":6207,""safe"":false},{""name"":""g32"",""parameters"":[],""returntype"":""Void"",""offset"":6228,""safe"":false},{""name"":""g33"",""parameters"":[],""returntype"":""Void"",""offset"":6249,""safe"":false},{""name"":""g34"",""parameters"":[],""returntype"":""Void"",""offset"":6270,""safe"":false},{""name"":""g35"",""parameters"":[],""returntype"":""Void"",""offset"":6291,""safe"":false},{""name"":""g36"",""parameters"":[],""returntype"":""Void"",""offset"":6312,""safe"":false},{""name"":""g37"",""parameters"":[],""returntype"":""Void"",""offset"":6333,""safe"":false},{""name"":""g38"",""parameters"":[],""returntype"":""Void"",""offset"":6354,""safe"":false},{""name"":""g39"",""parameters"":[],""returntype"":""Void"",""offset"":6375,""safe"":false},{""name"":""g40"",""parameters"":[],""returntype"":""Void"",""offset"":6396,""safe"":false},{""name"":""g41"",""parameters"":[],""returntype"":""Void"",""offset"":6417,""safe"":false},{""name"":""g42"",""parameters"":[],""returntype"":""Void"",""offset"":6438,""safe"":false},{""name"":""g43"",""parameters"":[],""returntype"":""Void"",""offset"":6459,""safe"":false},{""name"":""g44"",""parameters"":[],""returntype"":""Void"",""offset"":6480,""safe"":false},{""name"":""g45"",""parameters"":[],""returntype"":""Void"",""offset"":6501,""safe"":false},{""name"":""g46"",""parameters"":[],""returntype"":""Void"",""offset"":6522,""safe"":false},{""name"":""g47"",""parameters"":[],""returntype"":""Void"",""offset"":6543,""safe"":false},{""name"":""g48"",""parameters"":[],""returntype"":""Void"",""offset"":6564,""safe"":false},{""name"":""g49"",""parameters"":[],""returntype"":""Void"",""offset"":6585,""safe"":false},{""name"":""g50"",""parameters"":[],""returntype"":""Void"",""offset"":6606,""safe"":false},{""name"":""h"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":6627,""safe"":false},{""name"":""h0"",""parameters"":[],""returntype"":""Integer"",""offset"":6646,""safe"":false},{""name"":""h10"",""parameters"":[],""returntype"":""Void"",""offset"":6670,""safe"":false},{""name"":""h11"",""parameters"":[],""returntype"":""Void"",""offset"":6690,""safe"":false},{""name"":""h12"",""parameters"":[],""returntype"":""Void"",""offset"":6710,""safe"":false},{""name"":""h13"",""parameters"":[],""returntype"":""Void"",""offset"":6730,""safe"":false},{""name"":""h14"",""parameters"":[],""returntype"":""Void"",""offset"":6750,""safe"":false},{""name"":""h15"",""parameters"":[],""returntype"":""Void"",""offset"":6770,""safe"":false},{""name"":""h16"",""parameters"":[],""returntype"":""Void"",""offset"":6790,""safe"":false},{""name"":""h17"",""parameters"":[],""returntype"":""Void"",""offset"":6810,""safe"":false},{""name"":""h18"",""parameters"":[],""returntype"":""Void"",""offset"":6831,""safe"":false},{""name"":""h19"",""parameters"":[],""returntype"":""Void"",""offset"":6852,""safe"":false},{""name"":""h20"",""parameters"":[],""returntype"":""Void"",""offset"":6873,""safe"":false},{""name"":""h21"",""parameters"":[],""returntype"":""Void"",""offset"":6894,""safe"":false},{""name"":""h22"",""parameters"":[],""returntype"":""Void"",""offset"":6915,""safe"":false},{""name"":""h23"",""parameters"":[],""returntype"":""Void"",""offset"":6936,""safe"":false},{""name"":""h24"",""parameters"":[],""returntype"":""Void"",""offset"":6957,""safe"":false},{""name"":""h25"",""parameters"":[],""returntype"":""Void"",""offset"":6978,""safe"":false},{""name"":""h26"",""parameters"":[],""returntype"":""Void"",""offset"":6999,""safe"":false},{""name"":""h27"",""parameters"":[],""returntype"":""Void"",""offset"":7020,""safe"":false},{""name"":""h28"",""parameters"":[],""returntype"":""Void"",""offset"":7041,""safe"":false},{""name"":""h29"",""parameters"":[],""returntype"":""Void"",""offset"":7062,""safe"":false},{""name"":""h30"",""parameters"":[],""returntype"":""Void"",""offset"":7083,""safe"":false},{""name"":""h31"",""parameters"":[],""returntype"":""Void"",""offset"":7104,""safe"":false},{""name"":""h32"",""parameters"":[],""returntype"":""Void"",""offset"":7125,""safe"":false},{""name"":""h33"",""parameters"":[],""returntype"":""Void"",""offset"":7146,""safe"":false},{""name"":""h34"",""parameters"":[],""returntype"":""Void"",""offset"":7167,""safe"":false},{""name"":""h35"",""parameters"":[],""returntype"":""Void"",""offset"":7188,""safe"":false},{""name"":""h36"",""parameters"":[],""returntype"":""Void"",""offset"":7209,""safe"":false},{""name"":""h37"",""parameters"":[],""returntype"":""Void"",""offset"":7230,""safe"":false},{""name"":""h38"",""parameters"":[],""returntype"":""Void"",""offset"":7251,""safe"":false},{""name"":""h39"",""parameters"":[],""returntype"":""Void"",""offset"":7272,""safe"":false},{""name"":""h40"",""parameters"":[],""returntype"":""Void"",""offset"":7293,""safe"":false},{""name"":""h41"",""parameters"":[],""returntype"":""Void"",""offset"":7314,""safe"":false},{""name"":""h42"",""parameters"":[],""returntype"":""Void"",""offset"":7335,""safe"":false},{""name"":""h43"",""parameters"":[],""returntype"":""Void"",""offset"":7356,""safe"":false},{""name"":""h44"",""parameters"":[],""returntype"":""Void"",""offset"":7377,""safe"":false},{""name"":""h45"",""parameters"":[],""returntype"":""Void"",""offset"":7398,""safe"":false},{""name"":""h46"",""parameters"":[],""returntype"":""Void"",""offset"":7419,""safe"":false},{""name"":""h47"",""parameters"":[],""returntype"":""Void"",""offset"":7440,""safe"":false},{""name"":""h48"",""parameters"":[],""returntype"":""Void"",""offset"":7461,""safe"":false},{""name"":""h49"",""parameters"":[],""returntype"":""Void"",""offset"":7482,""safe"":false},{""name"":""h50"",""parameters"":[],""returntype"":""Void"",""offset"":7503,""safe"":false},{""name"":""i"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":7524,""safe"":false},{""name"":""i0"",""parameters"":[],""returntype"":""Integer"",""offset"":7545,""safe"":false},{""name"":""i10"",""parameters"":[],""returntype"":""Void"",""offset"":7571,""safe"":false},{""name"":""i11"",""parameters"":[],""returntype"":""Void"",""offset"":7593,""safe"":false},{""name"":""i12"",""parameters"":[],""returntype"":""Void"",""offset"":7615,""safe"":false},{""name"":""i13"",""parameters"":[],""returntype"":""Void"",""offset"":7637,""safe"":false},{""name"":""i14"",""parameters"":[],""returntype"":""Void"",""offset"":7659,""safe"":false},{""name"":""i15"",""parameters"":[],""returntype"":""Void"",""offset"":7681,""safe"":false},{""name"":""i16"",""parameters"":[],""returntype"":""Void"",""offset"":7703,""safe"":false},{""name"":""i17"",""parameters"":[],""returntype"":""Void"",""offset"":7725,""safe"":false},{""name"":""i18"",""parameters"":[],""returntype"":""Void"",""offset"":7748,""safe"":false},{""name"":""i19"",""parameters"":[],""returntype"":""Void"",""offset"":7771,""safe"":false},{""name"":""i20"",""parameters"":[],""returntype"":""Void"",""offset"":7794,""safe"":false},{""name"":""i21"",""parameters"":[],""returntype"":""Void"",""offset"":7817,""safe"":false},{""name"":""i22"",""parameters"":[],""returntype"":""Void"",""offset"":7840,""safe"":false},{""name"":""i23"",""parameters"":[],""returntype"":""Void"",""offset"":7863,""safe"":false},{""name"":""i24"",""parameters"":[],""returntype"":""Void"",""offset"":7886,""safe"":false},{""name"":""i25"",""parameters"":[],""returntype"":""Void"",""offset"":7909,""safe"":false},{""name"":""i26"",""parameters"":[],""returntype"":""Void"",""offset"":7932,""safe"":false},{""name"":""i27"",""parameters"":[],""returntype"":""Void"",""offset"":7955,""safe"":false},{""name"":""i28"",""parameters"":[],""returntype"":""Void"",""offset"":7978,""safe"":false},{""name"":""i29"",""parameters"":[],""returntype"":""Void"",""offset"":8001,""safe"":false},{""name"":""i30"",""parameters"":[],""returntype"":""Void"",""offset"":8024,""safe"":false},{""name"":""i31"",""parameters"":[],""returntype"":""Void"",""offset"":8047,""safe"":false},{""name"":""i32"",""parameters"":[],""returntype"":""Void"",""offset"":8070,""safe"":false},{""name"":""i33"",""parameters"":[],""returntype"":""Void"",""offset"":8093,""safe"":false},{""name"":""i34"",""parameters"":[],""returntype"":""Void"",""offset"":8116,""safe"":false},{""name"":""i35"",""parameters"":[],""returntype"":""Void"",""offset"":8139,""safe"":false},{""name"":""i36"",""parameters"":[],""returntype"":""Void"",""offset"":8162,""safe"":false},{""name"":""i37"",""parameters"":[],""returntype"":""Void"",""offset"":8185,""safe"":false},{""name"":""i38"",""parameters"":[],""returntype"":""Void"",""offset"":8208,""safe"":false},{""name"":""i39"",""parameters"":[],""returntype"":""Void"",""offset"":8231,""safe"":false},{""name"":""i40"",""parameters"":[],""returntype"":""Void"",""offset"":8254,""safe"":false},{""name"":""i41"",""parameters"":[],""returntype"":""Void"",""offset"":8277,""safe"":false},{""name"":""i42"",""parameters"":[],""returntype"":""Void"",""offset"":8300,""safe"":false},{""name"":""i43"",""parameters"":[],""returntype"":""Void"",""offset"":8323,""safe"":false},{""name"":""i44"",""parameters"":[],""returntype"":""Void"",""offset"":8346,""safe"":false},{""name"":""i45"",""parameters"":[],""returntype"":""Void"",""offset"":8369,""safe"":false},{""name"":""i46"",""parameters"":[],""returntype"":""Void"",""offset"":8392,""safe"":false},{""name"":""i47"",""parameters"":[],""returntype"":""Void"",""offset"":8415,""safe"":false},{""name"":""i48"",""parameters"":[],""returntype"":""Void"",""offset"":8438,""safe"":false},{""name"":""i49"",""parameters"":[],""returntype"":""Void"",""offset"":8461,""safe"":false},{""name"":""i50"",""parameters"":[],""returntype"":""Void"",""offset"":8484,""safe"":false},{""name"":""update"",""parameters"":[{""name"":""nefFile"",""type"":""ByteArray""},{""name"":""manifest"",""type"":""String""}],""returntype"":""Void"",""offset"":8511,""safe"":false},{""name"":""j"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":8578,""safe"":false},{""name"":""j0"",""parameters"":[],""returntype"":""Integer"",""offset"":8599,""safe"":false},{""name"":""j10"",""parameters"":[],""returntype"":""Void"",""offset"":8625,""safe"":false},{""name"":""j11"",""parameters"":[],""returntype"":""Void"",""offset"":8647,""safe"":false},{""name"":""j12"",""parameters"":[],""returntype"":""Void"",""offset"":8669,""safe"":false},{""name"":""j13"",""parameters"":[],""returntype"":""Void"",""offset"":8691,""safe"":false},{""name"":""j14"",""parameters"":[],""returntype"":""Void"",""offset"":8713,""safe"":false},{""name"":""j15"",""parameters"":[],""returntype"":""Void"",""offset"":8735,""safe"":false},{""name"":""j16"",""parameters"":[],""returntype"":""Void"",""offset"":8757,""safe"":false},{""name"":""j17"",""parameters"":[],""returntype"":""Void"",""offset"":8779,""safe"":false},{""name"":""j18"",""parameters"":[],""returntype"":""Void"",""offset"":8802,""safe"":false},{""name"":""j19"",""parameters"":[],""returntype"":""Void"",""offset"":8825,""safe"":false},{""name"":""j20"",""parameters"":[],""returntype"":""Void"",""offset"":8848,""safe"":false},{""name"":""j21"",""parameters"":[],""returntype"":""Void"",""offset"":8871,""safe"":false},{""name"":""j22"",""parameters"":[],""returntype"":""Void"",""offset"":8894,""safe"":false},{""name"":""j23"",""parameters"":[],""returntype"":""Void"",""offset"":8917,""safe"":false},{""name"":""j24"",""parameters"":[],""returntype"":""Void"",""offset"":8940,""safe"":false},{""name"":""j25"",""parameters"":[],""returntype"":""Void"",""offset"":8963,""safe"":false},{""name"":""j26"",""parameters"":[],""returntype"":""Void"",""offset"":8986,""safe"":false},{""name"":""j27"",""parameters"":[],""returntype"":""Void"",""offset"":9009,""safe"":false},{""name"":""j28"",""parameters"":[],""returntype"":""Void"",""offset"":9032,""safe"":false},{""name"":""j29"",""parameters"":[],""returntype"":""Void"",""offset"":9055,""safe"":false},{""name"":""j30"",""parameters"":[],""returntype"":""Void"",""offset"":9078,""safe"":false},{""name"":""j31"",""parameters"":[],""returntype"":""Void"",""offset"":9101,""safe"":false},{""name"":""j32"",""parameters"":[],""returntype"":""Void"",""offset"":9124,""safe"":false},{""name"":""j33"",""parameters"":[],""returntype"":""Void"",""offset"":9147,""safe"":false},{""name"":""j34"",""parameters"":[],""returntype"":""Void"",""offset"":9170,""safe"":false},{""name"":""j35"",""parameters"":[],""returntype"":""Void"",""offset"":9193,""safe"":false},{""name"":""j36"",""parameters"":[],""returntype"":""Void"",""offset"":9216,""safe"":false},{""name"":""j37"",""parameters"":[],""returntype"":""Void"",""offset"":9239,""safe"":false},{""name"":""j38"",""parameters"":[],""returntype"":""Void"",""offset"":9262,""safe"":false},{""name"":""j39"",""parameters"":[],""returntype"":""Void"",""offset"":9285,""safe"":false},{""name"":""j40"",""parameters"":[],""returntype"":""Void"",""offset"":9308,""safe"":false},{""name"":""j41"",""parameters"":[],""returntype"":""Void"",""offset"":9331,""safe"":false},{""name"":""j42"",""parameters"":[],""returntype"":""Void"",""offset"":9354,""safe"":false},{""name"":""j43"",""parameters"":[],""returntype"":""Void"",""offset"":9377,""safe"":false},{""name"":""j44"",""parameters"":[],""returntype"":""Void"",""offset"":9400,""safe"":false},{""name"":""j45"",""parameters"":[],""returntype"":""Void"",""offset"":9423,""safe"":false},{""name"":""j46"",""parameters"":[],""returntype"":""Void"",""offset"":9446,""safe"":false},{""name"":""j47"",""parameters"":[],""returntype"":""Void"",""offset"":9469,""safe"":false},{""name"":""j48"",""parameters"":[],""returntype"":""Void"",""offset"":9492,""safe"":false},{""name"":""j49"",""parameters"":[],""returntype"":""Void"",""offset"":9515,""safe"":false},{""name"":""j50"",""parameters"":[],""returntype"":""Void"",""offset"":9538,""safe"":false},{""name"":""k"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":9561,""safe"":false},{""name"":""k0"",""parameters"":[],""returntype"":""Integer"",""offset"":9601,""safe"":false},{""name"":""k10"",""parameters"":[],""returntype"":""Void"",""offset"":9646,""safe"":false},{""name"":""k11"",""parameters"":[],""returntype"":""Void"",""offset"":9687,""safe"":false},{""name"":""k12"",""parameters"":[],""returntype"":""Void"",""offset"":9728,""safe"":false},{""name"":""k13"",""parameters"":[],""returntype"":""Void"",""offset"":9769,""safe"":false},{""name"":""k14"",""parameters"":[],""returntype"":""Void"",""offset"":9810,""safe"":false},{""name"":""k15"",""parameters"":[],""returntype"":""Void"",""offset"":9851,""safe"":false},{""name"":""k16"",""parameters"":[],""returntype"":""Void"",""offset"":9892,""safe"":false},{""name"":""k17"",""parameters"":[],""returntype"":""Void"",""offset"":9933,""safe"":false},{""name"":""k18"",""parameters"":[],""returntype"":""Void"",""offset"":9975,""safe"":false},{""name"":""k19"",""parameters"":[],""returntype"":""Void"",""offset"":10017,""safe"":false},{""name"":""k20"",""parameters"":[],""returntype"":""Void"",""offset"":10059,""safe"":false},{""name"":""k21"",""parameters"":[],""returntype"":""Void"",""offset"":10101,""safe"":false},{""name"":""k22"",""parameters"":[],""returntype"":""Void"",""offset"":10143,""safe"":false},{""name"":""k23"",""parameters"":[],""returntype"":""Void"",""offset"":10185,""safe"":false},{""name"":""k24"",""parameters"":[],""returntype"":""Void"",""offset"":10227,""safe"":false},{""name"":""k25"",""parameters"":[],""returntype"":""Void"",""offset"":10269,""safe"":false},{""name"":""k26"",""parameters"":[],""returntype"":""Void"",""offset"":10311,""safe"":false},{""name"":""k27"",""parameters"":[],""returntype"":""Void"",""offset"":10353,""safe"":false},{""name"":""k28"",""parameters"":[],""returntype"":""Void"",""offset"":10395,""safe"":false},{""name"":""k29"",""parameters"":[],""returntype"":""Void"",""offset"":10437,""safe"":false},{""name"":""k30"",""parameters"":[],""returntype"":""Void"",""offset"":10479,""safe"":false},{""name"":""k31"",""parameters"":[],""returntype"":""Void"",""offset"":10521,""safe"":false},{""name"":""k32"",""parameters"":[],""returntype"":""Void"",""offset"":10563,""safe"":false},{""name"":""k33"",""parameters"":[],""returntype"":""Void"",""offset"":10605,""safe"":false},{""name"":""k34"",""parameters"":[],""returntype"":""Void"",""offset"":10647,""safe"":false},{""name"":""k35"",""parameters"":[],""returntype"":""Void"",""offset"":10689,""safe"":false},{""name"":""k36"",""parameters"":[],""returntype"":""Void"",""offset"":10731,""safe"":false},{""name"":""k37"",""parameters"":[],""returntype"":""Void"",""offset"":10773,""safe"":false},{""name"":""k38"",""parameters"":[],""returntype"":""Void"",""offset"":10815,""safe"":false},{""name"":""k39"",""parameters"":[],""returntype"":""Void"",""offset"":10857,""safe"":false},{""name"":""k40"",""parameters"":[],""returntype"":""Void"",""offset"":10899,""safe"":false},{""name"":""k41"",""parameters"":[],""returntype"":""Void"",""offset"":10941,""safe"":false},{""name"":""k42"",""parameters"":[],""returntype"":""Void"",""offset"":10983,""safe"":false},{""name"":""k43"",""parameters"":[],""returntype"":""Void"",""offset"":11025,""safe"":false},{""name"":""k44"",""parameters"":[],""returntype"":""Void"",""offset"":11067,""safe"":false},{""name"":""k45"",""parameters"":[],""returntype"":""Void"",""offset"":11109,""safe"":false},{""name"":""k46"",""parameters"":[],""returntype"":""Void"",""offset"":11151,""safe"":false},{""name"":""k47"",""parameters"":[],""returntype"":""Void"",""offset"":11193,""safe"":false},{""name"":""k48"",""parameters"":[],""returntype"":""Void"",""offset"":11235,""safe"":false},{""name"":""k49"",""parameters"":[],""returntype"":""Void"",""offset"":11277,""safe"":false},{""name"":""k50"",""parameters"":[],""returntype"":""Void"",""offset"":11319,""safe"":false},{""name"":""l"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":11361,""safe"":false},{""name"":""l0"",""parameters"":[],""returntype"":""Integer"",""offset"":11401,""safe"":false},{""name"":""l10"",""parameters"":[],""returntype"":""Void"",""offset"":11446,""safe"":false},{""name"":""l11"",""parameters"":[],""returntype"":""Void"",""offset"":11487,""safe"":false},{""name"":""l12"",""parameters"":[],""returntype"":""Void"",""offset"":11528,""safe"":false},{""name"":""l13"",""parameters"":[],""returntype"":""Void"",""offset"":11569,""safe"":false},{""name"":""l14"",""parameters"":[],""returntype"":""Void"",""offset"":11610,""safe"":false},{""name"":""l15"",""parameters"":[],""returntype"":""Void"",""offset"":11651,""safe"":false},{""name"":""l16"",""parameters"":[],""returntype"":""Void"",""offset"":11692,""safe"":false},{""name"":""l17"",""parameters"":[],""returntype"":""Void"",""offset"":11733,""safe"":false},{""name"":""l18"",""parameters"":[],""returntype"":""Void"",""offset"":11775,""safe"":false},{""name"":""l19"",""parameters"":[],""returntype"":""Void"",""offset"":11817,""safe"":false},{""name"":""l20"",""parameters"":[],""returntype"":""Void"",""offset"":11859,""safe"":false},{""name"":""l21"",""parameters"":[],""returntype"":""Void"",""offset"":11901,""safe"":false},{""name"":""l22"",""parameters"":[],""returntype"":""Void"",""offset"":11943,""safe"":false},{""name"":""l23"",""parameters"":[],""returntype"":""Void"",""offset"":11985,""safe"":false},{""name"":""l24"",""parameters"":[],""returntype"":""Void"",""offset"":12027,""safe"":false},{""name"":""l25"",""parameters"":[],""returntype"":""Void"",""offset"":12069,""safe"":false},{""name"":""l26"",""parameters"":[],""returntype"":""Void"",""offset"":12111,""safe"":false},{""name"":""l27"",""parameters"":[],""returntype"":""Void"",""offset"":12153,""safe"":false},{""name"":""l28"",""parameters"":[],""returntype"":""Void"",""offset"":12195,""safe"":false},{""name"":""l29"",""parameters"":[],""returntype"":""Void"",""offset"":12237,""safe"":false},{""name"":""l30"",""parameters"":[],""returntype"":""Void"",""offset"":12279,""safe"":false},{""name"":""l31"",""parameters"":[],""returntype"":""Void"",""offset"":12321,""safe"":false},{""name"":""l32"",""parameters"":[],""returntype"":""Void"",""offset"":12363,""safe"":false},{""name"":""l33"",""parameters"":[],""returntype"":""Void"",""offset"":12405,""safe"":false},{""name"":""l34"",""parameters"":[],""returntype"":""Void"",""offset"":12447,""safe"":false},{""name"":""l35"",""parameters"":[],""returntype"":""Void"",""offset"":12489,""safe"":false},{""name"":""l36"",""parameters"":[],""returntype"":""Void"",""offset"":12531,""safe"":false},{""name"":""l37"",""parameters"":[],""returntype"":""Void"",""offset"":12573,""safe"":false},{""name"":""l38"",""parameters"":[],""returntype"":""Void"",""offset"":12615,""safe"":false},{""name"":""l39"",""parameters"":[],""returntype"":""Void"",""offset"":12657,""safe"":false},{""name"":""l40"",""parameters"":[],""returntype"":""Void"",""offset"":12699,""safe"":false},{""name"":""l41"",""parameters"":[],""returntype"":""Void"",""offset"":12741,""safe"":false},{""name"":""l42"",""parameters"":[],""returntype"":""Void"",""offset"":12783,""safe"":false},{""name"":""l43"",""parameters"":[],""returntype"":""Void"",""offset"":12825,""safe"":false},{""name"":""l44"",""parameters"":[],""returntype"":""Void"",""offset"":12867,""safe"":false},{""name"":""l45"",""parameters"":[],""returntype"":""Void"",""offset"":12909,""safe"":false},{""name"":""l46"",""parameters"":[],""returntype"":""Void"",""offset"":12951,""safe"":false},{""name"":""l47"",""parameters"":[],""returntype"":""Void"",""offset"":12993,""safe"":false},{""name"":""l48"",""parameters"":[],""returntype"":""Void"",""offset"":13035,""safe"":false},{""name"":""l49"",""parameters"":[],""returntype"":""Void"",""offset"":13077,""safe"":false},{""name"":""l50"",""parameters"":[],""returntype"":""Void"",""offset"":13119,""safe"":false},{""name"":""m"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":13161,""safe"":false},{""name"":""m0"",""parameters"":[],""returntype"":""Integer"",""offset"":13181,""safe"":false},{""name"":""m10"",""parameters"":[],""returntype"":""Void"",""offset"":13206,""safe"":false},{""name"":""m11"",""parameters"":[],""returntype"":""Void"",""offset"":13227,""safe"":false},{""name"":""m12"",""parameters"":[],""returntype"":""Void"",""offset"":13248,""safe"":false},{""name"":""m13"",""parameters"":[],""returntype"":""Void"",""offset"":13269,""safe"":false},{""name"":""m14"",""parameters"":[],""returntype"":""Void"",""offset"":13290,""safe"":false},{""name"":""m15"",""parameters"":[],""returntype"":""Void"",""offset"":13311,""safe"":false},{""name"":""m16"",""parameters"":[],""returntype"":""Void"",""offset"":13332,""safe"":false},{""name"":""m17"",""parameters"":[],""returntype"":""Void"",""offset"":13353,""safe"":false},{""name"":""m18"",""parameters"":[],""returntype"":""Void"",""offset"":13375,""safe"":false},{""name"":""m19"",""parameters"":[],""returntype"":""Void"",""offset"":13397,""safe"":false},{""name"":""m20"",""parameters"":[],""returntype"":""Void"",""offset"":13419,""safe"":false},{""name"":""m21"",""parameters"":[],""returntype"":""Void"",""offset"":13441,""safe"":false},{""name"":""m22"",""parameters"":[],""returntype"":""Void"",""offset"":13463,""safe"":false},{""name"":""m23"",""parameters"":[],""returntype"":""Void"",""offset"":13485,""safe"":false},{""name"":""m24"",""parameters"":[],""returntype"":""Void"",""offset"":13507,""safe"":false},{""name"":""m25"",""parameters"":[],""returntype"":""Void"",""offset"":13529,""safe"":false},{""name"":""m26"",""parameters"":[],""returntype"":""Void"",""offset"":13551,""safe"":false},{""name"":""m27"",""parameters"":[],""returntype"":""Void"",""offset"":13573,""safe"":false},{""name"":""m28"",""parameters"":[],""returntype"":""Void"",""offset"":13595,""safe"":false},{""name"":""m29"",""parameters"":[],""returntype"":""Void"",""offset"":13617,""safe"":false},{""name"":""m30"",""parameters"":[],""returntype"":""Void"",""offset"":13639,""safe"":false},{""name"":""m31"",""parameters"":[],""returntype"":""Void"",""offset"":13661,""safe"":false},{""name"":""m32"",""parameters"":[],""returntype"":""Void"",""offset"":13683,""safe"":false},{""name"":""m33"",""parameters"":[],""returntype"":""Void"",""offset"":13705,""safe"":false},{""name"":""m34"",""parameters"":[],""returntype"":""Void"",""offset"":13727,""safe"":false},{""name"":""m35"",""parameters"":[],""returntype"":""Void"",""offset"":13749,""safe"":false},{""name"":""m36"",""parameters"":[],""returntype"":""Void"",""offset"":13771,""safe"":false},{""name"":""m37"",""parameters"":[],""returntype"":""Void"",""offset"":13793,""safe"":false},{""name"":""m38"",""parameters"":[],""returntype"":""Void"",""offset"":13815,""safe"":false},{""name"":""m39"",""parameters"":[],""returntype"":""Void"",""offset"":13837,""safe"":false},{""name"":""m40"",""parameters"":[],""returntype"":""Void"",""offset"":13859,""safe"":false},{""name"":""m41"",""parameters"":[],""returntype"":""Void"",""offset"":13881,""safe"":false},{""name"":""m42"",""parameters"":[],""returntype"":""Void"",""offset"":13903,""safe"":false},{""name"":""m43"",""parameters"":[],""returntype"":""Void"",""offset"":13925,""safe"":false},{""name"":""m44"",""parameters"":[],""returntype"":""Void"",""offset"":13947,""safe"":false},{""name"":""m45"",""parameters"":[],""returntype"":""Void"",""offset"":13969,""safe"":false},{""name"":""m46"",""parameters"":[],""returntype"":""Void"",""offset"":13991,""safe"":false},{""name"":""m47"",""parameters"":[],""returntype"":""Void"",""offset"":14013,""safe"":false},{""name"":""m48"",""parameters"":[],""returntype"":""Void"",""offset"":14035,""safe"":false},{""name"":""m49"",""parameters"":[],""returntype"":""Void"",""offset"":14057,""safe"":false},{""name"":""m50"",""parameters"":[],""returntype"":""Void"",""offset"":14079,""safe"":false},{""name"":""n"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":14101,""safe"":false},{""name"":""n0"",""parameters"":[],""returntype"":""Integer"",""offset"":14121,""safe"":false},{""name"":""n10"",""parameters"":[],""returntype"":""Void"",""offset"":14146,""safe"":false},{""name"":""n11"",""parameters"":[],""returntype"":""Void"",""offset"":14167,""safe"":false},{""name"":""n12"",""parameters"":[],""returntype"":""Void"",""offset"":14188,""safe"":false},{""name"":""n13"",""parameters"":[],""returntype"":""Void"",""offset"":14209,""safe"":false},{""name"":""n14"",""parameters"":[],""returntype"":""Void"",""offset"":14230,""safe"":false},{""name"":""n15"",""parameters"":[],""returntype"":""Void"",""offset"":14251,""safe"":false},{""name"":""n16"",""parameters"":[],""returntype"":""Void"",""offset"":14272,""safe"":false},{""name"":""n17"",""parameters"":[],""returntype"":""Void"",""offset"":14293,""safe"":false},{""name"":""n18"",""parameters"":[],""returntype"":""Void"",""offset"":14315,""safe"":false},{""name"":""n19"",""parameters"":[],""returntype"":""Void"",""offset"":14337,""safe"":false},{""name"":""n20"",""parameters"":[],""returntype"":""Void"",""offset"":14359,""safe"":false},{""name"":""n21"",""parameters"":[],""returntype"":""Void"",""offset"":14381,""safe"":false},{""name"":""n22"",""parameters"":[],""returntype"":""Void"",""offset"":14403,""safe"":false},{""name"":""n23"",""parameters"":[],""returntype"":""Void"",""offset"":14425,""safe"":false},{""name"":""n24"",""parameters"":[],""returntype"":""Void"",""offset"":14447,""safe"":false},{""name"":""n25"",""parameters"":[],""returntype"":""Void"",""offset"":14469,""safe"":false},{""name"":""n26"",""parameters"":[],""returntype"":""Void"",""offset"":14491,""safe"":false},{""name"":""n27"",""parameters"":[],""returntype"":""Void"",""offset"":14513,""safe"":false},{""name"":""n28"",""parameters"":[],""returntype"":""Void"",""offset"":14535,""safe"":false},{""name"":""n29"",""parameters"":[],""returntype"":""Void"",""offset"":14557,""safe"":false},{""name"":""n30"",""parameters"":[],""returntype"":""Void"",""offset"":14579,""safe"":false},{""name"":""n31"",""parameters"":[],""returntype"":""Void"",""offset"":14601,""safe"":false},{""name"":""n32"",""parameters"":[],""returntype"":""Void"",""offset"":14623,""safe"":false},{""name"":""n33"",""parameters"":[],""returntype"":""Void"",""offset"":14645,""safe"":false},{""name"":""n34"",""parameters"":[],""returntype"":""Void"",""offset"":14667,""safe"":false},{""name"":""n35"",""parameters"":[],""returntype"":""Void"",""offset"":14689,""safe"":false},{""name"":""n36"",""parameters"":[],""returntype"":""Void"",""offset"":14711,""safe"":false},{""name"":""n37"",""parameters"":[],""returntype"":""Void"",""offset"":14733,""safe"":false},{""name"":""n38"",""parameters"":[],""returntype"":""Void"",""offset"":14755,""safe"":false},{""name"":""n39"",""parameters"":[],""returntype"":""Void"",""offset"":14777,""safe"":false},{""name"":""n40"",""parameters"":[],""returntype"":""Void"",""offset"":14799,""safe"":false},{""name"":""n41"",""parameters"":[],""returntype"":""Void"",""offset"":14821,""safe"":false},{""name"":""n42"",""parameters"":[],""returntype"":""Void"",""offset"":14843,""safe"":false},{""name"":""n43"",""parameters"":[],""returntype"":""Void"",""offset"":14865,""safe"":false},{""name"":""n44"",""parameters"":[],""returntype"":""Void"",""offset"":14887,""safe"":false},{""name"":""n45"",""parameters"":[],""returntype"":""Void"",""offset"":14909,""safe"":false},{""name"":""n46"",""parameters"":[],""returntype"":""Void"",""offset"":14931,""safe"":false},{""name"":""n47"",""parameters"":[],""returntype"":""Void"",""offset"":14953,""safe"":false},{""name"":""n48"",""parameters"":[],""returntype"":""Void"",""offset"":14975,""safe"":false},{""name"":""n49"",""parameters"":[],""returntype"":""Void"",""offset"":14997,""safe"":false},{""name"":""n50"",""parameters"":[],""returntype"":""Void"",""offset"":15019,""safe"":false},{""name"":""_initialize"",""parameters"":[],""returntype"":""Void"",""offset"":15041,""safe"":false}],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""extra"":{""Author"":""Test"",""Email"":""Test@Test"",""Description"":""This is a Test Contract""}}"; var manifest = ContractManifest.Parse(json); - var counter = new ReferenceCounterV2(); + var counter = new ReferenceCounter(); var item = manifest.ToStackItem(counter); var data = BinarySerializer.Serialize(item, 1024 * 1024, 4096); @@ -118,7 +118,7 @@ public void ToInteroperable_Trust() { var json = @"{""name"":""CallOracleContract-6"",""groups"":[],""features"":{},""supportedstandards"":[],""abi"":{""methods"":[{""name"":""request"",""parameters"":[{""name"":""url"",""type"":""String""},{""name"":""filter"",""type"":""String""},{""name"":""gasForResponse"",""type"":""Integer""}],""returntype"":""Void"",""offset"":0,""safe"":false},{""name"":""callback"",""parameters"":[{""name"":""url"",""type"":""String""},{""name"":""userData"",""type"":""Any""},{""name"":""responseCode"",""type"":""Integer""},{""name"":""response"",""type"":""ByteArray""}],""returntype"":""Void"",""offset"":86,""safe"":false},{""name"":""getStoredUrl"",""parameters"":[],""returntype"":""String"",""offset"":129,""safe"":false},{""name"":""getStoredResponseCode"",""parameters"":[],""returntype"":""Integer"",""offset"":142,""safe"":false},{""name"":""getStoredResponse"",""parameters"":[],""returntype"":""ByteArray"",""offset"":165,""safe"":false}],""events"":[]},""permissions"":[{""contract"":""0xfe924b7cfe89ddd271abaf7210a80a7e11178758"",""methods"":""*""},{""contract"":""*"",""methods"":""*""}],""trusts"":[""0xfe924b7cfe89ddd271abaf7210a80a7e11178758"",""*""],""extra"":{}}"; var manifest = ContractManifest.Parse(json); - var s = (VM.Types.Struct)manifest.ToStackItem(new ReferenceCounterV2()); + var s = (VM.Types.Struct)manifest.ToStackItem(new ReferenceCounter()); manifest = s.ToInteroperable(); Assert.IsFalse(manifest.Permissions[0].Contract.IsWildcard); diff --git a/tests/Neo.UnitTests/SmartContract/UT_NotifyEventArgs.cs b/tests/Neo.UnitTests/SmartContract/UT_NotifyEventArgs.cs index 6e80a93bb0..59afbbb760 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_NotifyEventArgs.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_NotifyEventArgs.cs @@ -43,7 +43,7 @@ public void TestIssue3300() // https://github.com/neo-project/neo/issues/3300 engine.LoadScript(script.ToArray()); } - var ns = new Array(); + var ns = new Array(engine.ReferenceCounter); for (var i = 0; i < 500; i++) { ns.Add(""); @@ -54,12 +54,12 @@ public void TestIssue3300() // https://github.com/neo-project/neo/issues/3300 // This should have being 0, but we have optimized the vm to not clean the reference counter // unless it is necessary, so the reference counter will be 1000. // Same reason why its 1504 instead of 504. - Assert.AreEqual(0, engine.ReferenceCounter.Count); + Assert.AreEqual(1000, engine.ReferenceCounter.Count); // This will make a deepcopy for the notification, along with the 500 state items. engine.GetNotifications(hash); // With the fix of issue 3300, the reference counter calculates not only // the notifaction items, but also the subitems of the notification state. - Assert.AreEqual(0, engine.ReferenceCounter.Count); + Assert.AreEqual(1504, engine.ReferenceCounter.Count); } } } diff --git a/tests/Neo.VM.Tests/UT_EvaluationStack.cs b/tests/Neo.VM.Tests/UT_EvaluationStack.cs index 6aa15ea209..fb1f5e5813 100644 --- a/tests/Neo.VM.Tests/UT_EvaluationStack.cs +++ b/tests/Neo.VM.Tests/UT_EvaluationStack.cs @@ -25,7 +25,7 @@ public class UT_EvaluationStack private static EvaluationStack CreateOrderedStack(int count) { var check = new Integer[count]; - var stack = new EvaluationStack(new ReferenceCounterV2()); + var stack = new EvaluationStack(new ReferenceCounter()); for (int x = 1; x <= count; x++) { @@ -56,7 +56,7 @@ public void TestClear() public void TestCopyTo() { var stack = CreateOrderedStack(3); - var copy = new EvaluationStack(new ReferenceCounterV2()); + var copy = new EvaluationStack(new ReferenceCounter()); Assert.ThrowsException(() => stack.CopyTo(copy, -2)); Assert.ThrowsException(() => stack.CopyTo(copy, 4)); @@ -93,7 +93,7 @@ public void TestCopyTo() public void TestMoveTo() { var stack = CreateOrderedStack(3); - var other = new EvaluationStack(new ReferenceCounterV2()); + var other = new EvaluationStack(new ReferenceCounter()); stack.MoveTo(other, 0); @@ -126,7 +126,7 @@ public void TestMoveTo() [TestMethod] public void TestInsertPeek() { - var stack = new EvaluationStack(new ReferenceCounterV2()); + var stack = new EvaluationStack(new ReferenceCounter()); stack.Insert(0, 3); stack.Insert(1, 1); @@ -203,7 +203,7 @@ public void TestReverse() [TestMethod] public void TestEvaluationStackPrint() { - var stack = new EvaluationStack(new ReferenceCounterV2()); + var stack = new EvaluationStack(new ReferenceCounter()); stack.Insert(0, 3); stack.Insert(1, 1); @@ -216,7 +216,7 @@ public void TestEvaluationStackPrint() [TestMethod] public void TestPrintInvalidUTF8() { - var stack = new EvaluationStack(new ReferenceCounterV2()); + var stack = new EvaluationStack(new ReferenceCounter()); stack.Insert(0, "4CC95219999D421243C8161E3FC0F4290C067845".FromHexString()); Assert.AreEqual("[ByteString(\"Base64: TMlSGZmdQhJDyBYeP8D0KQwGeEU=\")]", stack.ToString()); } diff --git a/tests/Neo.VM.Tests/UT_ExecutionContext.cs b/tests/Neo.VM.Tests/UT_ExecutionContext.cs index 14c4e3235e..b53003a7e6 100644 --- a/tests/Neo.VM.Tests/UT_ExecutionContext.cs +++ b/tests/Neo.VM.Tests/UT_ExecutionContext.cs @@ -27,7 +27,7 @@ class TestState [TestMethod] public void TestStateTest() { - var context = new ExecutionContext(Array.Empty(), -1, new ReferenceCounterV2()); + var context = new ExecutionContext(Array.Empty(), -1, new ReferenceCounter()); // Test factory diff --git a/tests/Neo.VM.Tests/UT_ReferenceCounter.cs b/tests/Neo.VM.Tests/UT_ReferenceCounter.cs index 6ce0dae21f..61f7788dd8 100644 --- a/tests/Neo.VM.Tests/UT_ReferenceCounter.cs +++ b/tests/Neo.VM.Tests/UT_ReferenceCounter.cs @@ -158,9 +158,9 @@ public void TestRemoveReferrer() Assert.AreEqual(VMState.BREAK, debugger.StepInto()); Assert.AreEqual(3, engine.ReferenceCounter.Count); Assert.AreEqual(VMState.BREAK, debugger.StepInto()); - Assert.AreEqual(1, engine.ReferenceCounter.Count); + Assert.AreEqual(2, engine.ReferenceCounter.Count); Assert.AreEqual(VMState.HALT, debugger.Execute()); - Assert.AreEqual(0, engine.ReferenceCounter.Count); + Assert.AreEqual(1, engine.ReferenceCounter.Count); } [TestMethod] @@ -237,18 +237,18 @@ public void TestArrayNoPush() using ExecutionEngine engine = new(); engine.LoadScript(sb.ToArray()); Assert.AreEqual(0, engine.ReferenceCounter.Count); - Array array = new(new StackItem[] { 1, 2, 3, 4 }); - engine.CurrentContext.EvaluationStack.Push(array); - Assert.AreEqual(array.Count + 1, engine.ReferenceCounter.Count); + Array array = new(engine.ReferenceCounter, new StackItem[] { 1, 2, 3, 4 }); + Assert.AreEqual(array.Count, engine.ReferenceCounter.Count); Assert.AreEqual(VMState.HALT, engine.Execute()); - Assert.AreEqual(array.Count + 1, engine.ReferenceCounter.Count); + Assert.AreEqual(array.Count, engine.ReferenceCounter.Count); } [TestMethod] + [ExpectedException(typeof(InvalidOperationException))] public void TestInvalidReferenceStackItem() { - - var arr = new Array(); + var reference = new ReferenceCounter(); + var arr = new Array(reference); var arr2 = new Array(); for (var i = 0; i < 10; i++) @@ -257,12 +257,7 @@ public void TestInvalidReferenceStackItem() } arr.Add(arr2); - - var engine = new ExecutionEngine(); - engine.LoadScript(new Script((byte[])[(byte)OpCode.NOP])); - - engine.CurrentContext.EvaluationStack.Push(arr); - Assert.AreEqual(12, engine.ReferenceCounter.Count); + Assert.AreEqual(11, reference.Count); } } } diff --git a/tests/Neo.VM.Tests/UT_Slot.cs b/tests/Neo.VM.Tests/UT_Slot.cs index d175be1310..ea2f38029b 100644 --- a/tests/Neo.VM.Tests/UT_Slot.cs +++ b/tests/Neo.VM.Tests/UT_Slot.cs @@ -31,7 +31,7 @@ private static Slot CreateOrderedSlot(int count) check[x - 1] = x; } - var slot = new Slot(check, new ReferenceCounterV2()); + var slot = new Slot(check, new ReferenceCounter()); Assert.AreEqual(count, slot.Count); CollectionAssert.AreEqual(check, slot.ToArray()); From 5d9d7c47db26286715fa3cabd34a0f92340c72d3 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Sun, 17 Nov 2024 23:45:19 +0800 Subject: [PATCH 07/36] adopt new solution as using null rc, instead of making large scale change. and add hardfork --- src/Neo.VM/EvaluationStack.cs | 8 +++- src/Neo.VM/ExecutionEngine.cs | 40 +++++++++++++++---- .../IReferenceCounter.cs | 2 + src/Neo.VM/ReferenceCounter/RCVersion.cs | 19 +++++++++ .../ReferenceCounter.cs | 2 + .../ReferenceCounterV2.cs | 2 + src/Neo.VM/Types/Array.cs | 3 +- src/Neo.VM/Types/CompoundType.cs | 9 ++++- tests/Neo.VM.Tests/UT_EvaluationStack.cs | 12 +++--- 9 files changed, 79 insertions(+), 18 deletions(-) rename src/Neo.VM/{ => ReferenceCounter}/IReferenceCounter.cs (98%) create mode 100644 src/Neo.VM/ReferenceCounter/RCVersion.cs rename src/Neo.VM/{ => ReferenceCounter}/ReferenceCounter.cs (99%) rename src/Neo.VM/{ => ReferenceCounter}/ReferenceCounterV2.cs (98%) diff --git a/src/Neo.VM/EvaluationStack.cs b/src/Neo.VM/EvaluationStack.cs index 463df8d12a..c26d295666 100644 --- a/src/Neo.VM/EvaluationStack.cs +++ b/src/Neo.VM/EvaluationStack.cs @@ -13,6 +13,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Runtime.CompilerServices; @@ -28,7 +29,12 @@ public sealed class EvaluationStack : IReadOnlyList internal IReferenceCounter ReferenceCounter => referenceCounter; - internal EvaluationStack(IReferenceCounter referenceCounter) + /// + /// Initializes a new instance of the class. + /// + /// The reference counter. Cannot be null. + /// Keep the NotNull attribute to explicitly announce that the reference counter cannot be null. + internal EvaluationStack([NotNull] IReferenceCounter referenceCounter) { this.referenceCounter = referenceCounter; } diff --git a/src/Neo.VM/ExecutionEngine.cs b/src/Neo.VM/ExecutionEngine.cs index 8a3167b4c8..025650a952 100644 --- a/src/Neo.VM/ExecutionEngine.cs +++ b/src/Neo.VM/ExecutionEngine.cs @@ -34,7 +34,10 @@ public class ExecutionEngine : IDisposable /// /// Used for reference counting of objects in the VM. /// - public IReferenceCounter ReferenceCounter { get; } + [Obsolete("ReferenceCounter will not be visible in a future release.")] + public IReferenceCounter ReferenceCounter => _referenceCounter; + + private readonly IReferenceCounter _referenceCounter; /// /// The invocation stack of the VM. @@ -83,9 +86,24 @@ protected internal set /// /// Initializes a new instance of the class. /// + /// The reference counter to be used. + /// referenceCounter is shared cross ExecutionContexts. /// The jump table to be used. - public ExecutionEngine(JumpTable? jumpTable = null) : this(jumpTable, new ReferenceCounter(), ExecutionEngineLimits.Default) + public ExecutionEngine(IReferenceCounter referenceCounter, JumpTable? jumpTable = null) + : this(jumpTable, referenceCounter, ExecutionEngineLimits.Default) { + + } + + /// + /// Initializes a new instance of the class. + /// + /// The jump table to be used. + [Obsolete("Use ExecutionEngine(IReferenceCounter) to specify the reference counter.")] + public ExecutionEngine(JumpTable? jumpTable = null) + : this(jumpTable, new ReferenceCounter(), ExecutionEngineLimits.Default) + { + } /// @@ -98,7 +116,7 @@ protected ExecutionEngine(JumpTable? jumpTable, IReferenceCounter referenceCount { JumpTable = jumpTable ?? JumpTable.Default; Limits = limits; - ReferenceCounter = referenceCounter; + _referenceCounter = referenceCounter; ResultStack = new EvaluationStack(referenceCounter); } @@ -209,7 +227,7 @@ internal virtual void UnloadContext(ExecutionContext context) [MethodImpl(MethodImplOptions.AggressiveInlining)] protected ExecutionContext CreateContext(Script script, int rvcount, int initialPosition) { - return new ExecutionContext(script, rvcount, ReferenceCounter) + return new ExecutionContext(script, rvcount, _referenceCounter) { InstructionPointer = initialPosition }; @@ -289,9 +307,17 @@ public T Pop() where T : StackItem /// protected virtual void PostExecuteInstruction(Instruction instruction) { - if (ReferenceCounter.Count < Limits.MaxStackSize) return; - if (ReferenceCounter.CheckZeroReferred() > Limits.MaxStackSize) - throw new InvalidOperationException($"MaxStackSize exceed: {ReferenceCounter.Count}"); + if (_referenceCounter.Version == RCVersion.V1) + { + if (_referenceCounter.Count < Limits.MaxStackSize) return; + if (_referenceCounter.CheckZeroReferred() > Limits.MaxStackSize) + throw new InvalidOperationException($"MaxStackSize exceed: {_referenceCounter.Count}"); + } + else + { + if (_referenceCounter.Count <= Limits.MaxStackSize) return; + throw new InvalidOperationException($"MaxStackSize exceed: {_referenceCounter.Count}"); + } } /// diff --git a/src/Neo.VM/IReferenceCounter.cs b/src/Neo.VM/ReferenceCounter/IReferenceCounter.cs similarity index 98% rename from src/Neo.VM/IReferenceCounter.cs rename to src/Neo.VM/ReferenceCounter/IReferenceCounter.cs index f451c0e316..40c9723ccf 100644 --- a/src/Neo.VM/IReferenceCounter.cs +++ b/src/Neo.VM/ReferenceCounter/IReferenceCounter.cs @@ -18,6 +18,8 @@ namespace Neo.VM /// public interface IReferenceCounter { + RCVersion Version { get; init; } + /// /// Gets the count of references. /// diff --git a/src/Neo.VM/ReferenceCounter/RCVersion.cs b/src/Neo.VM/ReferenceCounter/RCVersion.cs new file mode 100644 index 0000000000..a5ca7f7f98 --- /dev/null +++ b/src/Neo.VM/ReferenceCounter/RCVersion.cs @@ -0,0 +1,19 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// RCVersion.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. + +namespace Neo.VM +{ + public enum RCVersion + { + V1 = 0, + V2 = 1, + } +} diff --git a/src/Neo.VM/ReferenceCounter.cs b/src/Neo.VM/ReferenceCounter/ReferenceCounter.cs similarity index 99% rename from src/Neo.VM/ReferenceCounter.cs rename to src/Neo.VM/ReferenceCounter/ReferenceCounter.cs index 2ba7d74063..4c7ac4f352 100644 --- a/src/Neo.VM/ReferenceCounter.cs +++ b/src/Neo.VM/ReferenceCounter/ReferenceCounter.cs @@ -38,6 +38,8 @@ public sealed class ReferenceCounter : IReferenceCounter // Keeps the total count of references. private int _referencesCount = 0; + public RCVersion Version { get; init; } = RCVersion.V1; + /// public int Count => _referencesCount; diff --git a/src/Neo.VM/ReferenceCounterV2.cs b/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs similarity index 98% rename from src/Neo.VM/ReferenceCounterV2.cs rename to src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs index 0dad0f185f..76827f6f19 100644 --- a/src/Neo.VM/ReferenceCounterV2.cs +++ b/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs @@ -25,6 +25,8 @@ namespace Neo.VM /// public sealed class ReferenceCounterV2 : IReferenceCounter { + public RCVersion Version { get; init; } = RCVersion.V2; + // Keeps the total count of references. private int _referencesCount = 0; diff --git a/src/Neo.VM/Types/Array.cs b/src/Neo.VM/Types/Array.cs index 903613c228..264a2a51c0 100644 --- a/src/Neo.VM/Types/Array.cs +++ b/src/Neo.VM/Types/Array.cs @@ -75,8 +75,7 @@ public Array(IReferenceCounter? referenceCounter, IEnumerable? items List list => list, _ => new List(items) }; - - if (referenceCounter == null) return; + if (referenceCounter == null || referenceCounter.Version == RCVersion.V2) return; foreach (var item in _array) { diff --git a/src/Neo.VM/Types/CompoundType.cs b/src/Neo.VM/Types/CompoundType.cs index 59a30fcb42..4504b468d1 100644 --- a/src/Neo.VM/Types/CompoundType.cs +++ b/src/Neo.VM/Types/CompoundType.cs @@ -32,8 +32,13 @@ public abstract class CompoundType : StackItem /// The reference counter to be used. protected CompoundType(IReferenceCounter? referenceCounter = null) { - ReferenceCounter = referenceCounter; - referenceCounter?.AddZeroReferred(this); + if (referenceCounter is { Version: RCVersion.V2 }) + ReferenceCounter = null; + else + { + ReferenceCounter = referenceCounter; + referenceCounter?.AddZeroReferred(this); + } } /// diff --git a/tests/Neo.VM.Tests/UT_EvaluationStack.cs b/tests/Neo.VM.Tests/UT_EvaluationStack.cs index fb1f5e5813..6aa15ea209 100644 --- a/tests/Neo.VM.Tests/UT_EvaluationStack.cs +++ b/tests/Neo.VM.Tests/UT_EvaluationStack.cs @@ -25,7 +25,7 @@ public class UT_EvaluationStack private static EvaluationStack CreateOrderedStack(int count) { var check = new Integer[count]; - var stack = new EvaluationStack(new ReferenceCounter()); + var stack = new EvaluationStack(new ReferenceCounterV2()); for (int x = 1; x <= count; x++) { @@ -56,7 +56,7 @@ public void TestClear() public void TestCopyTo() { var stack = CreateOrderedStack(3); - var copy = new EvaluationStack(new ReferenceCounter()); + var copy = new EvaluationStack(new ReferenceCounterV2()); Assert.ThrowsException(() => stack.CopyTo(copy, -2)); Assert.ThrowsException(() => stack.CopyTo(copy, 4)); @@ -93,7 +93,7 @@ public void TestCopyTo() public void TestMoveTo() { var stack = CreateOrderedStack(3); - var other = new EvaluationStack(new ReferenceCounter()); + var other = new EvaluationStack(new ReferenceCounterV2()); stack.MoveTo(other, 0); @@ -126,7 +126,7 @@ public void TestMoveTo() [TestMethod] public void TestInsertPeek() { - var stack = new EvaluationStack(new ReferenceCounter()); + var stack = new EvaluationStack(new ReferenceCounterV2()); stack.Insert(0, 3); stack.Insert(1, 1); @@ -203,7 +203,7 @@ public void TestReverse() [TestMethod] public void TestEvaluationStackPrint() { - var stack = new EvaluationStack(new ReferenceCounter()); + var stack = new EvaluationStack(new ReferenceCounterV2()); stack.Insert(0, 3); stack.Insert(1, 1); @@ -216,7 +216,7 @@ public void TestEvaluationStackPrint() [TestMethod] public void TestPrintInvalidUTF8() { - var stack = new EvaluationStack(new ReferenceCounter()); + var stack = new EvaluationStack(new ReferenceCounterV2()); stack.Insert(0, "4CC95219999D421243C8161E3FC0F4290C067845".FromHexString()); Assert.AreEqual("[ByteString(\"Base64: TMlSGZmdQhJDyBYeP8D0KQwGeEU=\")]", stack.ToString()); } From 0ccd831e2fc7dc0f42cbcda25c0eedd6832f7bd6 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Sun, 17 Nov 2024 23:47:39 +0800 Subject: [PATCH 08/36] avoid change that is currently not necessary --- src/Neo/Network/P2P/Payloads/Transaction.cs | 2 +- src/Neo/Network/P2P/Payloads/WitnessRule.cs | 2 +- src/Neo/SmartContract/ContractState.cs | 2 +- src/Neo/SmartContract/Manifest/ContractAbi.cs | 2 +- src/Neo/SmartContract/Manifest/ContractGroup.cs | 2 +- src/Neo/SmartContract/Manifest/ContractManifest.cs | 2 +- src/Neo/SmartContract/Manifest/ContractParameterDefinition.cs | 2 +- src/Neo/SmartContract/Manifest/ContractPermission.cs | 2 +- src/Neo/SmartContract/Native/InteroperableList.cs | 2 +- src/Neo/SmartContract/Native/NeoToken.cs | 2 +- src/Neo/SmartContract/Native/OracleRequest.cs | 2 +- src/Neo/SmartContract/NotifyEventArgs.cs | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Neo/Network/P2P/Payloads/Transaction.cs b/src/Neo/Network/P2P/Payloads/Transaction.cs index 310ceb7c9d..b5139f1c7c 100644 --- a/src/Neo/Network/P2P/Payloads/Transaction.cs +++ b/src/Neo/Network/P2P/Payloads/Transaction.cs @@ -459,7 +459,7 @@ public virtual VerifyResult VerifyStateIndependent(ProtocolSettings settings) return VerifyResult.Succeed; } - public StackItem ToStackItem(IReferenceCounter referenceCounter = null) + public StackItem ToStackItem(IReferenceCounter referenceCounter) { if (_signers == null || _signers.Length == 0) throw new ArgumentException("Sender is not specified in the transaction."); return new Array(referenceCounter, new StackItem[] diff --git a/src/Neo/Network/P2P/Payloads/WitnessRule.cs b/src/Neo/Network/P2P/Payloads/WitnessRule.cs index 473d6d64ee..08ab3911b2 100644 --- a/src/Neo/Network/P2P/Payloads/WitnessRule.cs +++ b/src/Neo/Network/P2P/Payloads/WitnessRule.cs @@ -110,7 +110,7 @@ void IInteroperable.FromStackItem(StackItem stackItem) throw new NotSupportedException(); } - public StackItem ToStackItem(IReferenceCounter referenceCounter = null) + public StackItem ToStackItem(IReferenceCounter referenceCounter) { return new VM.Types.Array(referenceCounter, new StackItem[] { diff --git a/src/Neo/SmartContract/ContractState.cs b/src/Neo/SmartContract/ContractState.cs index c19e7a0fdc..cd065cb8c3 100644 --- a/src/Neo/SmartContract/ContractState.cs +++ b/src/Neo/SmartContract/ContractState.cs @@ -119,7 +119,7 @@ public JObject ToJson() }; } - public StackItem ToStackItem(IReferenceCounter referenceCounter = null) + public StackItem ToStackItem(IReferenceCounter referenceCounter) { return new Array(referenceCounter, new StackItem[] { Id, (int)UpdateCounter, Hash.ToArray(), Nef.ToArray(), Manifest.ToStackItem(referenceCounter) }); } diff --git a/src/Neo/SmartContract/Manifest/ContractAbi.cs b/src/Neo/SmartContract/Manifest/ContractAbi.cs index ecbf9d9b41..4517ffeed2 100644 --- a/src/Neo/SmartContract/Manifest/ContractAbi.cs +++ b/src/Neo/SmartContract/Manifest/ContractAbi.cs @@ -44,7 +44,7 @@ void IInteroperable.FromStackItem(StackItem stackItem) Events = ((Array)@struct[1]).Select(p => p.ToInteroperable()).ToArray(); } - public StackItem ToStackItem(IReferenceCounter referenceCounter = null) + public StackItem ToStackItem(IReferenceCounter referenceCounter) { return new Struct(referenceCounter) { diff --git a/src/Neo/SmartContract/Manifest/ContractGroup.cs b/src/Neo/SmartContract/Manifest/ContractGroup.cs index c7f378b032..8796c0f07a 100644 --- a/src/Neo/SmartContract/Manifest/ContractGroup.cs +++ b/src/Neo/SmartContract/Manifest/ContractGroup.cs @@ -43,7 +43,7 @@ void IInteroperable.FromStackItem(StackItem stackItem) Signature = @struct[1].GetSpan().ToArray(); } - public StackItem ToStackItem(IReferenceCounter referenceCounter = null) + public StackItem ToStackItem(IReferenceCounter referenceCounter) { return new Struct(referenceCounter) { PubKey.ToArray(), Signature }; } diff --git a/src/Neo/SmartContract/Manifest/ContractManifest.cs b/src/Neo/SmartContract/Manifest/ContractManifest.cs index d48b95ee36..17722eb48a 100644 --- a/src/Neo/SmartContract/Manifest/ContractManifest.cs +++ b/src/Neo/SmartContract/Manifest/ContractManifest.cs @@ -88,7 +88,7 @@ void IInteroperable.FromStackItem(StackItem stackItem) Extra = (JObject)JToken.Parse(@struct[7].GetSpan()); } - public StackItem ToStackItem(IReferenceCounter referenceCounter = null) + public StackItem ToStackItem(IReferenceCounter referenceCounter) { return new Struct(referenceCounter) { diff --git a/src/Neo/SmartContract/Manifest/ContractParameterDefinition.cs b/src/Neo/SmartContract/Manifest/ContractParameterDefinition.cs index 217f695cb2..7579dd54e6 100644 --- a/src/Neo/SmartContract/Manifest/ContractParameterDefinition.cs +++ b/src/Neo/SmartContract/Manifest/ContractParameterDefinition.cs @@ -39,7 +39,7 @@ void IInteroperable.FromStackItem(StackItem stackItem) Type = (ContractParameterType)(byte)@struct[1].GetInteger(); } - public StackItem ToStackItem(IReferenceCounter referenceCounter = null) + public StackItem ToStackItem(IReferenceCounter referenceCounter) { return new Struct(referenceCounter) { Name, (byte)Type }; } diff --git a/src/Neo/SmartContract/Manifest/ContractPermission.cs b/src/Neo/SmartContract/Manifest/ContractPermission.cs index 23362729f9..cf4d5078c5 100644 --- a/src/Neo/SmartContract/Manifest/ContractPermission.cs +++ b/src/Neo/SmartContract/Manifest/ContractPermission.cs @@ -68,7 +68,7 @@ void IInteroperable.FromStackItem(StackItem stackItem) }; } - public StackItem ToStackItem(IReferenceCounter referenceCounter = null) + public StackItem ToStackItem(IReferenceCounter referenceCounter) { return new Struct(referenceCounter) { diff --git a/src/Neo/SmartContract/Native/InteroperableList.cs b/src/Neo/SmartContract/Native/InteroperableList.cs index 269710eefa..09088f6156 100644 --- a/src/Neo/SmartContract/Native/InteroperableList.cs +++ b/src/Neo/SmartContract/Native/InteroperableList.cs @@ -51,7 +51,7 @@ public void FromStackItem(StackItem stackItem) } } - public StackItem ToStackItem(IReferenceCounter referenceCounter = null) + public StackItem ToStackItem(IReferenceCounter referenceCounter) { return new Array(referenceCounter, this.Select(p => ElementToStackItem(p, referenceCounter))); } diff --git a/src/Neo/SmartContract/Native/NeoToken.cs b/src/Neo/SmartContract/Native/NeoToken.cs index ef3f8d5d2d..f1b267b8eb 100644 --- a/src/Neo/SmartContract/Native/NeoToken.cs +++ b/src/Neo/SmartContract/Native/NeoToken.cs @@ -603,7 +603,7 @@ public void FromStackItem(StackItem stackItem) Votes = @struct[1].GetInteger(); } - public StackItem ToStackItem(IReferenceCounter referenceCounter = null) + public StackItem ToStackItem(IReferenceCounter referenceCounter) { return new Struct(referenceCounter) { Registered, Votes }; } diff --git a/src/Neo/SmartContract/Native/OracleRequest.cs b/src/Neo/SmartContract/Native/OracleRequest.cs index 864939f204..cd4962b1cb 100644 --- a/src/Neo/SmartContract/Native/OracleRequest.cs +++ b/src/Neo/SmartContract/Native/OracleRequest.cs @@ -68,7 +68,7 @@ public void FromStackItem(StackItem stackItem) UserData = array[6].GetSpan().ToArray(); } - public StackItem ToStackItem(IReferenceCounter referenceCounter = null) + public StackItem ToStackItem(IReferenceCounter referenceCounter) { return new Array(referenceCounter) { diff --git a/src/Neo/SmartContract/NotifyEventArgs.cs b/src/Neo/SmartContract/NotifyEventArgs.cs index 02441a8c55..8d8542bca9 100644 --- a/src/Neo/SmartContract/NotifyEventArgs.cs +++ b/src/Neo/SmartContract/NotifyEventArgs.cs @@ -63,7 +63,7 @@ public void FromStackItem(StackItem stackItem) throw new NotSupportedException(); } - public StackItem ToStackItem(IReferenceCounter referenceCounter = null) + public StackItem ToStackItem(IReferenceCounter referenceCounter) { return new Array(referenceCounter) { From fc8df976a20fb6bab205414545d2aee8852bee9c Mon Sep 17 00:00:00 2001 From: Jimmy Date: Sun, 17 Nov 2024 23:48:53 +0800 Subject: [PATCH 09/36] revert null default --- src/Neo/Network/P2P/Payloads/Conditions/AndCondition.cs | 2 +- src/Neo/Network/P2P/Payloads/Conditions/BooleanCondition.cs | 2 +- .../P2P/Payloads/Conditions/CalledByContractCondition.cs | 2 +- .../Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs | 2 +- src/Neo/Network/P2P/Payloads/Conditions/GroupCondition.cs | 2 +- src/Neo/Network/P2P/Payloads/Conditions/NotCondition.cs | 2 +- src/Neo/Network/P2P/Payloads/Conditions/OrCondition.cs | 2 +- src/Neo/Network/P2P/Payloads/Conditions/ScriptHashCondition.cs | 2 +- src/Neo/SmartContract/Manifest/ContractMethodDescriptor.cs | 2 +- src/Neo/SmartContract/Native/NeoToken.cs | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Neo/Network/P2P/Payloads/Conditions/AndCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/AndCondition.cs index 975e2ec89d..0c8df2ddb7 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/AndCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/AndCondition.cs @@ -91,7 +91,7 @@ public override JObject ToJson() return json; } - public override StackItem ToStackItem(IReferenceCounter referenceCounter = null) + public override StackItem ToStackItem(IReferenceCounter referenceCounter) { var result = (VM.Types.Array)base.ToStackItem(referenceCounter); result.Add(new VM.Types.Array(referenceCounter, Expressions.Select(p => p.ToStackItem(referenceCounter)))); diff --git a/src/Neo/Network/P2P/Payloads/Conditions/BooleanCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/BooleanCondition.cs index dcde0de28c..4299bae04b 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/BooleanCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/BooleanCondition.cs @@ -80,7 +80,7 @@ public override JObject ToJson() return json; } - public override StackItem ToStackItem(IReferenceCounter referenceCounter = null) + public override StackItem ToStackItem(IReferenceCounter referenceCounter) { var result = (VM.Types.Array)base.ToStackItem(referenceCounter); result.Add(Expression); diff --git a/src/Neo/Network/P2P/Payloads/Conditions/CalledByContractCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/CalledByContractCondition.cs index 08a26903f7..4ce1e2dc1f 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/CalledByContractCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/CalledByContractCondition.cs @@ -80,7 +80,7 @@ public override JObject ToJson() return json; } - public override StackItem ToStackItem(IReferenceCounter referenceCounter = null) + public override StackItem ToStackItem(IReferenceCounter referenceCounter) { var result = (VM.Types.Array)base.ToStackItem(referenceCounter); result.Add(Hash.ToArray()); diff --git a/src/Neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs index 623fdc2e55..ac233a156a 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs @@ -85,7 +85,7 @@ public override JObject ToJson() return json; } - public override StackItem ToStackItem(IReferenceCounter referenceCounter = null) + public override StackItem ToStackItem(IReferenceCounter referenceCounter) { var result = (VM.Types.Array)base.ToStackItem(referenceCounter); result.Add(Group.ToArray()); diff --git a/src/Neo/Network/P2P/Payloads/Conditions/GroupCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/GroupCondition.cs index a9c3885c69..18e94fbc40 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/GroupCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/GroupCondition.cs @@ -85,7 +85,7 @@ public override JObject ToJson() return json; } - public override StackItem ToStackItem(IReferenceCounter referenceCounter = null) + public override StackItem ToStackItem(IReferenceCounter referenceCounter) { var result = (VM.Types.Array)base.ToStackItem(referenceCounter); result.Add(Group.ToArray()); diff --git a/src/Neo/Network/P2P/Payloads/Conditions/NotCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/NotCondition.cs index 0db660dadd..fd813c7230 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/NotCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/NotCondition.cs @@ -85,7 +85,7 @@ public override JObject ToJson() return json; } - public override StackItem ToStackItem(IReferenceCounter referenceCounter = null) + public override StackItem ToStackItem(IReferenceCounter referenceCounter) { var result = (VM.Types.Array)base.ToStackItem(referenceCounter); result.Add(Expression.ToStackItem(referenceCounter)); diff --git a/src/Neo/Network/P2P/Payloads/Conditions/OrCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/OrCondition.cs index 624b5eac75..177fb949fe 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/OrCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/OrCondition.cs @@ -91,7 +91,7 @@ public override JObject ToJson() return json; } - public override StackItem ToStackItem(IReferenceCounter referenceCounter = null) + public override StackItem ToStackItem(IReferenceCounter referenceCounter) { var result = (VM.Types.Array)base.ToStackItem(referenceCounter); result.Add(new VM.Types.Array(referenceCounter, Expressions.Select(p => p.ToStackItem(referenceCounter)))); diff --git a/src/Neo/Network/P2P/Payloads/Conditions/ScriptHashCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/ScriptHashCondition.cs index dc06fb64a6..a9cf1de0e9 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/ScriptHashCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/ScriptHashCondition.cs @@ -80,7 +80,7 @@ public override JObject ToJson() return json; } - public override StackItem ToStackItem(IReferenceCounter referenceCounter = null) + public override StackItem ToStackItem(IReferenceCounter referenceCounter) { var result = (VM.Types.Array)base.ToStackItem(referenceCounter); result.Add(Hash.ToArray()); diff --git a/src/Neo/SmartContract/Manifest/ContractMethodDescriptor.cs b/src/Neo/SmartContract/Manifest/ContractMethodDescriptor.cs index b6b320fc84..6c024dc179 100644 --- a/src/Neo/SmartContract/Manifest/ContractMethodDescriptor.cs +++ b/src/Neo/SmartContract/Manifest/ContractMethodDescriptor.cs @@ -48,7 +48,7 @@ public override void FromStackItem(StackItem stackItem) Safe = @struct[4].GetBoolean(); } - public override StackItem ToStackItem(IReferenceCounter referenceCounter = null) + public override StackItem ToStackItem(IReferenceCounter referenceCounter) { Struct @struct = (Struct)base.ToStackItem(referenceCounter); @struct.Add((byte)ReturnType); diff --git a/src/Neo/SmartContract/Native/NeoToken.cs b/src/Neo/SmartContract/Native/NeoToken.cs index f1b267b8eb..85309b4246 100644 --- a/src/Neo/SmartContract/Native/NeoToken.cs +++ b/src/Neo/SmartContract/Native/NeoToken.cs @@ -581,7 +581,7 @@ public override void FromStackItem(StackItem stackItem) LastGasPerVote = @struct[3].GetInteger(); } - public override StackItem ToStackItem(IReferenceCounter referenceCounter = null) + public override StackItem ToStackItem(IReferenceCounter referenceCounter) { Struct @struct = (Struct)base.ToStackItem(referenceCounter); @struct.Add(BalanceHeight); From 6acfc2c4d861f89c64ee5ec3a3b2e095f9f65251 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Sun, 17 Nov 2024 23:52:06 +0800 Subject: [PATCH 10/36] revert null default --- src/Neo/Network/P2P/Payloads/Conditions/WitnessCondition.cs | 2 +- src/Neo/Network/P2P/Payloads/Signer.cs | 2 +- src/Neo/SmartContract/Manifest/ContractEventDescriptor.cs | 2 +- src/Neo/SmartContract/Native/AccountState.cs | 2 +- src/Neo/SmartContract/Native/HashIndexState.cs | 2 +- src/Neo/SmartContract/Native/TransactionState.cs | 2 +- src/Neo/SmartContract/Native/TrimmedBlock.cs | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Neo/Network/P2P/Payloads/Conditions/WitnessCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/WitnessCondition.cs index 05dcc8be03..5fb5808714 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/WitnessCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/WitnessCondition.cs @@ -132,7 +132,7 @@ void IInteroperable.FromStackItem(StackItem stackItem) throw new NotSupportedException(); } - public virtual StackItem ToStackItem(IReferenceCounter referenceCounter = null) + public virtual StackItem ToStackItem(IReferenceCounter referenceCounter) { return new VM.Types.Array(referenceCounter, new StackItem[] { (byte)Type }); } diff --git a/src/Neo/Network/P2P/Payloads/Signer.cs b/src/Neo/Network/P2P/Payloads/Signer.cs index ed87de9162..40496dfe74 100644 --- a/src/Neo/Network/P2P/Payloads/Signer.cs +++ b/src/Neo/Network/P2P/Payloads/Signer.cs @@ -191,7 +191,7 @@ void IInteroperable.FromStackItem(VM.Types.StackItem stackItem) throw new NotSupportedException(); } - VM.Types.StackItem IInteroperable.ToStackItem(IReferenceCounter referenceCounter = null) + VM.Types.StackItem IInteroperable.ToStackItem(IReferenceCounter referenceCounter) { return new VM.Types.Array(referenceCounter, [ diff --git a/src/Neo/SmartContract/Manifest/ContractEventDescriptor.cs b/src/Neo/SmartContract/Manifest/ContractEventDescriptor.cs index bbf60e86d2..9a3eabab06 100644 --- a/src/Neo/SmartContract/Manifest/ContractEventDescriptor.cs +++ b/src/Neo/SmartContract/Manifest/ContractEventDescriptor.cs @@ -41,7 +41,7 @@ public virtual void FromStackItem(StackItem stackItem) Parameters = ((Array)@struct[1]).Select(p => p.ToInteroperable()).ToArray(); } - public virtual StackItem ToStackItem(IReferenceCounter referenceCounter = null) + public virtual StackItem ToStackItem(IReferenceCounter referenceCounter) { return new Struct(referenceCounter) { diff --git a/src/Neo/SmartContract/Native/AccountState.cs b/src/Neo/SmartContract/Native/AccountState.cs index 312a7cf414..4e8944ab73 100644 --- a/src/Neo/SmartContract/Native/AccountState.cs +++ b/src/Neo/SmartContract/Native/AccountState.cs @@ -30,7 +30,7 @@ public virtual void FromStackItem(StackItem stackItem) Balance = ((Struct)stackItem)[0].GetInteger(); } - public virtual StackItem ToStackItem(IReferenceCounter referenceCounter = null) + public virtual StackItem ToStackItem(IReferenceCounter referenceCounter) { return new Struct(referenceCounter) { Balance }; } diff --git a/src/Neo/SmartContract/Native/HashIndexState.cs b/src/Neo/SmartContract/Native/HashIndexState.cs index c008c4bf27..4ab7a991cf 100644 --- a/src/Neo/SmartContract/Native/HashIndexState.cs +++ b/src/Neo/SmartContract/Native/HashIndexState.cs @@ -27,7 +27,7 @@ void IInteroperable.FromStackItem(StackItem stackItem) Index = (uint)@struct[1].GetInteger(); } - StackItem IInteroperable.ToStackItem(IReferenceCounter referenceCounter = null) + StackItem IInteroperable.ToStackItem(IReferenceCounter referenceCounter) { return new Struct(referenceCounter) { Hash.ToArray(), Index }; } diff --git a/src/Neo/SmartContract/Native/TransactionState.cs b/src/Neo/SmartContract/Native/TransactionState.cs index f27103c970..9e3eb2527a 100644 --- a/src/Neo/SmartContract/Native/TransactionState.cs +++ b/src/Neo/SmartContract/Native/TransactionState.cs @@ -76,7 +76,7 @@ void IInteroperable.FromStackItem(StackItem stackItem) State = (VMState)(byte)@struct[2].GetInteger(); } - StackItem IInteroperable.ToStackItem(IReferenceCounter referenceCounter = null) + StackItem IInteroperable.ToStackItem(IReferenceCounter referenceCounter) { if (Transaction is null) return new Struct(referenceCounter) { BlockIndex }; diff --git a/src/Neo/SmartContract/Native/TrimmedBlock.cs b/src/Neo/SmartContract/Native/TrimmedBlock.cs index a11880fc52..69dd55fdbb 100644 --- a/src/Neo/SmartContract/Native/TrimmedBlock.cs +++ b/src/Neo/SmartContract/Native/TrimmedBlock.cs @@ -80,7 +80,7 @@ void IInteroperable.FromStackItem(StackItem stackItem) throw new NotSupportedException(); } - StackItem IInteroperable.ToStackItem(IReferenceCounter referenceCounter = null) + StackItem IInteroperable.ToStackItem(IReferenceCounter referenceCounter) { return new VM.Types.Array(referenceCounter, new StackItem[] { From 2d6deabc23f8e7456faea0b41b9e29239b95111f Mon Sep 17 00:00:00 2001 From: Jimmy Date: Sun, 17 Nov 2024 23:52:56 +0800 Subject: [PATCH 11/36] revert null --- src/Neo/SmartContract/IInteroperable.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Neo/SmartContract/IInteroperable.cs b/src/Neo/SmartContract/IInteroperable.cs index a3c3e273ae..f177b3f76f 100644 --- a/src/Neo/SmartContract/IInteroperable.cs +++ b/src/Neo/SmartContract/IInteroperable.cs @@ -31,7 +31,7 @@ public interface IInteroperable /// /// The used by the . /// The converted . - StackItem ToStackItem(IReferenceCounter referenceCounter = null); + StackItem ToStackItem(IReferenceCounter referenceCounter); public IInteroperable Clone() { From 6200bdbe84678fe5c4576e597e044fff3981168e Mon Sep 17 00:00:00 2001 From: Jimmy Date: Mon, 18 Nov 2024 00:24:19 +0800 Subject: [PATCH 12/36] apply compound update and apply hardfork --- src/Neo.VM/ExecutionEngine.cs | 23 ++++++-------- src/Neo.VM/JumpTable/JumpTable.Compound.cs | 37 ++++++++++++++++++++++ src/Neo/SmartContract/ApplicationEngine.cs | 1 + 3 files changed, 48 insertions(+), 13 deletions(-) diff --git a/src/Neo.VM/ExecutionEngine.cs b/src/Neo.VM/ExecutionEngine.cs index 025650a952..5783e262c0 100644 --- a/src/Neo.VM/ExecutionEngine.cs +++ b/src/Neo.VM/ExecutionEngine.cs @@ -34,10 +34,7 @@ public class ExecutionEngine : IDisposable /// /// Used for reference counting of objects in the VM. /// - [Obsolete("ReferenceCounter will not be visible in a future release.")] - public IReferenceCounter ReferenceCounter => _referenceCounter; - - private readonly IReferenceCounter _referenceCounter; + public IReferenceCounter ReferenceCounter { get; set; } /// /// The invocation stack of the VM. @@ -86,7 +83,7 @@ protected internal set /// /// Initializes a new instance of the class. /// - /// The reference counter to be used. + /// The reference counter to be used. /// referenceCounter is shared cross ExecutionContexts. /// The jump table to be used. public ExecutionEngine(IReferenceCounter referenceCounter, JumpTable? jumpTable = null) @@ -116,7 +113,7 @@ protected ExecutionEngine(JumpTable? jumpTable, IReferenceCounter referenceCount { JumpTable = jumpTable ?? JumpTable.Default; Limits = limits; - _referenceCounter = referenceCounter; + ReferenceCounter = referenceCounter; ResultStack = new EvaluationStack(referenceCounter); } @@ -227,7 +224,7 @@ internal virtual void UnloadContext(ExecutionContext context) [MethodImpl(MethodImplOptions.AggressiveInlining)] protected ExecutionContext CreateContext(Script script, int rvcount, int initialPosition) { - return new ExecutionContext(script, rvcount, _referenceCounter) + return new ExecutionContext(script, rvcount, ReferenceCounter) { InstructionPointer = initialPosition }; @@ -307,16 +304,16 @@ public T Pop() where T : StackItem /// protected virtual void PostExecuteInstruction(Instruction instruction) { - if (_referenceCounter.Version == RCVersion.V1) + if (ReferenceCounter.Version == RCVersion.V1) { - if (_referenceCounter.Count < Limits.MaxStackSize) return; - if (_referenceCounter.CheckZeroReferred() > Limits.MaxStackSize) - throw new InvalidOperationException($"MaxStackSize exceed: {_referenceCounter.Count}"); + if (ReferenceCounter.Count < Limits.MaxStackSize) return; + if (ReferenceCounter.CheckZeroReferred() > Limits.MaxStackSize) + throw new InvalidOperationException($"MaxStackSize exceed: {ReferenceCounter.Count}"); } else { - if (_referenceCounter.Count <= Limits.MaxStackSize) return; - throw new InvalidOperationException($"MaxStackSize exceed: {_referenceCounter.Count}"); + if (ReferenceCounter.Count <= Limits.MaxStackSize) return; + throw new InvalidOperationException($"MaxStackSize exceed: {ReferenceCounter.Count}"); } } diff --git a/src/Neo.VM/JumpTable/JumpTable.Compound.cs b/src/Neo.VM/JumpTable/JumpTable.Compound.cs index 2447edfa35..1307589ce4 100644 --- a/src/Neo.VM/JumpTable/JumpTable.Compound.cs +++ b/src/Neo.VM/JumpTable/JumpTable.Compound.cs @@ -422,6 +422,8 @@ public virtual void Append(ExecutionEngine engine, Instruction instruction) var array = engine.Pop(); if (newItem is Struct s) newItem = s.Clone(engine.Limits); array.Add(newItem); + if (engine.ReferenceCounter.Version == RCVersion.V2) + engine.ReferenceCounter.AddStackReference(newItem); } /// @@ -445,12 +447,30 @@ public virtual void SetItem(ExecutionEngine engine, Instruction instruction) var index = (int)key.GetInteger(); if (index < 0 || index >= array.Count) throw new CatchableException($"The value {index} is out of range."); + if (engine.ReferenceCounter.Version == RCVersion.V2) + engine.ReferenceCounter.RemoveStackReference(array[index]); array[index] = value; + if (engine.ReferenceCounter.Version == RCVersion.V2) + engine.ReferenceCounter.AddStackReference(array[index]); break; } case Map map: { + if (engine.ReferenceCounter.Version == RCVersion.V2) + { + if (!map.TryGetValue(key, out var value1)) + { + engine.ReferenceCounter.AddStackReference(key); + } + else + { + engine.ReferenceCounter.RemoveStackReference(value1); + } + } + map[key] = value; + if (engine.ReferenceCounter.Version == RCVersion.V2) + engine.ReferenceCounter.AddStackReference(value); break; } case Types.Buffer buffer: @@ -515,9 +535,18 @@ public virtual void Remove(ExecutionEngine engine, Instruction instruction) var index = (int)key.GetInteger(); if (index < 0 || index >= array.Count) throw new InvalidOperationException($"The value {index} is out of range."); + var item = array[index]; array.RemoveAt(index); + if (engine.ReferenceCounter.Version == RCVersion.V2) + engine.ReferenceCounter.RemoveStackReference(item); break; case Map map: + if (engine.ReferenceCounter.Version == RCVersion.V2) + { + engine.ReferenceCounter.RemoveStackReference(key); + engine.ReferenceCounter.RemoveStackReference(map[key]); + } + map.Remove(key); break; default: @@ -536,6 +565,14 @@ public virtual void Remove(ExecutionEngine engine, Instruction instruction) public virtual void ClearItems(ExecutionEngine engine, Instruction instruction) { var x = engine.Pop(); + if (engine.ReferenceCounter.Version == RCVersion.V2) + { + foreach (var xSubItem in x.SubItems) + { + engine.ReferenceCounter.RemoveStackReference(xSubItem); + } + } + x.Clear(); } diff --git a/src/Neo/SmartContract/ApplicationEngine.cs b/src/Neo/SmartContract/ApplicationEngine.cs index 7808baae5e..b1c268107a 100644 --- a/src/Neo/SmartContract/ApplicationEngine.cs +++ b/src/Neo/SmartContract/ApplicationEngine.cs @@ -182,6 +182,7 @@ protected unsafe ApplicationEngine( ProtocolSettings settings, long gas, IDiagnostic diagnostic, JumpTable jumpTable = null) : base(jumpTable ?? DefaultJumpTable) { + ReferenceCounter = IsHardforkEnabled(Hardfork.HF_Echidna) ? new ReferenceCounterV2() : new ReferenceCounter(); Trigger = trigger; ScriptContainer = container; originalSnapshotCache = snapshotCache; From 06fc01620864f22bb3202b5151e39922165adc44 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Mon, 18 Nov 2024 00:25:18 +0800 Subject: [PATCH 13/36] fix stack --- src/Neo.VM/EvaluationStack.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Neo.VM/EvaluationStack.cs b/src/Neo.VM/EvaluationStack.cs index c26d295666..463df8d12a 100644 --- a/src/Neo.VM/EvaluationStack.cs +++ b/src/Neo.VM/EvaluationStack.cs @@ -13,7 +13,6 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Runtime.CompilerServices; @@ -29,12 +28,7 @@ public sealed class EvaluationStack : IReadOnlyList internal IReferenceCounter ReferenceCounter => referenceCounter; - /// - /// Initializes a new instance of the class. - /// - /// The reference counter. Cannot be null. - /// Keep the NotNull attribute to explicitly announce that the reference counter cannot be null. - internal EvaluationStack([NotNull] IReferenceCounter referenceCounter) + internal EvaluationStack(IReferenceCounter referenceCounter) { this.referenceCounter = referenceCounter; } From 4bb8043a4e260b7bd0809a129885d569b414f0fd Mon Sep 17 00:00:00 2001 From: Jimmy Date: Mon, 18 Nov 2024 01:14:38 +0800 Subject: [PATCH 14/36] fix applicationengine rc version issue --- .../VMTypes/Benchmarks_Convert.cs | 2 +- .../VMTypes/Benchmarks_DeepCopy.cs | 8 ++++---- src/Neo/SmartContract/ApplicationEngine.cs | 17 +++++++++++------ .../Manifest/UT_ContractManifest.cs | 4 ++-- tests/Neo.VM.Tests/UT_ExecutionContext.cs | 2 +- tests/Neo.VM.Tests/UT_ReferenceCounter.cs | 2 +- tests/Neo.VM.Tests/UT_Slot.cs | 2 +- 7 files changed, 21 insertions(+), 16 deletions(-) diff --git a/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_Convert.cs b/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_Convert.cs index de71f3332d..de5e2cd187 100644 --- a/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_Convert.cs +++ b/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_Convert.cs @@ -60,7 +60,7 @@ public IEnumerable GetTypeConversionPairs() private Dictionary> CreateTestItemsByType() { - var referenceCounter = new ReferenceCounter(); + var referenceCounter = new ReferenceCounterV2(); var result = new Dictionary>(); foreach (StackItemType type in Enum.GetValues(typeof(StackItemType))) diff --git a/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopy.cs b/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopy.cs index 4cef2e555f..868c91add1 100644 --- a/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopy.cs +++ b/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopy.cs @@ -39,7 +39,7 @@ public class Benchmarks_DeepCopy [Benchmark] public void BenchNestedArrayDeepCopy() { - var root = new Array(new ReferenceCounter()); + var root = new Array(new ReferenceCounterV2()); CreateNestedArray(root, Params.Depth, Params.ElementsPerLevel); _ = root.DeepCopy(); } @@ -47,7 +47,7 @@ public void BenchNestedArrayDeepCopy() [Benchmark] public void BenchNestedArrayDeepCopyWithReferenceCounter() { - var referenceCounter = new ReferenceCounter(); + var referenceCounter = new ReferenceCounterV2(); var root = new Array(referenceCounter); CreateNestedArray(root, Params.Depth, Params.ElementsPerLevel, referenceCounter); _ = root.DeepCopy(); @@ -56,7 +56,7 @@ public void BenchNestedArrayDeepCopyWithReferenceCounter() [Benchmark] public void BenchNestedTestArrayDeepCopy() { - var root = new TestArray(new ReferenceCounter()); + var root = new TestArray(new ReferenceCounterV2()); CreateNestedTestArray(root, Params.Depth, Params.ElementsPerLevel); _ = root.DeepCopy(); } @@ -64,7 +64,7 @@ public void BenchNestedTestArrayDeepCopy() [Benchmark] public void BenchNestedTestArrayDeepCopyWithReferenceCounter() { - var referenceCounter = new ReferenceCounter(); + var referenceCounter = new ReferenceCounterV2(); var root = new TestArray(referenceCounter); CreateNestedTestArray(root, Params.Depth, Params.ElementsPerLevel, referenceCounter); _ = root.DeepCopy(); diff --git a/src/Neo/SmartContract/ApplicationEngine.cs b/src/Neo/SmartContract/ApplicationEngine.cs index b1c268107a..ca566c8601 100644 --- a/src/Neo/SmartContract/ApplicationEngine.cs +++ b/src/Neo/SmartContract/ApplicationEngine.cs @@ -180,9 +180,17 @@ public virtual UInt160 CallingScriptHash protected unsafe ApplicationEngine( TriggerType trigger, IVerifiable container, DataCache snapshotCache, Block persistingBlock, ProtocolSettings settings, long gas, IDiagnostic diagnostic, JumpTable jumpTable = null) - : base(jumpTable ?? DefaultJumpTable) + : base( + // this is IsHardforkEnabled + settings is not null + ? (persistingBlock is null + ? settings.Hardforks.ContainsKey(Hardfork.HF_Echidna) + : settings.IsHardforkEnabled(Hardfork.HF_Echidna, persistingBlock.Index)) + ? new ReferenceCounterV2() + : new ReferenceCounter() + : new ReferenceCounterV2(), + jumpTable ?? DefaultJumpTable) { - ReferenceCounter = IsHardforkEnabled(Hardfork.HF_Echidna) ? new ReferenceCounterV2() : new ReferenceCounter(); Trigger = trigger; ScriptContainer = container; originalSnapshotCache = snapshotCache; @@ -708,10 +716,7 @@ public void SetState(T state) public bool IsHardforkEnabled(Hardfork hardfork) { // Return true if PersistingBlock is null and Hardfork is enabled - if (PersistingBlock is null) - return ProtocolSettings.Hardforks.ContainsKey(hardfork); - - return ProtocolSettings.IsHardforkEnabled(hardfork, PersistingBlock.Index); + return PersistingBlock is null ? ProtocolSettings.Hardforks.ContainsKey(hardfork) : ProtocolSettings.IsHardforkEnabled(hardfork, PersistingBlock.Index); } } } diff --git a/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs b/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs index 7a44517b87..80ce2a1b54 100644 --- a/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs +++ b/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs @@ -32,7 +32,7 @@ public void TestMainnetContract() var json = @"{""name"":""Test"",""groups"":[],""features"":{},""supportedstandards"":[],""abi"":{""methods"":[{""name"":""a"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":0,""safe"":false},{""name"":""a0"",""parameters"":[],""returntype"":""Integer"",""offset"":77,""safe"":false},{""name"":""a10"",""parameters"":[],""returntype"":""Void"",""offset"":378,""safe"":false},{""name"":""a11"",""parameters"":[],""returntype"":""Void"",""offset"":398,""safe"":false},{""name"":""a12"",""parameters"":[],""returntype"":""Void"",""offset"":418,""safe"":false},{""name"":""a13"",""parameters"":[],""returntype"":""Void"",""offset"":438,""safe"":false},{""name"":""a14"",""parameters"":[],""returntype"":""Void"",""offset"":458,""safe"":false},{""name"":""a15"",""parameters"":[],""returntype"":""Void"",""offset"":478,""safe"":false},{""name"":""a16"",""parameters"":[],""returntype"":""Void"",""offset"":498,""safe"":false},{""name"":""a17"",""parameters"":[],""returntype"":""Void"",""offset"":518,""safe"":false},{""name"":""a18"",""parameters"":[],""returntype"":""Void"",""offset"":539,""safe"":false},{""name"":""a19"",""parameters"":[],""returntype"":""Void"",""offset"":560,""safe"":false},{""name"":""a20"",""parameters"":[],""returntype"":""Void"",""offset"":581,""safe"":false},{""name"":""a21"",""parameters"":[],""returntype"":""Void"",""offset"":602,""safe"":false},{""name"":""a22"",""parameters"":[],""returntype"":""Void"",""offset"":623,""safe"":false},{""name"":""a23"",""parameters"":[],""returntype"":""Void"",""offset"":644,""safe"":false},{""name"":""a24"",""parameters"":[],""returntype"":""Void"",""offset"":665,""safe"":false},{""name"":""a25"",""parameters"":[],""returntype"":""Void"",""offset"":686,""safe"":false},{""name"":""a26"",""parameters"":[],""returntype"":""Void"",""offset"":707,""safe"":false},{""name"":""a27"",""parameters"":[],""returntype"":""Void"",""offset"":728,""safe"":false},{""name"":""a28"",""parameters"":[],""returntype"":""Void"",""offset"":749,""safe"":false},{""name"":""a29"",""parameters"":[],""returntype"":""Void"",""offset"":770,""safe"":false},{""name"":""a30"",""parameters"":[],""returntype"":""Void"",""offset"":791,""safe"":false},{""name"":""a31"",""parameters"":[],""returntype"":""Void"",""offset"":812,""safe"":false},{""name"":""a32"",""parameters"":[],""returntype"":""Void"",""offset"":833,""safe"":false},{""name"":""a33"",""parameters"":[],""returntype"":""Void"",""offset"":854,""safe"":false},{""name"":""a34"",""parameters"":[],""returntype"":""Void"",""offset"":875,""safe"":false},{""name"":""a35"",""parameters"":[],""returntype"":""Void"",""offset"":896,""safe"":false},{""name"":""a36"",""parameters"":[],""returntype"":""Void"",""offset"":917,""safe"":false},{""name"":""a37"",""parameters"":[],""returntype"":""Void"",""offset"":938,""safe"":false},{""name"":""a38"",""parameters"":[],""returntype"":""Void"",""offset"":959,""safe"":false},{""name"":""a39"",""parameters"":[],""returntype"":""Void"",""offset"":980,""safe"":false},{""name"":""a40"",""parameters"":[],""returntype"":""Void"",""offset"":1001,""safe"":false},{""name"":""a41"",""parameters"":[],""returntype"":""Void"",""offset"":1022,""safe"":false},{""name"":""a42"",""parameters"":[],""returntype"":""Void"",""offset"":1043,""safe"":false},{""name"":""a43"",""parameters"":[],""returntype"":""Void"",""offset"":1064,""safe"":false},{""name"":""a44"",""parameters"":[],""returntype"":""Void"",""offset"":1085,""safe"":false},{""name"":""a45"",""parameters"":[],""returntype"":""Void"",""offset"":1106,""safe"":false},{""name"":""a46"",""parameters"":[],""returntype"":""Void"",""offset"":1127,""safe"":false},{""name"":""a47"",""parameters"":[],""returntype"":""Void"",""offset"":1148,""safe"":false},{""name"":""a48"",""parameters"":[],""returntype"":""Void"",""offset"":1169,""safe"":false},{""name"":""a49"",""parameters"":[],""returntype"":""Void"",""offset"":1190,""safe"":false},{""name"":""a50"",""parameters"":[],""returntype"":""Void"",""offset"":1211,""safe"":false},{""name"":""b"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":1232,""safe"":false},{""name"":""b0"",""parameters"":[],""returntype"":""Integer"",""offset"":1251,""safe"":false},{""name"":""b10"",""parameters"":[],""returntype"":""Void"",""offset"":1275,""safe"":false},{""name"":""b11"",""parameters"":[],""returntype"":""Void"",""offset"":1295,""safe"":false},{""name"":""b12"",""parameters"":[],""returntype"":""Void"",""offset"":1315,""safe"":false},{""name"":""b13"",""parameters"":[],""returntype"":""Void"",""offset"":1335,""safe"":false},{""name"":""b14"",""parameters"":[],""returntype"":""Void"",""offset"":1355,""safe"":false},{""name"":""b15"",""parameters"":[],""returntype"":""Void"",""offset"":1375,""safe"":false},{""name"":""b16"",""parameters"":[],""returntype"":""Void"",""offset"":1395,""safe"":false},{""name"":""b17"",""parameters"":[],""returntype"":""Void"",""offset"":1415,""safe"":false},{""name"":""b18"",""parameters"":[],""returntype"":""Void"",""offset"":1436,""safe"":false},{""name"":""b19"",""parameters"":[],""returntype"":""Void"",""offset"":1457,""safe"":false},{""name"":""b20"",""parameters"":[],""returntype"":""Void"",""offset"":1478,""safe"":false},{""name"":""b21"",""parameters"":[],""returntype"":""Void"",""offset"":1499,""safe"":false},{""name"":""b22"",""parameters"":[],""returntype"":""Void"",""offset"":1520,""safe"":false},{""name"":""b23"",""parameters"":[],""returntype"":""Void"",""offset"":1541,""safe"":false},{""name"":""b24"",""parameters"":[],""returntype"":""Void"",""offset"":1562,""safe"":false},{""name"":""b25"",""parameters"":[],""returntype"":""Void"",""offset"":1583,""safe"":false},{""name"":""b26"",""parameters"":[],""returntype"":""Void"",""offset"":1604,""safe"":false},{""name"":""b27"",""parameters"":[],""returntype"":""Void"",""offset"":1625,""safe"":false},{""name"":""b28"",""parameters"":[],""returntype"":""Void"",""offset"":1646,""safe"":false},{""name"":""b29"",""parameters"":[],""returntype"":""Void"",""offset"":1667,""safe"":false},{""name"":""b30"",""parameters"":[],""returntype"":""Void"",""offset"":1688,""safe"":false},{""name"":""b31"",""parameters"":[],""returntype"":""Void"",""offset"":1709,""safe"":false},{""name"":""b32"",""parameters"":[],""returntype"":""Void"",""offset"":1730,""safe"":false},{""name"":""b33"",""parameters"":[],""returntype"":""Void"",""offset"":1751,""safe"":false},{""name"":""b34"",""parameters"":[],""returntype"":""Void"",""offset"":1772,""safe"":false},{""name"":""b35"",""parameters"":[],""returntype"":""Void"",""offset"":1793,""safe"":false},{""name"":""b36"",""parameters"":[],""returntype"":""Void"",""offset"":1814,""safe"":false},{""name"":""b37"",""parameters"":[],""returntype"":""Void"",""offset"":1835,""safe"":false},{""name"":""b38"",""parameters"":[],""returntype"":""Void"",""offset"":1856,""safe"":false},{""name"":""b39"",""parameters"":[],""returntype"":""Void"",""offset"":1877,""safe"":false},{""name"":""b40"",""parameters"":[],""returntype"":""Void"",""offset"":1898,""safe"":false},{""name"":""b41"",""parameters"":[],""returntype"":""Void"",""offset"":1919,""safe"":false},{""name"":""b42"",""parameters"":[],""returntype"":""Void"",""offset"":1940,""safe"":false},{""name"":""b43"",""parameters"":[],""returntype"":""Void"",""offset"":1961,""safe"":false},{""name"":""b44"",""parameters"":[],""returntype"":""Void"",""offset"":1982,""safe"":false},{""name"":""b45"",""parameters"":[],""returntype"":""Void"",""offset"":2003,""safe"":false},{""name"":""b46"",""parameters"":[],""returntype"":""Void"",""offset"":2024,""safe"":false},{""name"":""b47"",""parameters"":[],""returntype"":""Void"",""offset"":2045,""safe"":false},{""name"":""b48"",""parameters"":[],""returntype"":""Void"",""offset"":2066,""safe"":false},{""name"":""b49"",""parameters"":[],""returntype"":""Void"",""offset"":2087,""safe"":false},{""name"":""b50"",""parameters"":[],""returntype"":""Void"",""offset"":2108,""safe"":false},{""name"":""c"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":2129,""safe"":false},{""name"":""c0"",""parameters"":[],""returntype"":""Integer"",""offset"":2148,""safe"":false},{""name"":""c10"",""parameters"":[],""returntype"":""Void"",""offset"":2172,""safe"":false},{""name"":""c11"",""parameters"":[],""returntype"":""Void"",""offset"":2192,""safe"":false},{""name"":""c12"",""parameters"":[],""returntype"":""Void"",""offset"":2212,""safe"":false},{""name"":""c13"",""parameters"":[],""returntype"":""Void"",""offset"":2232,""safe"":false},{""name"":""c14"",""parameters"":[],""returntype"":""Void"",""offset"":2252,""safe"":false},{""name"":""c15"",""parameters"":[],""returntype"":""Void"",""offset"":2272,""safe"":false},{""name"":""c16"",""parameters"":[],""returntype"":""Void"",""offset"":2292,""safe"":false},{""name"":""c17"",""parameters"":[],""returntype"":""Void"",""offset"":2312,""safe"":false},{""name"":""c18"",""parameters"":[],""returntype"":""Void"",""offset"":2333,""safe"":false},{""name"":""c19"",""parameters"":[],""returntype"":""Void"",""offset"":2354,""safe"":false},{""name"":""c20"",""parameters"":[],""returntype"":""Void"",""offset"":2375,""safe"":false},{""name"":""c21"",""parameters"":[],""returntype"":""Void"",""offset"":2396,""safe"":false},{""name"":""c22"",""parameters"":[],""returntype"":""Void"",""offset"":2417,""safe"":false},{""name"":""c23"",""parameters"":[],""returntype"":""Void"",""offset"":2438,""safe"":false},{""name"":""c24"",""parameters"":[],""returntype"":""Void"",""offset"":2459,""safe"":false},{""name"":""c25"",""parameters"":[],""returntype"":""Void"",""offset"":2480,""safe"":false},{""name"":""c26"",""parameters"":[],""returntype"":""Void"",""offset"":2501,""safe"":false},{""name"":""c27"",""parameters"":[],""returntype"":""Void"",""offset"":2522,""safe"":false},{""name"":""c28"",""parameters"":[],""returntype"":""Void"",""offset"":2543,""safe"":false},{""name"":""c29"",""parameters"":[],""returntype"":""Void"",""offset"":2564,""safe"":false},{""name"":""c30"",""parameters"":[],""returntype"":""Void"",""offset"":2585,""safe"":false},{""name"":""c31"",""parameters"":[],""returntype"":""Void"",""offset"":2606,""safe"":false},{""name"":""c32"",""parameters"":[],""returntype"":""Void"",""offset"":2627,""safe"":false},{""name"":""c33"",""parameters"":[],""returntype"":""Void"",""offset"":2648,""safe"":false},{""name"":""c34"",""parameters"":[],""returntype"":""Void"",""offset"":2669,""safe"":false},{""name"":""c35"",""parameters"":[],""returntype"":""Void"",""offset"":2690,""safe"":false},{""name"":""c36"",""parameters"":[],""returntype"":""Void"",""offset"":2711,""safe"":false},{""name"":""c37"",""parameters"":[],""returntype"":""Void"",""offset"":2732,""safe"":false},{""name"":""c38"",""parameters"":[],""returntype"":""Void"",""offset"":2753,""safe"":false},{""name"":""c39"",""parameters"":[],""returntype"":""Void"",""offset"":2774,""safe"":false},{""name"":""c40"",""parameters"":[],""returntype"":""Void"",""offset"":2795,""safe"":false},{""name"":""c41"",""parameters"":[],""returntype"":""Void"",""offset"":2816,""safe"":false},{""name"":""c42"",""parameters"":[],""returntype"":""Void"",""offset"":2837,""safe"":false},{""name"":""c43"",""parameters"":[],""returntype"":""Void"",""offset"":2858,""safe"":false},{""name"":""c44"",""parameters"":[],""returntype"":""Void"",""offset"":2879,""safe"":false},{""name"":""c45"",""parameters"":[],""returntype"":""Void"",""offset"":2900,""safe"":false},{""name"":""c46"",""parameters"":[],""returntype"":""Void"",""offset"":2921,""safe"":false},{""name"":""c47"",""parameters"":[],""returntype"":""Void"",""offset"":2942,""safe"":false},{""name"":""c48"",""parameters"":[],""returntype"":""Void"",""offset"":2963,""safe"":false},{""name"":""c49"",""parameters"":[],""returntype"":""Void"",""offset"":2984,""safe"":false},{""name"":""c50"",""parameters"":[],""returntype"":""Void"",""offset"":3005,""safe"":false},{""name"":""verify"",""parameters"":[],""returntype"":""Boolean"",""offset"":3026,""safe"":false},{""name"":""d"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":3039,""safe"":false},{""name"":""d0"",""parameters"":[],""returntype"":""Integer"",""offset"":3058,""safe"":false},{""name"":""d10"",""parameters"":[],""returntype"":""Void"",""offset"":3082,""safe"":false},{""name"":""d11"",""parameters"":[],""returntype"":""Void"",""offset"":3102,""safe"":false},{""name"":""d12"",""parameters"":[],""returntype"":""Void"",""offset"":3122,""safe"":false},{""name"":""d13"",""parameters"":[],""returntype"":""Void"",""offset"":3142,""safe"":false},{""name"":""d14"",""parameters"":[],""returntype"":""Void"",""offset"":3162,""safe"":false},{""name"":""d15"",""parameters"":[],""returntype"":""Void"",""offset"":3182,""safe"":false},{""name"":""d16"",""parameters"":[],""returntype"":""Void"",""offset"":3202,""safe"":false},{""name"":""d17"",""parameters"":[],""returntype"":""Void"",""offset"":3222,""safe"":false},{""name"":""d18"",""parameters"":[],""returntype"":""Void"",""offset"":3243,""safe"":false},{""name"":""d19"",""parameters"":[],""returntype"":""Void"",""offset"":3264,""safe"":false},{""name"":""d20"",""parameters"":[],""returntype"":""Void"",""offset"":3285,""safe"":false},{""name"":""d21"",""parameters"":[],""returntype"":""Void"",""offset"":3306,""safe"":false},{""name"":""d22"",""parameters"":[],""returntype"":""Void"",""offset"":3327,""safe"":false},{""name"":""d23"",""parameters"":[],""returntype"":""Void"",""offset"":3348,""safe"":false},{""name"":""d24"",""parameters"":[],""returntype"":""Void"",""offset"":3369,""safe"":false},{""name"":""d25"",""parameters"":[],""returntype"":""Void"",""offset"":3390,""safe"":false},{""name"":""d26"",""parameters"":[],""returntype"":""Void"",""offset"":3411,""safe"":false},{""name"":""d27"",""parameters"":[],""returntype"":""Void"",""offset"":3432,""safe"":false},{""name"":""d28"",""parameters"":[],""returntype"":""Void"",""offset"":3453,""safe"":false},{""name"":""d29"",""parameters"":[],""returntype"":""Void"",""offset"":3474,""safe"":false},{""name"":""d30"",""parameters"":[],""returntype"":""Void"",""offset"":3495,""safe"":false},{""name"":""d31"",""parameters"":[],""returntype"":""Void"",""offset"":3516,""safe"":false},{""name"":""d32"",""parameters"":[],""returntype"":""Void"",""offset"":3537,""safe"":false},{""name"":""d33"",""parameters"":[],""returntype"":""Void"",""offset"":3558,""safe"":false},{""name"":""d34"",""parameters"":[],""returntype"":""Void"",""offset"":3579,""safe"":false},{""name"":""d35"",""parameters"":[],""returntype"":""Void"",""offset"":3600,""safe"":false},{""name"":""d36"",""parameters"":[],""returntype"":""Void"",""offset"":3621,""safe"":false},{""name"":""d37"",""parameters"":[],""returntype"":""Void"",""offset"":3642,""safe"":false},{""name"":""d38"",""parameters"":[],""returntype"":""Void"",""offset"":3663,""safe"":false},{""name"":""d39"",""parameters"":[],""returntype"":""Void"",""offset"":3684,""safe"":false},{""name"":""d40"",""parameters"":[],""returntype"":""Void"",""offset"":3705,""safe"":false},{""name"":""d41"",""parameters"":[],""returntype"":""Void"",""offset"":3726,""safe"":false},{""name"":""d42"",""parameters"":[],""returntype"":""Void"",""offset"":3747,""safe"":false},{""name"":""d43"",""parameters"":[],""returntype"":""Void"",""offset"":3768,""safe"":false},{""name"":""d44"",""parameters"":[],""returntype"":""Void"",""offset"":3789,""safe"":false},{""name"":""d45"",""parameters"":[],""returntype"":""Void"",""offset"":3810,""safe"":false},{""name"":""d46"",""parameters"":[],""returntype"":""Void"",""offset"":3831,""safe"":false},{""name"":""d47"",""parameters"":[],""returntype"":""Void"",""offset"":3852,""safe"":false},{""name"":""d48"",""parameters"":[],""returntype"":""Void"",""offset"":3873,""safe"":false},{""name"":""d49"",""parameters"":[],""returntype"":""Void"",""offset"":3894,""safe"":false},{""name"":""d50"",""parameters"":[],""returntype"":""Void"",""offset"":3915,""safe"":false},{""name"":""e"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":3936,""safe"":false},{""name"":""e0"",""parameters"":[],""returntype"":""Integer"",""offset"":3955,""safe"":false},{""name"":""e10"",""parameters"":[],""returntype"":""Void"",""offset"":3979,""safe"":false},{""name"":""e11"",""parameters"":[],""returntype"":""Void"",""offset"":3999,""safe"":false},{""name"":""e12"",""parameters"":[],""returntype"":""Void"",""offset"":4019,""safe"":false},{""name"":""e13"",""parameters"":[],""returntype"":""Void"",""offset"":4039,""safe"":false},{""name"":""e14"",""parameters"":[],""returntype"":""Void"",""offset"":4059,""safe"":false},{""name"":""e15"",""parameters"":[],""returntype"":""Void"",""offset"":4079,""safe"":false},{""name"":""e16"",""parameters"":[],""returntype"":""Void"",""offset"":4099,""safe"":false},{""name"":""e17"",""parameters"":[],""returntype"":""Void"",""offset"":4119,""safe"":false},{""name"":""e18"",""parameters"":[],""returntype"":""Void"",""offset"":4140,""safe"":false},{""name"":""e19"",""parameters"":[],""returntype"":""Void"",""offset"":4161,""safe"":false},{""name"":""e20"",""parameters"":[],""returntype"":""Void"",""offset"":4182,""safe"":false},{""name"":""e21"",""parameters"":[],""returntype"":""Void"",""offset"":4203,""safe"":false},{""name"":""e22"",""parameters"":[],""returntype"":""Void"",""offset"":4224,""safe"":false},{""name"":""e23"",""parameters"":[],""returntype"":""Void"",""offset"":4245,""safe"":false},{""name"":""e24"",""parameters"":[],""returntype"":""Void"",""offset"":4266,""safe"":false},{""name"":""e25"",""parameters"":[],""returntype"":""Void"",""offset"":4287,""safe"":false},{""name"":""e26"",""parameters"":[],""returntype"":""Void"",""offset"":4308,""safe"":false},{""name"":""e27"",""parameters"":[],""returntype"":""Void"",""offset"":4329,""safe"":false},{""name"":""e28"",""parameters"":[],""returntype"":""Void"",""offset"":4350,""safe"":false},{""name"":""e29"",""parameters"":[],""returntype"":""Void"",""offset"":4371,""safe"":false},{""name"":""e30"",""parameters"":[],""returntype"":""Void"",""offset"":4392,""safe"":false},{""name"":""e31"",""parameters"":[],""returntype"":""Void"",""offset"":4413,""safe"":false},{""name"":""e32"",""parameters"":[],""returntype"":""Void"",""offset"":4434,""safe"":false},{""name"":""e33"",""parameters"":[],""returntype"":""Void"",""offset"":4455,""safe"":false},{""name"":""e34"",""parameters"":[],""returntype"":""Void"",""offset"":4476,""safe"":false},{""name"":""e35"",""parameters"":[],""returntype"":""Void"",""offset"":4497,""safe"":false},{""name"":""e36"",""parameters"":[],""returntype"":""Void"",""offset"":4518,""safe"":false},{""name"":""e37"",""parameters"":[],""returntype"":""Void"",""offset"":4539,""safe"":false},{""name"":""e38"",""parameters"":[],""returntype"":""Void"",""offset"":4560,""safe"":false},{""name"":""e39"",""parameters"":[],""returntype"":""Void"",""offset"":4581,""safe"":false},{""name"":""e40"",""parameters"":[],""returntype"":""Void"",""offset"":4602,""safe"":false},{""name"":""e41"",""parameters"":[],""returntype"":""Void"",""offset"":4623,""safe"":false},{""name"":""e42"",""parameters"":[],""returntype"":""Void"",""offset"":4644,""safe"":false},{""name"":""e43"",""parameters"":[],""returntype"":""Void"",""offset"":4665,""safe"":false},{""name"":""e44"",""parameters"":[],""returntype"":""Void"",""offset"":4686,""safe"":false},{""name"":""e45"",""parameters"":[],""returntype"":""Void"",""offset"":4707,""safe"":false},{""name"":""e46"",""parameters"":[],""returntype"":""Void"",""offset"":4728,""safe"":false},{""name"":""e47"",""parameters"":[],""returntype"":""Void"",""offset"":4749,""safe"":false},{""name"":""e48"",""parameters"":[],""returntype"":""Void"",""offset"":4770,""safe"":false},{""name"":""e49"",""parameters"":[],""returntype"":""Void"",""offset"":4791,""safe"":false},{""name"":""e50"",""parameters"":[],""returntype"":""Void"",""offset"":4812,""safe"":false},{""name"":""f"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":4833,""safe"":false},{""name"":""f0"",""parameters"":[],""returntype"":""Integer"",""offset"":4852,""safe"":false},{""name"":""f10"",""parameters"":[],""returntype"":""Void"",""offset"":4876,""safe"":false},{""name"":""f11"",""parameters"":[],""returntype"":""Void"",""offset"":4896,""safe"":false},{""name"":""f12"",""parameters"":[],""returntype"":""Void"",""offset"":4916,""safe"":false},{""name"":""f13"",""parameters"":[],""returntype"":""Void"",""offset"":4936,""safe"":false},{""name"":""f14"",""parameters"":[],""returntype"":""Void"",""offset"":4956,""safe"":false},{""name"":""f15"",""parameters"":[],""returntype"":""Void"",""offset"":4976,""safe"":false},{""name"":""f16"",""parameters"":[],""returntype"":""Void"",""offset"":4996,""safe"":false},{""name"":""f17"",""parameters"":[],""returntype"":""Void"",""offset"":5016,""safe"":false},{""name"":""f18"",""parameters"":[],""returntype"":""Void"",""offset"":5037,""safe"":false},{""name"":""f19"",""parameters"":[],""returntype"":""Void"",""offset"":5058,""safe"":false},{""name"":""f20"",""parameters"":[],""returntype"":""Void"",""offset"":5079,""safe"":false},{""name"":""f21"",""parameters"":[],""returntype"":""Void"",""offset"":5100,""safe"":false},{""name"":""f22"",""parameters"":[],""returntype"":""Void"",""offset"":5121,""safe"":false},{""name"":""f23"",""parameters"":[],""returntype"":""Void"",""offset"":5142,""safe"":false},{""name"":""f24"",""parameters"":[],""returntype"":""Void"",""offset"":5163,""safe"":false},{""name"":""f25"",""parameters"":[],""returntype"":""Void"",""offset"":5184,""safe"":false},{""name"":""f26"",""parameters"":[],""returntype"":""Void"",""offset"":5205,""safe"":false},{""name"":""f27"",""parameters"":[],""returntype"":""Void"",""offset"":5226,""safe"":false},{""name"":""f28"",""parameters"":[],""returntype"":""Void"",""offset"":5247,""safe"":false},{""name"":""f29"",""parameters"":[],""returntype"":""Void"",""offset"":5268,""safe"":false},{""name"":""f30"",""parameters"":[],""returntype"":""Void"",""offset"":5289,""safe"":false},{""name"":""f31"",""parameters"":[],""returntype"":""Void"",""offset"":5310,""safe"":false},{""name"":""f32"",""parameters"":[],""returntype"":""Void"",""offset"":5331,""safe"":false},{""name"":""f33"",""parameters"":[],""returntype"":""Void"",""offset"":5352,""safe"":false},{""name"":""f34"",""parameters"":[],""returntype"":""Void"",""offset"":5373,""safe"":false},{""name"":""f35"",""parameters"":[],""returntype"":""Void"",""offset"":5394,""safe"":false},{""name"":""f36"",""parameters"":[],""returntype"":""Void"",""offset"":5415,""safe"":false},{""name"":""f37"",""parameters"":[],""returntype"":""Void"",""offset"":5436,""safe"":false},{""name"":""f38"",""parameters"":[],""returntype"":""Void"",""offset"":5457,""safe"":false},{""name"":""f39"",""parameters"":[],""returntype"":""Void"",""offset"":5478,""safe"":false},{""name"":""f40"",""parameters"":[],""returntype"":""Void"",""offset"":5499,""safe"":false},{""name"":""f41"",""parameters"":[],""returntype"":""Void"",""offset"":5520,""safe"":false},{""name"":""f42"",""parameters"":[],""returntype"":""Void"",""offset"":5541,""safe"":false},{""name"":""f43"",""parameters"":[],""returntype"":""Void"",""offset"":5562,""safe"":false},{""name"":""f44"",""parameters"":[],""returntype"":""Void"",""offset"":5583,""safe"":false},{""name"":""f45"",""parameters"":[],""returntype"":""Void"",""offset"":5604,""safe"":false},{""name"":""f46"",""parameters"":[],""returntype"":""Void"",""offset"":5625,""safe"":false},{""name"":""f47"",""parameters"":[],""returntype"":""Void"",""offset"":5646,""safe"":false},{""name"":""f48"",""parameters"":[],""returntype"":""Void"",""offset"":5667,""safe"":false},{""name"":""f49"",""parameters"":[],""returntype"":""Void"",""offset"":5688,""safe"":false},{""name"":""f50"",""parameters"":[],""returntype"":""Void"",""offset"":5709,""safe"":false},{""name"":""g"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":5730,""safe"":false},{""name"":""g0"",""parameters"":[],""returntype"":""Integer"",""offset"":5749,""safe"":false},{""name"":""g10"",""parameters"":[],""returntype"":""Void"",""offset"":5773,""safe"":false},{""name"":""g11"",""parameters"":[],""returntype"":""Void"",""offset"":5793,""safe"":false},{""name"":""g12"",""parameters"":[],""returntype"":""Void"",""offset"":5813,""safe"":false},{""name"":""g13"",""parameters"":[],""returntype"":""Void"",""offset"":5833,""safe"":false},{""name"":""g14"",""parameters"":[],""returntype"":""Void"",""offset"":5853,""safe"":false},{""name"":""g15"",""parameters"":[],""returntype"":""Void"",""offset"":5873,""safe"":false},{""name"":""g16"",""parameters"":[],""returntype"":""Void"",""offset"":5893,""safe"":false},{""name"":""g17"",""parameters"":[],""returntype"":""Void"",""offset"":5913,""safe"":false},{""name"":""g18"",""parameters"":[],""returntype"":""Void"",""offset"":5934,""safe"":false},{""name"":""g19"",""parameters"":[],""returntype"":""Void"",""offset"":5955,""safe"":false},{""name"":""g20"",""parameters"":[],""returntype"":""Void"",""offset"":5976,""safe"":false},{""name"":""g21"",""parameters"":[],""returntype"":""Void"",""offset"":5997,""safe"":false},{""name"":""g22"",""parameters"":[],""returntype"":""Void"",""offset"":6018,""safe"":false},{""name"":""g23"",""parameters"":[],""returntype"":""Void"",""offset"":6039,""safe"":false},{""name"":""g24"",""parameters"":[],""returntype"":""Void"",""offset"":6060,""safe"":false},{""name"":""g25"",""parameters"":[],""returntype"":""Void"",""offset"":6081,""safe"":false},{""name"":""g26"",""parameters"":[],""returntype"":""Void"",""offset"":6102,""safe"":false},{""name"":""g27"",""parameters"":[],""returntype"":""Void"",""offset"":6123,""safe"":false},{""name"":""g28"",""parameters"":[],""returntype"":""Void"",""offset"":6144,""safe"":false},{""name"":""g29"",""parameters"":[],""returntype"":""Void"",""offset"":6165,""safe"":false},{""name"":""g30"",""parameters"":[],""returntype"":""Void"",""offset"":6186,""safe"":false},{""name"":""g31"",""parameters"":[],""returntype"":""Void"",""offset"":6207,""safe"":false},{""name"":""g32"",""parameters"":[],""returntype"":""Void"",""offset"":6228,""safe"":false},{""name"":""g33"",""parameters"":[],""returntype"":""Void"",""offset"":6249,""safe"":false},{""name"":""g34"",""parameters"":[],""returntype"":""Void"",""offset"":6270,""safe"":false},{""name"":""g35"",""parameters"":[],""returntype"":""Void"",""offset"":6291,""safe"":false},{""name"":""g36"",""parameters"":[],""returntype"":""Void"",""offset"":6312,""safe"":false},{""name"":""g37"",""parameters"":[],""returntype"":""Void"",""offset"":6333,""safe"":false},{""name"":""g38"",""parameters"":[],""returntype"":""Void"",""offset"":6354,""safe"":false},{""name"":""g39"",""parameters"":[],""returntype"":""Void"",""offset"":6375,""safe"":false},{""name"":""g40"",""parameters"":[],""returntype"":""Void"",""offset"":6396,""safe"":false},{""name"":""g41"",""parameters"":[],""returntype"":""Void"",""offset"":6417,""safe"":false},{""name"":""g42"",""parameters"":[],""returntype"":""Void"",""offset"":6438,""safe"":false},{""name"":""g43"",""parameters"":[],""returntype"":""Void"",""offset"":6459,""safe"":false},{""name"":""g44"",""parameters"":[],""returntype"":""Void"",""offset"":6480,""safe"":false},{""name"":""g45"",""parameters"":[],""returntype"":""Void"",""offset"":6501,""safe"":false},{""name"":""g46"",""parameters"":[],""returntype"":""Void"",""offset"":6522,""safe"":false},{""name"":""g47"",""parameters"":[],""returntype"":""Void"",""offset"":6543,""safe"":false},{""name"":""g48"",""parameters"":[],""returntype"":""Void"",""offset"":6564,""safe"":false},{""name"":""g49"",""parameters"":[],""returntype"":""Void"",""offset"":6585,""safe"":false},{""name"":""g50"",""parameters"":[],""returntype"":""Void"",""offset"":6606,""safe"":false},{""name"":""h"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":6627,""safe"":false},{""name"":""h0"",""parameters"":[],""returntype"":""Integer"",""offset"":6646,""safe"":false},{""name"":""h10"",""parameters"":[],""returntype"":""Void"",""offset"":6670,""safe"":false},{""name"":""h11"",""parameters"":[],""returntype"":""Void"",""offset"":6690,""safe"":false},{""name"":""h12"",""parameters"":[],""returntype"":""Void"",""offset"":6710,""safe"":false},{""name"":""h13"",""parameters"":[],""returntype"":""Void"",""offset"":6730,""safe"":false},{""name"":""h14"",""parameters"":[],""returntype"":""Void"",""offset"":6750,""safe"":false},{""name"":""h15"",""parameters"":[],""returntype"":""Void"",""offset"":6770,""safe"":false},{""name"":""h16"",""parameters"":[],""returntype"":""Void"",""offset"":6790,""safe"":false},{""name"":""h17"",""parameters"":[],""returntype"":""Void"",""offset"":6810,""safe"":false},{""name"":""h18"",""parameters"":[],""returntype"":""Void"",""offset"":6831,""safe"":false},{""name"":""h19"",""parameters"":[],""returntype"":""Void"",""offset"":6852,""safe"":false},{""name"":""h20"",""parameters"":[],""returntype"":""Void"",""offset"":6873,""safe"":false},{""name"":""h21"",""parameters"":[],""returntype"":""Void"",""offset"":6894,""safe"":false},{""name"":""h22"",""parameters"":[],""returntype"":""Void"",""offset"":6915,""safe"":false},{""name"":""h23"",""parameters"":[],""returntype"":""Void"",""offset"":6936,""safe"":false},{""name"":""h24"",""parameters"":[],""returntype"":""Void"",""offset"":6957,""safe"":false},{""name"":""h25"",""parameters"":[],""returntype"":""Void"",""offset"":6978,""safe"":false},{""name"":""h26"",""parameters"":[],""returntype"":""Void"",""offset"":6999,""safe"":false},{""name"":""h27"",""parameters"":[],""returntype"":""Void"",""offset"":7020,""safe"":false},{""name"":""h28"",""parameters"":[],""returntype"":""Void"",""offset"":7041,""safe"":false},{""name"":""h29"",""parameters"":[],""returntype"":""Void"",""offset"":7062,""safe"":false},{""name"":""h30"",""parameters"":[],""returntype"":""Void"",""offset"":7083,""safe"":false},{""name"":""h31"",""parameters"":[],""returntype"":""Void"",""offset"":7104,""safe"":false},{""name"":""h32"",""parameters"":[],""returntype"":""Void"",""offset"":7125,""safe"":false},{""name"":""h33"",""parameters"":[],""returntype"":""Void"",""offset"":7146,""safe"":false},{""name"":""h34"",""parameters"":[],""returntype"":""Void"",""offset"":7167,""safe"":false},{""name"":""h35"",""parameters"":[],""returntype"":""Void"",""offset"":7188,""safe"":false},{""name"":""h36"",""parameters"":[],""returntype"":""Void"",""offset"":7209,""safe"":false},{""name"":""h37"",""parameters"":[],""returntype"":""Void"",""offset"":7230,""safe"":false},{""name"":""h38"",""parameters"":[],""returntype"":""Void"",""offset"":7251,""safe"":false},{""name"":""h39"",""parameters"":[],""returntype"":""Void"",""offset"":7272,""safe"":false},{""name"":""h40"",""parameters"":[],""returntype"":""Void"",""offset"":7293,""safe"":false},{""name"":""h41"",""parameters"":[],""returntype"":""Void"",""offset"":7314,""safe"":false},{""name"":""h42"",""parameters"":[],""returntype"":""Void"",""offset"":7335,""safe"":false},{""name"":""h43"",""parameters"":[],""returntype"":""Void"",""offset"":7356,""safe"":false},{""name"":""h44"",""parameters"":[],""returntype"":""Void"",""offset"":7377,""safe"":false},{""name"":""h45"",""parameters"":[],""returntype"":""Void"",""offset"":7398,""safe"":false},{""name"":""h46"",""parameters"":[],""returntype"":""Void"",""offset"":7419,""safe"":false},{""name"":""h47"",""parameters"":[],""returntype"":""Void"",""offset"":7440,""safe"":false},{""name"":""h48"",""parameters"":[],""returntype"":""Void"",""offset"":7461,""safe"":false},{""name"":""h49"",""parameters"":[],""returntype"":""Void"",""offset"":7482,""safe"":false},{""name"":""h50"",""parameters"":[],""returntype"":""Void"",""offset"":7503,""safe"":false},{""name"":""i"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":7524,""safe"":false},{""name"":""i0"",""parameters"":[],""returntype"":""Integer"",""offset"":7545,""safe"":false},{""name"":""i10"",""parameters"":[],""returntype"":""Void"",""offset"":7571,""safe"":false},{""name"":""i11"",""parameters"":[],""returntype"":""Void"",""offset"":7593,""safe"":false},{""name"":""i12"",""parameters"":[],""returntype"":""Void"",""offset"":7615,""safe"":false},{""name"":""i13"",""parameters"":[],""returntype"":""Void"",""offset"":7637,""safe"":false},{""name"":""i14"",""parameters"":[],""returntype"":""Void"",""offset"":7659,""safe"":false},{""name"":""i15"",""parameters"":[],""returntype"":""Void"",""offset"":7681,""safe"":false},{""name"":""i16"",""parameters"":[],""returntype"":""Void"",""offset"":7703,""safe"":false},{""name"":""i17"",""parameters"":[],""returntype"":""Void"",""offset"":7725,""safe"":false},{""name"":""i18"",""parameters"":[],""returntype"":""Void"",""offset"":7748,""safe"":false},{""name"":""i19"",""parameters"":[],""returntype"":""Void"",""offset"":7771,""safe"":false},{""name"":""i20"",""parameters"":[],""returntype"":""Void"",""offset"":7794,""safe"":false},{""name"":""i21"",""parameters"":[],""returntype"":""Void"",""offset"":7817,""safe"":false},{""name"":""i22"",""parameters"":[],""returntype"":""Void"",""offset"":7840,""safe"":false},{""name"":""i23"",""parameters"":[],""returntype"":""Void"",""offset"":7863,""safe"":false},{""name"":""i24"",""parameters"":[],""returntype"":""Void"",""offset"":7886,""safe"":false},{""name"":""i25"",""parameters"":[],""returntype"":""Void"",""offset"":7909,""safe"":false},{""name"":""i26"",""parameters"":[],""returntype"":""Void"",""offset"":7932,""safe"":false},{""name"":""i27"",""parameters"":[],""returntype"":""Void"",""offset"":7955,""safe"":false},{""name"":""i28"",""parameters"":[],""returntype"":""Void"",""offset"":7978,""safe"":false},{""name"":""i29"",""parameters"":[],""returntype"":""Void"",""offset"":8001,""safe"":false},{""name"":""i30"",""parameters"":[],""returntype"":""Void"",""offset"":8024,""safe"":false},{""name"":""i31"",""parameters"":[],""returntype"":""Void"",""offset"":8047,""safe"":false},{""name"":""i32"",""parameters"":[],""returntype"":""Void"",""offset"":8070,""safe"":false},{""name"":""i33"",""parameters"":[],""returntype"":""Void"",""offset"":8093,""safe"":false},{""name"":""i34"",""parameters"":[],""returntype"":""Void"",""offset"":8116,""safe"":false},{""name"":""i35"",""parameters"":[],""returntype"":""Void"",""offset"":8139,""safe"":false},{""name"":""i36"",""parameters"":[],""returntype"":""Void"",""offset"":8162,""safe"":false},{""name"":""i37"",""parameters"":[],""returntype"":""Void"",""offset"":8185,""safe"":false},{""name"":""i38"",""parameters"":[],""returntype"":""Void"",""offset"":8208,""safe"":false},{""name"":""i39"",""parameters"":[],""returntype"":""Void"",""offset"":8231,""safe"":false},{""name"":""i40"",""parameters"":[],""returntype"":""Void"",""offset"":8254,""safe"":false},{""name"":""i41"",""parameters"":[],""returntype"":""Void"",""offset"":8277,""safe"":false},{""name"":""i42"",""parameters"":[],""returntype"":""Void"",""offset"":8300,""safe"":false},{""name"":""i43"",""parameters"":[],""returntype"":""Void"",""offset"":8323,""safe"":false},{""name"":""i44"",""parameters"":[],""returntype"":""Void"",""offset"":8346,""safe"":false},{""name"":""i45"",""parameters"":[],""returntype"":""Void"",""offset"":8369,""safe"":false},{""name"":""i46"",""parameters"":[],""returntype"":""Void"",""offset"":8392,""safe"":false},{""name"":""i47"",""parameters"":[],""returntype"":""Void"",""offset"":8415,""safe"":false},{""name"":""i48"",""parameters"":[],""returntype"":""Void"",""offset"":8438,""safe"":false},{""name"":""i49"",""parameters"":[],""returntype"":""Void"",""offset"":8461,""safe"":false},{""name"":""i50"",""parameters"":[],""returntype"":""Void"",""offset"":8484,""safe"":false},{""name"":""update"",""parameters"":[{""name"":""nefFile"",""type"":""ByteArray""},{""name"":""manifest"",""type"":""String""}],""returntype"":""Void"",""offset"":8511,""safe"":false},{""name"":""j"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":8578,""safe"":false},{""name"":""j0"",""parameters"":[],""returntype"":""Integer"",""offset"":8599,""safe"":false},{""name"":""j10"",""parameters"":[],""returntype"":""Void"",""offset"":8625,""safe"":false},{""name"":""j11"",""parameters"":[],""returntype"":""Void"",""offset"":8647,""safe"":false},{""name"":""j12"",""parameters"":[],""returntype"":""Void"",""offset"":8669,""safe"":false},{""name"":""j13"",""parameters"":[],""returntype"":""Void"",""offset"":8691,""safe"":false},{""name"":""j14"",""parameters"":[],""returntype"":""Void"",""offset"":8713,""safe"":false},{""name"":""j15"",""parameters"":[],""returntype"":""Void"",""offset"":8735,""safe"":false},{""name"":""j16"",""parameters"":[],""returntype"":""Void"",""offset"":8757,""safe"":false},{""name"":""j17"",""parameters"":[],""returntype"":""Void"",""offset"":8779,""safe"":false},{""name"":""j18"",""parameters"":[],""returntype"":""Void"",""offset"":8802,""safe"":false},{""name"":""j19"",""parameters"":[],""returntype"":""Void"",""offset"":8825,""safe"":false},{""name"":""j20"",""parameters"":[],""returntype"":""Void"",""offset"":8848,""safe"":false},{""name"":""j21"",""parameters"":[],""returntype"":""Void"",""offset"":8871,""safe"":false},{""name"":""j22"",""parameters"":[],""returntype"":""Void"",""offset"":8894,""safe"":false},{""name"":""j23"",""parameters"":[],""returntype"":""Void"",""offset"":8917,""safe"":false},{""name"":""j24"",""parameters"":[],""returntype"":""Void"",""offset"":8940,""safe"":false},{""name"":""j25"",""parameters"":[],""returntype"":""Void"",""offset"":8963,""safe"":false},{""name"":""j26"",""parameters"":[],""returntype"":""Void"",""offset"":8986,""safe"":false},{""name"":""j27"",""parameters"":[],""returntype"":""Void"",""offset"":9009,""safe"":false},{""name"":""j28"",""parameters"":[],""returntype"":""Void"",""offset"":9032,""safe"":false},{""name"":""j29"",""parameters"":[],""returntype"":""Void"",""offset"":9055,""safe"":false},{""name"":""j30"",""parameters"":[],""returntype"":""Void"",""offset"":9078,""safe"":false},{""name"":""j31"",""parameters"":[],""returntype"":""Void"",""offset"":9101,""safe"":false},{""name"":""j32"",""parameters"":[],""returntype"":""Void"",""offset"":9124,""safe"":false},{""name"":""j33"",""parameters"":[],""returntype"":""Void"",""offset"":9147,""safe"":false},{""name"":""j34"",""parameters"":[],""returntype"":""Void"",""offset"":9170,""safe"":false},{""name"":""j35"",""parameters"":[],""returntype"":""Void"",""offset"":9193,""safe"":false},{""name"":""j36"",""parameters"":[],""returntype"":""Void"",""offset"":9216,""safe"":false},{""name"":""j37"",""parameters"":[],""returntype"":""Void"",""offset"":9239,""safe"":false},{""name"":""j38"",""parameters"":[],""returntype"":""Void"",""offset"":9262,""safe"":false},{""name"":""j39"",""parameters"":[],""returntype"":""Void"",""offset"":9285,""safe"":false},{""name"":""j40"",""parameters"":[],""returntype"":""Void"",""offset"":9308,""safe"":false},{""name"":""j41"",""parameters"":[],""returntype"":""Void"",""offset"":9331,""safe"":false},{""name"":""j42"",""parameters"":[],""returntype"":""Void"",""offset"":9354,""safe"":false},{""name"":""j43"",""parameters"":[],""returntype"":""Void"",""offset"":9377,""safe"":false},{""name"":""j44"",""parameters"":[],""returntype"":""Void"",""offset"":9400,""safe"":false},{""name"":""j45"",""parameters"":[],""returntype"":""Void"",""offset"":9423,""safe"":false},{""name"":""j46"",""parameters"":[],""returntype"":""Void"",""offset"":9446,""safe"":false},{""name"":""j47"",""parameters"":[],""returntype"":""Void"",""offset"":9469,""safe"":false},{""name"":""j48"",""parameters"":[],""returntype"":""Void"",""offset"":9492,""safe"":false},{""name"":""j49"",""parameters"":[],""returntype"":""Void"",""offset"":9515,""safe"":false},{""name"":""j50"",""parameters"":[],""returntype"":""Void"",""offset"":9538,""safe"":false},{""name"":""k"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":9561,""safe"":false},{""name"":""k0"",""parameters"":[],""returntype"":""Integer"",""offset"":9601,""safe"":false},{""name"":""k10"",""parameters"":[],""returntype"":""Void"",""offset"":9646,""safe"":false},{""name"":""k11"",""parameters"":[],""returntype"":""Void"",""offset"":9687,""safe"":false},{""name"":""k12"",""parameters"":[],""returntype"":""Void"",""offset"":9728,""safe"":false},{""name"":""k13"",""parameters"":[],""returntype"":""Void"",""offset"":9769,""safe"":false},{""name"":""k14"",""parameters"":[],""returntype"":""Void"",""offset"":9810,""safe"":false},{""name"":""k15"",""parameters"":[],""returntype"":""Void"",""offset"":9851,""safe"":false},{""name"":""k16"",""parameters"":[],""returntype"":""Void"",""offset"":9892,""safe"":false},{""name"":""k17"",""parameters"":[],""returntype"":""Void"",""offset"":9933,""safe"":false},{""name"":""k18"",""parameters"":[],""returntype"":""Void"",""offset"":9975,""safe"":false},{""name"":""k19"",""parameters"":[],""returntype"":""Void"",""offset"":10017,""safe"":false},{""name"":""k20"",""parameters"":[],""returntype"":""Void"",""offset"":10059,""safe"":false},{""name"":""k21"",""parameters"":[],""returntype"":""Void"",""offset"":10101,""safe"":false},{""name"":""k22"",""parameters"":[],""returntype"":""Void"",""offset"":10143,""safe"":false},{""name"":""k23"",""parameters"":[],""returntype"":""Void"",""offset"":10185,""safe"":false},{""name"":""k24"",""parameters"":[],""returntype"":""Void"",""offset"":10227,""safe"":false},{""name"":""k25"",""parameters"":[],""returntype"":""Void"",""offset"":10269,""safe"":false},{""name"":""k26"",""parameters"":[],""returntype"":""Void"",""offset"":10311,""safe"":false},{""name"":""k27"",""parameters"":[],""returntype"":""Void"",""offset"":10353,""safe"":false},{""name"":""k28"",""parameters"":[],""returntype"":""Void"",""offset"":10395,""safe"":false},{""name"":""k29"",""parameters"":[],""returntype"":""Void"",""offset"":10437,""safe"":false},{""name"":""k30"",""parameters"":[],""returntype"":""Void"",""offset"":10479,""safe"":false},{""name"":""k31"",""parameters"":[],""returntype"":""Void"",""offset"":10521,""safe"":false},{""name"":""k32"",""parameters"":[],""returntype"":""Void"",""offset"":10563,""safe"":false},{""name"":""k33"",""parameters"":[],""returntype"":""Void"",""offset"":10605,""safe"":false},{""name"":""k34"",""parameters"":[],""returntype"":""Void"",""offset"":10647,""safe"":false},{""name"":""k35"",""parameters"":[],""returntype"":""Void"",""offset"":10689,""safe"":false},{""name"":""k36"",""parameters"":[],""returntype"":""Void"",""offset"":10731,""safe"":false},{""name"":""k37"",""parameters"":[],""returntype"":""Void"",""offset"":10773,""safe"":false},{""name"":""k38"",""parameters"":[],""returntype"":""Void"",""offset"":10815,""safe"":false},{""name"":""k39"",""parameters"":[],""returntype"":""Void"",""offset"":10857,""safe"":false},{""name"":""k40"",""parameters"":[],""returntype"":""Void"",""offset"":10899,""safe"":false},{""name"":""k41"",""parameters"":[],""returntype"":""Void"",""offset"":10941,""safe"":false},{""name"":""k42"",""parameters"":[],""returntype"":""Void"",""offset"":10983,""safe"":false},{""name"":""k43"",""parameters"":[],""returntype"":""Void"",""offset"":11025,""safe"":false},{""name"":""k44"",""parameters"":[],""returntype"":""Void"",""offset"":11067,""safe"":false},{""name"":""k45"",""parameters"":[],""returntype"":""Void"",""offset"":11109,""safe"":false},{""name"":""k46"",""parameters"":[],""returntype"":""Void"",""offset"":11151,""safe"":false},{""name"":""k47"",""parameters"":[],""returntype"":""Void"",""offset"":11193,""safe"":false},{""name"":""k48"",""parameters"":[],""returntype"":""Void"",""offset"":11235,""safe"":false},{""name"":""k49"",""parameters"":[],""returntype"":""Void"",""offset"":11277,""safe"":false},{""name"":""k50"",""parameters"":[],""returntype"":""Void"",""offset"":11319,""safe"":false},{""name"":""l"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":11361,""safe"":false},{""name"":""l0"",""parameters"":[],""returntype"":""Integer"",""offset"":11401,""safe"":false},{""name"":""l10"",""parameters"":[],""returntype"":""Void"",""offset"":11446,""safe"":false},{""name"":""l11"",""parameters"":[],""returntype"":""Void"",""offset"":11487,""safe"":false},{""name"":""l12"",""parameters"":[],""returntype"":""Void"",""offset"":11528,""safe"":false},{""name"":""l13"",""parameters"":[],""returntype"":""Void"",""offset"":11569,""safe"":false},{""name"":""l14"",""parameters"":[],""returntype"":""Void"",""offset"":11610,""safe"":false},{""name"":""l15"",""parameters"":[],""returntype"":""Void"",""offset"":11651,""safe"":false},{""name"":""l16"",""parameters"":[],""returntype"":""Void"",""offset"":11692,""safe"":false},{""name"":""l17"",""parameters"":[],""returntype"":""Void"",""offset"":11733,""safe"":false},{""name"":""l18"",""parameters"":[],""returntype"":""Void"",""offset"":11775,""safe"":false},{""name"":""l19"",""parameters"":[],""returntype"":""Void"",""offset"":11817,""safe"":false},{""name"":""l20"",""parameters"":[],""returntype"":""Void"",""offset"":11859,""safe"":false},{""name"":""l21"",""parameters"":[],""returntype"":""Void"",""offset"":11901,""safe"":false},{""name"":""l22"",""parameters"":[],""returntype"":""Void"",""offset"":11943,""safe"":false},{""name"":""l23"",""parameters"":[],""returntype"":""Void"",""offset"":11985,""safe"":false},{""name"":""l24"",""parameters"":[],""returntype"":""Void"",""offset"":12027,""safe"":false},{""name"":""l25"",""parameters"":[],""returntype"":""Void"",""offset"":12069,""safe"":false},{""name"":""l26"",""parameters"":[],""returntype"":""Void"",""offset"":12111,""safe"":false},{""name"":""l27"",""parameters"":[],""returntype"":""Void"",""offset"":12153,""safe"":false},{""name"":""l28"",""parameters"":[],""returntype"":""Void"",""offset"":12195,""safe"":false},{""name"":""l29"",""parameters"":[],""returntype"":""Void"",""offset"":12237,""safe"":false},{""name"":""l30"",""parameters"":[],""returntype"":""Void"",""offset"":12279,""safe"":false},{""name"":""l31"",""parameters"":[],""returntype"":""Void"",""offset"":12321,""safe"":false},{""name"":""l32"",""parameters"":[],""returntype"":""Void"",""offset"":12363,""safe"":false},{""name"":""l33"",""parameters"":[],""returntype"":""Void"",""offset"":12405,""safe"":false},{""name"":""l34"",""parameters"":[],""returntype"":""Void"",""offset"":12447,""safe"":false},{""name"":""l35"",""parameters"":[],""returntype"":""Void"",""offset"":12489,""safe"":false},{""name"":""l36"",""parameters"":[],""returntype"":""Void"",""offset"":12531,""safe"":false},{""name"":""l37"",""parameters"":[],""returntype"":""Void"",""offset"":12573,""safe"":false},{""name"":""l38"",""parameters"":[],""returntype"":""Void"",""offset"":12615,""safe"":false},{""name"":""l39"",""parameters"":[],""returntype"":""Void"",""offset"":12657,""safe"":false},{""name"":""l40"",""parameters"":[],""returntype"":""Void"",""offset"":12699,""safe"":false},{""name"":""l41"",""parameters"":[],""returntype"":""Void"",""offset"":12741,""safe"":false},{""name"":""l42"",""parameters"":[],""returntype"":""Void"",""offset"":12783,""safe"":false},{""name"":""l43"",""parameters"":[],""returntype"":""Void"",""offset"":12825,""safe"":false},{""name"":""l44"",""parameters"":[],""returntype"":""Void"",""offset"":12867,""safe"":false},{""name"":""l45"",""parameters"":[],""returntype"":""Void"",""offset"":12909,""safe"":false},{""name"":""l46"",""parameters"":[],""returntype"":""Void"",""offset"":12951,""safe"":false},{""name"":""l47"",""parameters"":[],""returntype"":""Void"",""offset"":12993,""safe"":false},{""name"":""l48"",""parameters"":[],""returntype"":""Void"",""offset"":13035,""safe"":false},{""name"":""l49"",""parameters"":[],""returntype"":""Void"",""offset"":13077,""safe"":false},{""name"":""l50"",""parameters"":[],""returntype"":""Void"",""offset"":13119,""safe"":false},{""name"":""m"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":13161,""safe"":false},{""name"":""m0"",""parameters"":[],""returntype"":""Integer"",""offset"":13181,""safe"":false},{""name"":""m10"",""parameters"":[],""returntype"":""Void"",""offset"":13206,""safe"":false},{""name"":""m11"",""parameters"":[],""returntype"":""Void"",""offset"":13227,""safe"":false},{""name"":""m12"",""parameters"":[],""returntype"":""Void"",""offset"":13248,""safe"":false},{""name"":""m13"",""parameters"":[],""returntype"":""Void"",""offset"":13269,""safe"":false},{""name"":""m14"",""parameters"":[],""returntype"":""Void"",""offset"":13290,""safe"":false},{""name"":""m15"",""parameters"":[],""returntype"":""Void"",""offset"":13311,""safe"":false},{""name"":""m16"",""parameters"":[],""returntype"":""Void"",""offset"":13332,""safe"":false},{""name"":""m17"",""parameters"":[],""returntype"":""Void"",""offset"":13353,""safe"":false},{""name"":""m18"",""parameters"":[],""returntype"":""Void"",""offset"":13375,""safe"":false},{""name"":""m19"",""parameters"":[],""returntype"":""Void"",""offset"":13397,""safe"":false},{""name"":""m20"",""parameters"":[],""returntype"":""Void"",""offset"":13419,""safe"":false},{""name"":""m21"",""parameters"":[],""returntype"":""Void"",""offset"":13441,""safe"":false},{""name"":""m22"",""parameters"":[],""returntype"":""Void"",""offset"":13463,""safe"":false},{""name"":""m23"",""parameters"":[],""returntype"":""Void"",""offset"":13485,""safe"":false},{""name"":""m24"",""parameters"":[],""returntype"":""Void"",""offset"":13507,""safe"":false},{""name"":""m25"",""parameters"":[],""returntype"":""Void"",""offset"":13529,""safe"":false},{""name"":""m26"",""parameters"":[],""returntype"":""Void"",""offset"":13551,""safe"":false},{""name"":""m27"",""parameters"":[],""returntype"":""Void"",""offset"":13573,""safe"":false},{""name"":""m28"",""parameters"":[],""returntype"":""Void"",""offset"":13595,""safe"":false},{""name"":""m29"",""parameters"":[],""returntype"":""Void"",""offset"":13617,""safe"":false},{""name"":""m30"",""parameters"":[],""returntype"":""Void"",""offset"":13639,""safe"":false},{""name"":""m31"",""parameters"":[],""returntype"":""Void"",""offset"":13661,""safe"":false},{""name"":""m32"",""parameters"":[],""returntype"":""Void"",""offset"":13683,""safe"":false},{""name"":""m33"",""parameters"":[],""returntype"":""Void"",""offset"":13705,""safe"":false},{""name"":""m34"",""parameters"":[],""returntype"":""Void"",""offset"":13727,""safe"":false},{""name"":""m35"",""parameters"":[],""returntype"":""Void"",""offset"":13749,""safe"":false},{""name"":""m36"",""parameters"":[],""returntype"":""Void"",""offset"":13771,""safe"":false},{""name"":""m37"",""parameters"":[],""returntype"":""Void"",""offset"":13793,""safe"":false},{""name"":""m38"",""parameters"":[],""returntype"":""Void"",""offset"":13815,""safe"":false},{""name"":""m39"",""parameters"":[],""returntype"":""Void"",""offset"":13837,""safe"":false},{""name"":""m40"",""parameters"":[],""returntype"":""Void"",""offset"":13859,""safe"":false},{""name"":""m41"",""parameters"":[],""returntype"":""Void"",""offset"":13881,""safe"":false},{""name"":""m42"",""parameters"":[],""returntype"":""Void"",""offset"":13903,""safe"":false},{""name"":""m43"",""parameters"":[],""returntype"":""Void"",""offset"":13925,""safe"":false},{""name"":""m44"",""parameters"":[],""returntype"":""Void"",""offset"":13947,""safe"":false},{""name"":""m45"",""parameters"":[],""returntype"":""Void"",""offset"":13969,""safe"":false},{""name"":""m46"",""parameters"":[],""returntype"":""Void"",""offset"":13991,""safe"":false},{""name"":""m47"",""parameters"":[],""returntype"":""Void"",""offset"":14013,""safe"":false},{""name"":""m48"",""parameters"":[],""returntype"":""Void"",""offset"":14035,""safe"":false},{""name"":""m49"",""parameters"":[],""returntype"":""Void"",""offset"":14057,""safe"":false},{""name"":""m50"",""parameters"":[],""returntype"":""Void"",""offset"":14079,""safe"":false},{""name"":""n"",""parameters"":[{""name"":""amountIn"",""type"":""Integer""}],""returntype"":""Void"",""offset"":14101,""safe"":false},{""name"":""n0"",""parameters"":[],""returntype"":""Integer"",""offset"":14121,""safe"":false},{""name"":""n10"",""parameters"":[],""returntype"":""Void"",""offset"":14146,""safe"":false},{""name"":""n11"",""parameters"":[],""returntype"":""Void"",""offset"":14167,""safe"":false},{""name"":""n12"",""parameters"":[],""returntype"":""Void"",""offset"":14188,""safe"":false},{""name"":""n13"",""parameters"":[],""returntype"":""Void"",""offset"":14209,""safe"":false},{""name"":""n14"",""parameters"":[],""returntype"":""Void"",""offset"":14230,""safe"":false},{""name"":""n15"",""parameters"":[],""returntype"":""Void"",""offset"":14251,""safe"":false},{""name"":""n16"",""parameters"":[],""returntype"":""Void"",""offset"":14272,""safe"":false},{""name"":""n17"",""parameters"":[],""returntype"":""Void"",""offset"":14293,""safe"":false},{""name"":""n18"",""parameters"":[],""returntype"":""Void"",""offset"":14315,""safe"":false},{""name"":""n19"",""parameters"":[],""returntype"":""Void"",""offset"":14337,""safe"":false},{""name"":""n20"",""parameters"":[],""returntype"":""Void"",""offset"":14359,""safe"":false},{""name"":""n21"",""parameters"":[],""returntype"":""Void"",""offset"":14381,""safe"":false},{""name"":""n22"",""parameters"":[],""returntype"":""Void"",""offset"":14403,""safe"":false},{""name"":""n23"",""parameters"":[],""returntype"":""Void"",""offset"":14425,""safe"":false},{""name"":""n24"",""parameters"":[],""returntype"":""Void"",""offset"":14447,""safe"":false},{""name"":""n25"",""parameters"":[],""returntype"":""Void"",""offset"":14469,""safe"":false},{""name"":""n26"",""parameters"":[],""returntype"":""Void"",""offset"":14491,""safe"":false},{""name"":""n27"",""parameters"":[],""returntype"":""Void"",""offset"":14513,""safe"":false},{""name"":""n28"",""parameters"":[],""returntype"":""Void"",""offset"":14535,""safe"":false},{""name"":""n29"",""parameters"":[],""returntype"":""Void"",""offset"":14557,""safe"":false},{""name"":""n30"",""parameters"":[],""returntype"":""Void"",""offset"":14579,""safe"":false},{""name"":""n31"",""parameters"":[],""returntype"":""Void"",""offset"":14601,""safe"":false},{""name"":""n32"",""parameters"":[],""returntype"":""Void"",""offset"":14623,""safe"":false},{""name"":""n33"",""parameters"":[],""returntype"":""Void"",""offset"":14645,""safe"":false},{""name"":""n34"",""parameters"":[],""returntype"":""Void"",""offset"":14667,""safe"":false},{""name"":""n35"",""parameters"":[],""returntype"":""Void"",""offset"":14689,""safe"":false},{""name"":""n36"",""parameters"":[],""returntype"":""Void"",""offset"":14711,""safe"":false},{""name"":""n37"",""parameters"":[],""returntype"":""Void"",""offset"":14733,""safe"":false},{""name"":""n38"",""parameters"":[],""returntype"":""Void"",""offset"":14755,""safe"":false},{""name"":""n39"",""parameters"":[],""returntype"":""Void"",""offset"":14777,""safe"":false},{""name"":""n40"",""parameters"":[],""returntype"":""Void"",""offset"":14799,""safe"":false},{""name"":""n41"",""parameters"":[],""returntype"":""Void"",""offset"":14821,""safe"":false},{""name"":""n42"",""parameters"":[],""returntype"":""Void"",""offset"":14843,""safe"":false},{""name"":""n43"",""parameters"":[],""returntype"":""Void"",""offset"":14865,""safe"":false},{""name"":""n44"",""parameters"":[],""returntype"":""Void"",""offset"":14887,""safe"":false},{""name"":""n45"",""parameters"":[],""returntype"":""Void"",""offset"":14909,""safe"":false},{""name"":""n46"",""parameters"":[],""returntype"":""Void"",""offset"":14931,""safe"":false},{""name"":""n47"",""parameters"":[],""returntype"":""Void"",""offset"":14953,""safe"":false},{""name"":""n48"",""parameters"":[],""returntype"":""Void"",""offset"":14975,""safe"":false},{""name"":""n49"",""parameters"":[],""returntype"":""Void"",""offset"":14997,""safe"":false},{""name"":""n50"",""parameters"":[],""returntype"":""Void"",""offset"":15019,""safe"":false},{""name"":""_initialize"",""parameters"":[],""returntype"":""Void"",""offset"":15041,""safe"":false}],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""extra"":{""Author"":""Test"",""Email"":""Test@Test"",""Description"":""This is a Test Contract""}}"; var manifest = ContractManifest.Parse(json); - var counter = new ReferenceCounter(); + var counter = new ReferenceCounterV2(); var item = manifest.ToStackItem(counter); var data = BinarySerializer.Serialize(item, 1024 * 1024, 4096); @@ -118,7 +118,7 @@ public void ToInteroperable_Trust() { var json = @"{""name"":""CallOracleContract-6"",""groups"":[],""features"":{},""supportedstandards"":[],""abi"":{""methods"":[{""name"":""request"",""parameters"":[{""name"":""url"",""type"":""String""},{""name"":""filter"",""type"":""String""},{""name"":""gasForResponse"",""type"":""Integer""}],""returntype"":""Void"",""offset"":0,""safe"":false},{""name"":""callback"",""parameters"":[{""name"":""url"",""type"":""String""},{""name"":""userData"",""type"":""Any""},{""name"":""responseCode"",""type"":""Integer""},{""name"":""response"",""type"":""ByteArray""}],""returntype"":""Void"",""offset"":86,""safe"":false},{""name"":""getStoredUrl"",""parameters"":[],""returntype"":""String"",""offset"":129,""safe"":false},{""name"":""getStoredResponseCode"",""parameters"":[],""returntype"":""Integer"",""offset"":142,""safe"":false},{""name"":""getStoredResponse"",""parameters"":[],""returntype"":""ByteArray"",""offset"":165,""safe"":false}],""events"":[]},""permissions"":[{""contract"":""0xfe924b7cfe89ddd271abaf7210a80a7e11178758"",""methods"":""*""},{""contract"":""*"",""methods"":""*""}],""trusts"":[""0xfe924b7cfe89ddd271abaf7210a80a7e11178758"",""*""],""extra"":{}}"; var manifest = ContractManifest.Parse(json); - var s = (VM.Types.Struct)manifest.ToStackItem(new ReferenceCounter()); + var s = (VM.Types.Struct)manifest.ToStackItem(new ReferenceCounterV2()); manifest = s.ToInteroperable(); Assert.IsFalse(manifest.Permissions[0].Contract.IsWildcard); diff --git a/tests/Neo.VM.Tests/UT_ExecutionContext.cs b/tests/Neo.VM.Tests/UT_ExecutionContext.cs index b53003a7e6..14c4e3235e 100644 --- a/tests/Neo.VM.Tests/UT_ExecutionContext.cs +++ b/tests/Neo.VM.Tests/UT_ExecutionContext.cs @@ -27,7 +27,7 @@ class TestState [TestMethod] public void TestStateTest() { - var context = new ExecutionContext(Array.Empty(), -1, new ReferenceCounter()); + var context = new ExecutionContext(Array.Empty(), -1, new ReferenceCounterV2()); // Test factory diff --git a/tests/Neo.VM.Tests/UT_ReferenceCounter.cs b/tests/Neo.VM.Tests/UT_ReferenceCounter.cs index 61f7788dd8..356d236953 100644 --- a/tests/Neo.VM.Tests/UT_ReferenceCounter.cs +++ b/tests/Neo.VM.Tests/UT_ReferenceCounter.cs @@ -247,7 +247,7 @@ public void TestArrayNoPush() [ExpectedException(typeof(InvalidOperationException))] public void TestInvalidReferenceStackItem() { - var reference = new ReferenceCounter(); + var reference = new ReferenceCounterV2(); var arr = new Array(reference); var arr2 = new Array(); diff --git a/tests/Neo.VM.Tests/UT_Slot.cs b/tests/Neo.VM.Tests/UT_Slot.cs index ea2f38029b..d175be1310 100644 --- a/tests/Neo.VM.Tests/UT_Slot.cs +++ b/tests/Neo.VM.Tests/UT_Slot.cs @@ -31,7 +31,7 @@ private static Slot CreateOrderedSlot(int count) check[x - 1] = x; } - var slot = new Slot(check, new ReferenceCounter()); + var slot = new Slot(check, new ReferenceCounterV2()); Assert.AreEqual(count, slot.Count); CollectionAssert.AreEqual(check, slot.ToArray()); From e735b5e7e5ececff19aff25210148f153e013cbd Mon Sep 17 00:00:00 2001 From: Jimmy Date: Mon, 18 Nov 2024 01:17:53 +0800 Subject: [PATCH 15/36] update ut to adopt RCV2 --- .../SmartContract/UT_NotifyEventArgs.cs | 4 ++-- tests/Neo.VM.Tests/UT_ReferenceCounter.cs | 23 +++++++++++-------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/tests/Neo.UnitTests/SmartContract/UT_NotifyEventArgs.cs b/tests/Neo.UnitTests/SmartContract/UT_NotifyEventArgs.cs index 59afbbb760..28e7eab81f 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_NotifyEventArgs.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_NotifyEventArgs.cs @@ -54,12 +54,12 @@ public void TestIssue3300() // https://github.com/neo-project/neo/issues/3300 // This should have being 0, but we have optimized the vm to not clean the reference counter // unless it is necessary, so the reference counter will be 1000. // Same reason why its 1504 instead of 504. - Assert.AreEqual(1000, engine.ReferenceCounter.Count); + Assert.AreEqual(0, engine.ReferenceCounter.Count); // This will make a deepcopy for the notification, along with the 500 state items. engine.GetNotifications(hash); // With the fix of issue 3300, the reference counter calculates not only // the notifaction items, but also the subitems of the notification state. - Assert.AreEqual(1504, engine.ReferenceCounter.Count); + Assert.AreEqual(0, engine.ReferenceCounter.Count); } } } diff --git a/tests/Neo.VM.Tests/UT_ReferenceCounter.cs b/tests/Neo.VM.Tests/UT_ReferenceCounter.cs index 356d236953..5dc1cdd0e1 100644 --- a/tests/Neo.VM.Tests/UT_ReferenceCounter.cs +++ b/tests/Neo.VM.Tests/UT_ReferenceCounter.cs @@ -158,9 +158,9 @@ public void TestRemoveReferrer() Assert.AreEqual(VMState.BREAK, debugger.StepInto()); Assert.AreEqual(3, engine.ReferenceCounter.Count); Assert.AreEqual(VMState.BREAK, debugger.StepInto()); - Assert.AreEqual(2, engine.ReferenceCounter.Count); - Assert.AreEqual(VMState.HALT, debugger.Execute()); Assert.AreEqual(1, engine.ReferenceCounter.Count); + Assert.AreEqual(VMState.HALT, debugger.Execute()); + Assert.AreEqual(0, engine.ReferenceCounter.Count); } [TestMethod] @@ -237,18 +237,18 @@ public void TestArrayNoPush() using ExecutionEngine engine = new(); engine.LoadScript(sb.ToArray()); Assert.AreEqual(0, engine.ReferenceCounter.Count); - Array array = new(engine.ReferenceCounter, new StackItem[] { 1, 2, 3, 4 }); - Assert.AreEqual(array.Count, engine.ReferenceCounter.Count); + Array array = new(new StackItem[] { 1, 2, 3, 4 }); + engine.CurrentContext.EvaluationStack.Push(array); + Assert.AreEqual(array.Count + 1, engine.ReferenceCounter.Count); Assert.AreEqual(VMState.HALT, engine.Execute()); - Assert.AreEqual(array.Count, engine.ReferenceCounter.Count); + Assert.AreEqual(array.Count + 1, engine.ReferenceCounter.Count); } [TestMethod] - [ExpectedException(typeof(InvalidOperationException))] public void TestInvalidReferenceStackItem() { - var reference = new ReferenceCounterV2(); - var arr = new Array(reference); + + var arr = new Array(); var arr2 = new Array(); for (var i = 0; i < 10; i++) @@ -257,7 +257,12 @@ public void TestInvalidReferenceStackItem() } arr.Add(arr2); - Assert.AreEqual(11, reference.Count); + + var engine = new ExecutionEngine(new ReferenceCounterV2()); + engine.LoadScript(new Script((byte[])[(byte)OpCode.NOP])); + + engine.CurrentContext.EvaluationStack.Push(arr); + Assert.AreEqual(12, engine.ReferenceCounter.Count); } } } From 24efc8bec669eb3cbcec159abcef77b37ada4356 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Mon, 18 Nov 2024 01:20:05 +0800 Subject: [PATCH 16/36] fix UT --- tests/Neo.VM.Tests/UT_ReferenceCounter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Neo.VM.Tests/UT_ReferenceCounter.cs b/tests/Neo.VM.Tests/UT_ReferenceCounter.cs index 5dc1cdd0e1..1acf79460c 100644 --- a/tests/Neo.VM.Tests/UT_ReferenceCounter.cs +++ b/tests/Neo.VM.Tests/UT_ReferenceCounter.cs @@ -136,7 +136,7 @@ public void TestRemoveReferrer() sb.Emit(OpCode.DROP); //{}|{B[]}:1 sb.Emit(OpCode.RET); //{}:0 - using ExecutionEngine engine = new(); + using ExecutionEngine engine = new(new ReferenceCounterV2()); Debugger debugger = new(engine); engine.LoadScript(sb.ToArray()); Assert.AreEqual(VMState.BREAK, debugger.StepInto()); @@ -234,7 +234,7 @@ public void TestArrayNoPush() { using ScriptBuilder sb = new(); sb.Emit(OpCode.RET); - using ExecutionEngine engine = new(); + using ExecutionEngine engine = new(new ReferenceCounterV2()); engine.LoadScript(sb.ToArray()); Assert.AreEqual(0, engine.ReferenceCounter.Count); Array array = new(new StackItem[] { 1, 2, 3, 4 }); From aa58fc93b54dbd14458fb6e56383fb260726a6e2 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Mon, 18 Nov 2024 16:07:03 +0800 Subject: [PATCH 17/36] update UT and bench, and apply hecate suggestion --- .../Neo.VM.Benchmarks/Benchmarks.POC.cs | 45 ++++++++++++++++++- benchmarks/Neo.VM.Benchmarks/Program.cs | 1 + .../ReferenceCounter/ReferenceCounterV2.cs | 15 +++++++ .../Manifest/UT_ContractPermission.cs | 4 +- tests/Neo.VM.Tests/Types/TestEngine.cs | 2 +- 5 files changed, 62 insertions(+), 5 deletions(-) diff --git a/benchmarks/Neo.VM.Benchmarks/Benchmarks.POC.cs b/benchmarks/Neo.VM.Benchmarks/Benchmarks.POC.cs index 2eede59fc3..4af1601a1c 100644 --- a/benchmarks/Neo.VM.Benchmarks/Benchmarks.POC.cs +++ b/benchmarks/Neo.VM.Benchmarks/Benchmarks.POC.cs @@ -10,6 +10,7 @@ // modifications are permitted. using BenchmarkDotNet.Attributes; +using Neo.VM.Benchmark.OpCode; using System.Diagnostics; namespace Neo.VM.Benchmark @@ -387,11 +388,51 @@ public void PoC_GetScriptContainer() private static void Run(string poc) { byte[] script = Convert.FromBase64String(poc); - using ExecutionEngine engine = new(); + using BenchmarkEngine engine = new(); engine.LoadScript(script); - engine.Execute(); + engine.ExecuteOneGASBenchmark(); Debug.Assert(engine.State == VMState.HALT); } } } + +// +// | Method | Mean | Error | StdDev | +// |----------------------- |----------------:|---------------:|---------------:| +// | NeoIssue2528 | 55,319.65 us | 1,105.171 us | 1,687.713 us | +// | NeoVMIssue418 | 347.21 us | 4.985 us | 4.663 us | +// | NeoIssue2723 | 71.05 us | 0.674 us | 0.630 us | +// | PoC_NewBuffer | 68.60 us | 0.691 us | 0.646 us | +// | PoC_Cat | 68.96 us | 0.831 us | 0.777 us | +// | PoC_Left | 65.76 us | 0.773 us | 0.723 us | +// | PoC_Right | 64.84 us | 0.679 us | 0.635 us | +// | PoC_ReverseN | 8,399,264.69 us | 152,328.560 us | 135,035.301 us | +// | PoC_Substr | 65.07 us | 1.122 us | 1.050 us | +// | PoC_NewArray | 2,903,663.37 us | 15,827.726 us | 14,805.265 us | +// | PoC_NewStruct | 3,027,978.35 us | 12,747.892 us | 11,300.674 us | +// | PoC_Roll | 1,274,207.78 us | 8,063.045 us | 7,542.177 us | +// | PoC_XDrop | 1,217,206.92 us | 22,759.560 us | 21,289.307 us | +// | PoC_MemCpy | 70.88 us | 1.407 us | 1.728 us | +// | PoC_Unpack | 384,346.69 us | 3,212.166 us | 2,847.502 us | +// | PoC_GetScriptContainer | 69.26 us | 0.620 us | 0.580 us | + + +// | Method | Mean | Error | StdDev | +// |----------------------- |----------------:|---------------:|---------------:| +// | NeoIssue2528 | 698,949.53 us | 13,657.042 us | 22,817.849 us | +// | NeoVMIssue418 | 589.21 us | 11.631 us | 17.409 us | +// | NeoIssue2723 | 70.68 us | 1.375 us | 1.739 us | +// | PoC_NewBuffer | 71.54 us | 1.350 us | 1.607 us | +// | PoC_Cat | 70.13 us | 1.387 us | 2.077 us | +// | PoC_Left | 69.71 us | 1.230 us | 1.151 us | +// | PoC_Right | 70.44 us | 1.358 us | 1.564 us | +// | PoC_ReverseN | 8,387,677.64 us | 157,776.848 us | 154,957.961 us | +// | PoC_Substr | 66.31 us | 0.834 us | 0.780 us | +// | PoC_NewArray | 4,081,067.00 us | 21,804.230 us | 20,395.690 us | +// | PoC_NewStruct | 4,073,281.73 us | 14,618.967 us | 13,674.591 us | +// | PoC_Roll | 1,226,264.36 us | 9,115.778 us | 8,952.913 us | +// | PoC_XDrop | 1,220,594.82 us | 12,695.011 us | 9,911.430 us | +// | PoC_MemCpy | 65.53 us | 0.737 us | 0.616 us | +// | PoC_Unpack | 392,349.50 us | 7,267.582 us | 7,463.272 us | +// | PoC_GetScriptContainer | 66.83 us | 0.622 us | 0.551 us | diff --git a/benchmarks/Neo.VM.Benchmarks/Program.cs b/benchmarks/Neo.VM.Benchmarks/Program.cs index 09523ecd7c..8a7be8b523 100644 --- a/benchmarks/Neo.VM.Benchmarks/Program.cs +++ b/benchmarks/Neo.VM.Benchmarks/Program.cs @@ -12,6 +12,7 @@ using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Running; using Neo.VM.Benchmark; +using Neo.VM.Benchmark.OpCode; using System.Reflection; // Flag to determine if running benchmark or running methods diff --git a/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs b/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs index 76827f6f19..a16f01d249 100644 --- a/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs +++ b/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs @@ -27,12 +27,19 @@ public sealed class ReferenceCounterV2 : IReferenceCounter { public RCVersion Version { get; init; } = RCVersion.V2; + private readonly ExecutionEngineLimits _limits = ExecutionEngineLimits.Default; + // Keeps the total count of references. private int _referencesCount = 0; /// public int Count => _referencesCount; + public ReferenceCounterV2(ExecutionEngineLimits limits = null) + { + _limits = limits ?? ExecutionEngineLimits.Default; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool NeedTrack(StackItem item) @@ -52,10 +59,13 @@ public void AddStackReference(StackItem item, int count = 1) // Increment the reference count by the specified count. _referencesCount += count; + if (_referencesCount > _limits.MaxStackSize) + throw new IndexOutOfRangeException("Circular reference detected, execution stopped."); if (item is CompoundType compoundType) { // Increment the item's stack references by the specified count. compoundType.StackReferences += count; + if (compoundType.StackReferences == count) { foreach (var subItem in compoundType.SubItems) @@ -89,11 +99,16 @@ public void RemoveStackReference(StackItem item) { // Increment the reference count by the specified count. _referencesCount--; + if (_referencesCount < 0) + throw new IndexOutOfRangeException("Circular reference detected, execution stopped."); if (item is CompoundType compoundType) { // Increment the item's stack references by the specified count. compoundType.StackReferences--; + + if (compoundType.StackReferences < 0) + throw new IndexOutOfRangeException("Circular reference detected, execution stopped."); if (compoundType.StackReferences == 0) { foreach (var subItem in compoundType.SubItems) diff --git a/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractPermission.cs b/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractPermission.cs index 972a06d56d..a24be6d0d2 100644 --- a/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractPermission.cs +++ b/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractPermission.cs @@ -26,7 +26,7 @@ public void TestDeserialize() { // null ContractPermission contractPermission = ContractPermission.DefaultPermission; - Struct s = (Struct)contractPermission.ToStackItem(new VM.ReferenceCounter()); + Struct s = (Struct)contractPermission.ToStackItem(new VM.ReferenceCounterV2()); contractPermission = s.ToInteroperable(); Assert.IsTrue(contractPermission.Contract.IsWildcard); @@ -38,7 +38,7 @@ public void TestDeserialize() Contract = ContractPermissionDescriptor.Create(UInt160.Zero), Methods = WildcardContainer.Create("test") }; - s = (Struct)contractPermission.ToStackItem(new VM.ReferenceCounter()); + s = (Struct)contractPermission.ToStackItem(new VM.ReferenceCounterV2()); contractPermission = s.ToInteroperable(); Assert.IsFalse(contractPermission.Contract.IsWildcard); diff --git a/tests/Neo.VM.Tests/Types/TestEngine.cs b/tests/Neo.VM.Tests/Types/TestEngine.cs index 2602163315..f781990136 100644 --- a/tests/Neo.VM.Tests/Types/TestEngine.cs +++ b/tests/Neo.VM.Tests/Types/TestEngine.cs @@ -19,7 +19,7 @@ public class TestEngine : ExecutionEngine { public Exception FaultException { get; private set; } - public TestEngine() : base(ComposeJumpTable()) { } + public TestEngine() : base(new ReferenceCounterV2(), ComposeJumpTable()) { } private static JumpTable ComposeJumpTable() { From 83c3d2f3c7efb016c8bab09138b0fd25ad6cc0b1 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Mon, 18 Nov 2024 16:13:34 +0800 Subject: [PATCH 18/36] update exception message --- src/Neo.VM/ExecutionEngine.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Neo.VM/ExecutionEngine.cs b/src/Neo.VM/ExecutionEngine.cs index 5783e262c0..8f99d73871 100644 --- a/src/Neo.VM/ExecutionEngine.cs +++ b/src/Neo.VM/ExecutionEngine.cs @@ -308,12 +308,12 @@ protected virtual void PostExecuteInstruction(Instruction instruction) { if (ReferenceCounter.Count < Limits.MaxStackSize) return; if (ReferenceCounter.CheckZeroReferred() > Limits.MaxStackSize) - throw new InvalidOperationException($"MaxStackSize exceed: {ReferenceCounter.Count}"); + throw new InvalidOperationException($"MaxStackSize exceed: {ReferenceCounter.Count}/{Limits.MaxStackSize}"); } else { if (ReferenceCounter.Count <= Limits.MaxStackSize) return; - throw new InvalidOperationException($"MaxStackSize exceed: {ReferenceCounter.Count}"); + throw new InvalidOperationException($"MaxStackSize exceed: {ReferenceCounter.Count}/{Limits.MaxStackSize}"); } } From c2582e2c96fae7b298a2c5f4609a5ce093219465 Mon Sep 17 00:00:00 2001 From: Shargon Date: Wed, 20 Nov 2024 23:10:14 +0100 Subject: [PATCH 19/36] Update src/Neo.VM/Types/CompoundType.cs --- src/Neo.VM/Types/CompoundType.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Neo.VM/Types/CompoundType.cs b/src/Neo.VM/Types/CompoundType.cs index 4504b468d1..e5ae353493 100644 --- a/src/Neo.VM/Types/CompoundType.cs +++ b/src/Neo.VM/Types/CompoundType.cs @@ -32,12 +32,14 @@ public abstract class CompoundType : StackItem /// The reference counter to be used. protected CompoundType(IReferenceCounter? referenceCounter = null) { - if (referenceCounter is { Version: RCVersion.V2 }) - ReferenceCounter = null; - else + if (referenceCounter?.Version == RCVersion.V1) { ReferenceCounter = referenceCounter; - referenceCounter?.AddZeroReferred(this); + referenceCounter.AddZeroReferred(this); + } + else + { + ReferenceCounter = null; } } From 5d8921c47a69f75c3e04a7e0d41ca8eeae4e772e Mon Sep 17 00:00:00 2001 From: Jimmy Date: Thu, 21 Nov 2024 15:02:01 +0800 Subject: [PATCH 20/36] define and use isRC2 --- src/Neo.VM/JumpTable/JumpTable.Compound.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Neo.VM/JumpTable/JumpTable.Compound.cs b/src/Neo.VM/JumpTable/JumpTable.Compound.cs index 529a16c32b..0054cc5ad1 100644 --- a/src/Neo.VM/JumpTable/JumpTable.Compound.cs +++ b/src/Neo.VM/JumpTable/JumpTable.Compound.cs @@ -440,6 +440,7 @@ public virtual void SetItem(ExecutionEngine engine, Instruction instruction) if (value is Struct s) value = s.Clone(engine.Limits); var key = engine.Pop(); var x = engine.Pop(); + var isRC2 = engine.ReferenceCounter.Version == RCVersion.V2; switch (x) { case VMArray array: @@ -447,16 +448,16 @@ public virtual void SetItem(ExecutionEngine engine, Instruction instruction) var index = (int)key.GetInteger(); if (index < 0 || index >= array.Count) throw new CatchableException($"The index of {nameof(VMArray)} is out of range, {index}/[0, {array.Count})."); - if (engine.ReferenceCounter.Version == RCVersion.V2) + if (isRC2) engine.ReferenceCounter.RemoveStackReference(array[index]); array[index] = value; - if (engine.ReferenceCounter.Version == RCVersion.V2) + if (isRC2) engine.ReferenceCounter.AddStackReference(array[index]); break; } case Map map: { - if (engine.ReferenceCounter.Version == RCVersion.V2) + if (isRC2) { if (!map.TryGetValue(key, out var value1)) { @@ -469,7 +470,7 @@ public virtual void SetItem(ExecutionEngine engine, Instruction instruction) } map[key] = value; - if (engine.ReferenceCounter.Version == RCVersion.V2) + if (isRC2) engine.ReferenceCounter.AddStackReference(value); break; } From 1da5aa70f8c70d78823ead3fc7386155fa810cce Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Thu, 21 Nov 2024 20:21:32 +0100 Subject: [PATCH 21/36] Avoid replace benchmarks --- ...s_Convert.cs => Benchmarks_ConvertRCV1.cs} | 11 +- .../VMTypes/Benchmarks_ConvertRCV2.cs | 131 ++++++++++++++++++ ...DeepCopy.cs => Benchmarks_DeepCopyRCV1.cs} | 17 ++- .../VMTypes/Benchmarks_DeepCopyRCV2.cs | 21 +++ 4 files changed, 171 insertions(+), 9 deletions(-) rename benchmarks/Neo.VM.Benchmarks/VMTypes/{Benchmarks_Convert.cs => Benchmarks_ConvertRCV1.cs} (98%) create mode 100644 benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_ConvertRCV2.cs rename benchmarks/Neo.VM.Benchmarks/VMTypes/{Benchmarks_DeepCopy.cs => Benchmarks_DeepCopyRCV1.cs} (88%) create mode 100644 benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopyRCV2.cs diff --git a/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_Convert.cs b/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_ConvertRCV1.cs similarity index 98% rename from benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_Convert.cs rename to benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_ConvertRCV1.cs index de5e2cd187..ea9f6de802 100644 --- a/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_Convert.cs +++ b/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_ConvertRCV1.cs @@ -1,6 +1,6 @@ // Copyright (C) 2015-2024 The Neo Project. // -// Benchmarks_Convert.cs file belongs to the neo project and is free +// Benchmarks_ConvertRCV1.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 @@ -16,7 +16,7 @@ namespace Neo.VM.Benchmark { - public class Benchmarks_Convert + public class Benchmarks_ConvertRCV1 { private Dictionary>? testItemsByType; @@ -26,6 +26,11 @@ public void Setup() testItemsByType = CreateTestItemsByType(); } + public virtual IReferenceCounter CreateReferenceCounter() + { + return new ReferenceCounter(); + } + [Benchmark] [ArgumentsSource(nameof(GetTypeConversionPairs))] public void BenchConvertTo(StackItemType fromType, StackItemType toType) @@ -60,7 +65,7 @@ public IEnumerable GetTypeConversionPairs() private Dictionary> CreateTestItemsByType() { - var referenceCounter = new ReferenceCounterV2(); + var referenceCounter = CreateReferenceCounter(); var result = new Dictionary>(); foreach (StackItemType type in Enum.GetValues(typeof(StackItemType))) diff --git a/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_ConvertRCV2.cs b/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_ConvertRCV2.cs new file mode 100644 index 0000000000..499f2bcfc4 --- /dev/null +++ b/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_ConvertRCV2.cs @@ -0,0 +1,131 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// Benchmarks_ConvertRCV2.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. + +namespace Neo.VM.Benchmark +{ + public class Benchmarks_ConvertRCV2 : Benchmarks_ConvertRCV1 + { + public override IReferenceCounter CreateReferenceCounter() + { + return new ReferenceCounterV2(); + } + } +} + +// BenchmarkDotNet v0.13.12, Windows 11 (10.0.22631.4249/23H2/2023Update/SunValley3) +// Intel Core i9-14900HX, 1 CPU, 32 logical and 24 physical cores +// .NET SDK 8.0.205 +// [Host] : .NET 8.0.5 (8.0.524.21615), X64 RyuJIT AVX2 +// DefaultJob : .NET 8.0.5 (8.0.524.21615), X64 RyuJIT AVX2 +// +// +// | Method | fromType | toType | Mean | Error | StdDev | +// |--------------- |----------------- |----------------- |-------------:|------------:|------------:| +// | BenchConvertTo | Any | Any | 1.762 ns | 0.0195 ns | 0.0182 ns | +// | BenchConvertTo | Any | Pointer | 1.791 ns | 0.0196 ns | 0.0183 ns | +// | BenchConvertTo | Any | Boolean | 1.774 ns | 0.0245 ns | 0.0229 ns | +// | BenchConvertTo | Any | Integer | 1.781 ns | 0.0236 ns | 0.0220 ns | +// | BenchConvertTo | Any | ByteString | 1.767 ns | 0.0255 ns | 0.0226 ns | +// | BenchConvertTo | Any | Buffer | 1.774 ns | 0.0217 ns | 0.0203 ns | +// | BenchConvertTo | Any | Array | 1.770 ns | 0.0412 ns | 0.0385 ns | +// | BenchConvertTo | Any | Struct | 1.787 ns | 0.0227 ns | 0.0212 ns | +// | BenchConvertTo | Any | Map | 1.796 ns | 0.0292 ns | 0.0273 ns | +// | BenchConvertTo | Any | InteropInterface | 1.820 ns | 0.0549 ns | 0.0675 ns | +// | BenchConvertTo | Pointer | Any | 2.312 ns | 0.0210 ns | 0.0175 ns | +// | BenchConvertTo | Pointer | Pointer | 2.337 ns | 0.0157 ns | 0.0146 ns | +// | BenchConvertTo | Pointer | Boolean | 2.352 ns | 0.0190 ns | 0.0169 ns | +// | BenchConvertTo | Pointer | Integer | 2.334 ns | 0.0231 ns | 0.0216 ns | +// | BenchConvertTo | Pointer | ByteString | 2.317 ns | 0.0298 ns | 0.0279 ns | +// | BenchConvertTo | Pointer | Buffer | 2.329 ns | 0.0274 ns | 0.0256 ns | +// | BenchConvertTo | Pointer | Array | 2.338 ns | 0.0257 ns | 0.0241 ns | +// | BenchConvertTo | Pointer | Struct | 2.336 ns | 0.0318 ns | 0.0298 ns | +// | BenchConvertTo | Pointer | Map | 2.351 ns | 0.0676 ns | 0.0903 ns | +// | BenchConvertTo | Pointer | InteropInterface | 2.281 ns | 0.0133 ns | 0.0125 ns | +// | BenchConvertTo | Boolean | Any | 5,926.451 ns | 118.1195 ns | 136.0266 ns | +// | BenchConvertTo | Boolean | Pointer | 6,001.282 ns | 15.3048 ns | 12.7802 ns | +// | BenchConvertTo | Boolean | Boolean | 4.459 ns | 0.0151 ns | 0.0133 ns | +// | BenchConvertTo | Boolean | Integer | 14.104 ns | 0.1526 ns | 0.1428 ns | +// | BenchConvertTo | Boolean | ByteString | 11.650 ns | 0.0539 ns | 0.0450 ns | +// | BenchConvertTo | Boolean | Buffer | 26.106 ns | 0.1549 ns | 0.1449 ns | +// | BenchConvertTo | Boolean | Array | 5,813.116 ns | 28.1911 ns | 26.3700 ns | +// | BenchConvertTo | Boolean | Struct | 5,809.844 ns | 19.1249 ns | 15.9702 ns | +// | BenchConvertTo | Boolean | Map | 6,061.558 ns | 29.3991 ns | 27.4999 ns | +// | BenchConvertTo | Boolean | InteropInterface | 5,924.682 ns | 80.5533 ns | 75.3496 ns | +// | BenchConvertTo | Integer | Any | 5,240.903 ns | 41.0628 ns | 38.4102 ns | +// | BenchConvertTo | Integer | Pointer | 5,479.116 ns | 75.8232 ns | 70.9251 ns | +// | BenchConvertTo | Integer | Boolean | 5.981 ns | 0.0445 ns | 0.0416 ns | +// | BenchConvertTo | Integer | Integer | 4.277 ns | 0.0177 ns | 0.0166 ns | +// | BenchConvertTo | Integer | ByteString | 19.053 ns | 0.2125 ns | 0.1883 ns | +// | BenchConvertTo | Integer | Buffer | 32.782 ns | 0.1653 ns | 0.1380 ns | +// | BenchConvertTo | Integer | Array | 4,693.207 ns | 14.2446 ns | 12.6275 ns | +// | BenchConvertTo | Integer | Struct | 4,737.341 ns | 60.1813 ns | 56.2936 ns | +// | BenchConvertTo | Integer | Map | 4,808.431 ns | 23.5380 ns | 22.0174 ns | +// | BenchConvertTo | Integer | InteropInterface | 4,684.409 ns | 24.7033 ns | 21.8989 ns | +// | BenchConvertTo | ByteString | Any | 5,833.857 ns | 20.1553 ns | 18.8533 ns | +// | BenchConvertTo | ByteString | Pointer | 5,807.973 ns | 11.7754 ns | 10.4386 ns | +// | BenchConvertTo | ByteString | Boolean | 33.007 ns | 0.1574 ns | 0.1472 ns | +// | BenchConvertTo | ByteString | Integer | 23.622 ns | 0.0755 ns | 0.0669 ns | +// | BenchConvertTo | ByteString | ByteString | 4.288 ns | 0.0152 ns | 0.0142 ns | +// | BenchConvertTo | ByteString | Buffer | 24.881 ns | 0.0889 ns | 0.0788 ns | +// | BenchConvertTo | ByteString | Array | 6,030.813 ns | 19.9562 ns | 18.6670 ns | +// | BenchConvertTo | ByteString | Struct | 5,811.185 ns | 24.0781 ns | 22.5226 ns | +// | BenchConvertTo | ByteString | Map | 5,866.820 ns | 17.0315 ns | 15.0980 ns | +// | BenchConvertTo | ByteString | InteropInterface | 5,757.124 ns | 16.3184 ns | 14.4658 ns | +// | BenchConvertTo | Buffer | Any | 4,886.279 ns | 17.1370 ns | 14.3102 ns | +// | BenchConvertTo | Buffer | Pointer | 4,698.364 ns | 14.5491 ns | 12.1492 ns | +// | BenchConvertTo | Buffer | Boolean | 6.130 ns | 0.0323 ns | 0.0302 ns | +// | BenchConvertTo | Buffer | Integer | 4,645.764 ns | 15.8146 ns | 14.7930 ns | +// | BenchConvertTo | Buffer | ByteString | 29.874 ns | 0.1518 ns | 0.1268 ns | +// | BenchConvertTo | Buffer | Buffer | 4.939 ns | 0.0190 ns | 0.0178 ns | +// | BenchConvertTo | Buffer | Array | 4,683.427 ns | 21.3813 ns | 20.0001 ns | +// | BenchConvertTo | Buffer | Struct | 4,680.762 ns | 15.7220 ns | 13.9371 ns | +// | BenchConvertTo | Buffer | Map | 4,706.510 ns | 14.2061 ns | 12.5934 ns | +// | BenchConvertTo | Buffer | InteropInterface | 4,703.050 ns | 15.8002 ns | 14.0064 ns | +// | BenchConvertTo | Array | Any | 4,652.710 ns | 23.2061 ns | 20.5716 ns | +// | BenchConvertTo | Array | Pointer | 4,625.049 ns | 12.4455 ns | 11.6415 ns | +// | BenchConvertTo | Array | Boolean | 5.568 ns | 0.0181 ns | 0.0169 ns | +// | BenchConvertTo | Array | Integer | 4,659.897 ns | 19.8036 ns | 18.5243 ns | +// | BenchConvertTo | Array | ByteString | 4,663.020 ns | 12.4988 ns | 11.6914 ns | +// | BenchConvertTo | Array | Buffer | 4,680.281 ns | 14.9748 ns | 13.2748 ns | +// | BenchConvertTo | Array | Array | 4.246 ns | 0.0124 ns | 0.0110 ns | +// | BenchConvertTo | Array | Struct | 1,193.106 ns | 98.5374 ns | 285.8748 ns | +// | BenchConvertTo | Array | Map | 4,742.631 ns | 35.5855 ns | 33.2867 ns | +// | BenchConvertTo | Array | InteropInterface | 4,670.743 ns | 9.3547 ns | 7.8116 ns | +// | BenchConvertTo | Struct | Any | 4,643.558 ns | 31.0451 ns | 29.0396 ns | +// | BenchConvertTo | Struct | Pointer | 4,867.925 ns | 22.2347 ns | 19.7105 ns | +// | BenchConvertTo | Struct | Boolean | 5.581 ns | 0.0251 ns | 0.0235 ns | +// | BenchConvertTo | Struct | Integer | 4,653.442 ns | 17.7417 ns | 16.5956 ns | +// | BenchConvertTo | Struct | ByteString | 4,646.242 ns | 13.7830 ns | 12.8926 ns | +// | BenchConvertTo | Struct | Buffer | 4,776.205 ns | 14.1918 ns | 13.2751 ns | +// | BenchConvertTo | Struct | Array | 1,622.573 ns | 144.8116 ns | 398.8532 ns | +// | BenchConvertTo | Struct | Struct | 4.195 ns | 0.0327 ns | 0.0290 ns | +// | BenchConvertTo | Struct | Map | 4,672.579 ns | 17.6257 ns | 16.4871 ns | +// | BenchConvertTo | Struct | InteropInterface | 4,653.476 ns | 8.2047 ns | 7.6747 ns | +// | BenchConvertTo | Map | Any | 4,676.540 ns | 15.2010 ns | 13.4753 ns | +// | BenchConvertTo | Map | Pointer | 4,663.489 ns | 13.7871 ns | 12.2219 ns | +// | BenchConvertTo | Map | Boolean | 5.535 ns | 0.0205 ns | 0.0192 ns | +// | BenchConvertTo | Map | Integer | 4,661.275 ns | 12.4402 ns | 11.6366 ns | +// | BenchConvertTo | Map | ByteString | 4,662.482 ns | 25.7111 ns | 24.0502 ns | +// | BenchConvertTo | Map | Buffer | 4,859.809 ns | 18.2981 ns | 16.2208 ns | +// | BenchConvertTo | Map | Array | 4,627.149 ns | 10.7487 ns | 9.5285 ns | +// | BenchConvertTo | Map | Struct | 4,646.504 ns | 22.4190 ns | 20.9707 ns | +// | BenchConvertTo | Map | Map | 4.160 ns | 0.0180 ns | 0.0169 ns | +// | BenchConvertTo | Map | InteropInterface | 4,667.024 ns | 14.1790 ns | 13.2630 ns | +// | BenchConvertTo | InteropInterface | Any | 4,700.511 ns | 17.4725 ns | 15.4889 ns | +// | BenchConvertTo | InteropInterface | Pointer | 4,705.819 ns | 25.2035 ns | 23.5754 ns | +// | BenchConvertTo | InteropInterface | Boolean | 5.557 ns | 0.0244 ns | 0.0228 ns | +// | BenchConvertTo | InteropInterface | Integer | 4,695.410 ns | 21.8674 ns | 20.4547 ns | +// | BenchConvertTo | InteropInterface | ByteString | 4,674.552 ns | 18.8705 ns | 17.6515 ns | +// | BenchConvertTo | InteropInterface | Buffer | 4,649.237 ns | 23.9084 ns | 22.3639 ns | +// | BenchConvertTo | InteropInterface | Array | 4,827.652 ns | 29.7153 ns | 27.7957 ns | +// | BenchConvertTo | InteropInterface | Struct | 4,624.202 ns | 10.3563 ns | 8.0855 ns | +// | BenchConvertTo | InteropInterface | Map | 4,695.310 ns | 23.1192 ns | 21.6257 ns | +// | BenchConvertTo | InteropInterface | InteropInterface | 4.137 ns | 0.0156 ns | 0.0138 ns | diff --git a/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopy.cs b/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopyRCV1.cs similarity index 88% rename from benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopy.cs rename to benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopyRCV1.cs index 868c91add1..0d4fa48a07 100644 --- a/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopy.cs +++ b/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopyRCV1.cs @@ -1,6 +1,6 @@ // Copyright (C) 2015-2024 The Neo Project. // -// Benchmarks_DeepCopy.cs file belongs to the neo project and is free +// Benchmarks_DeepCopyRCV1.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 @@ -14,8 +14,13 @@ namespace Neo.VM.Benchmark { - public class Benchmarks_DeepCopy + public class Benchmarks_DeepCopyRCV1 { + public virtual IReferenceCounter CreateReferenceCounter() + { + return new ReferenceCounter(); + } + public IEnumerable<(int Depth, int ElementsPerLevel)> ParamSource() { int[] depths = [2, 4]; @@ -39,7 +44,7 @@ public class Benchmarks_DeepCopy [Benchmark] public void BenchNestedArrayDeepCopy() { - var root = new Array(new ReferenceCounterV2()); + var root = new Array(CreateReferenceCounter()); CreateNestedArray(root, Params.Depth, Params.ElementsPerLevel); _ = root.DeepCopy(); } @@ -47,7 +52,7 @@ public void BenchNestedArrayDeepCopy() [Benchmark] public void BenchNestedArrayDeepCopyWithReferenceCounter() { - var referenceCounter = new ReferenceCounterV2(); + var referenceCounter = CreateReferenceCounter(); var root = new Array(referenceCounter); CreateNestedArray(root, Params.Depth, Params.ElementsPerLevel, referenceCounter); _ = root.DeepCopy(); @@ -56,7 +61,7 @@ public void BenchNestedArrayDeepCopyWithReferenceCounter() [Benchmark] public void BenchNestedTestArrayDeepCopy() { - var root = new TestArray(new ReferenceCounterV2()); + var root = new TestArray(CreateReferenceCounter()); CreateNestedTestArray(root, Params.Depth, Params.ElementsPerLevel); _ = root.DeepCopy(); } @@ -64,7 +69,7 @@ public void BenchNestedTestArrayDeepCopy() [Benchmark] public void BenchNestedTestArrayDeepCopyWithReferenceCounter() { - var referenceCounter = new ReferenceCounterV2(); + var referenceCounter = CreateReferenceCounter(); var root = new TestArray(referenceCounter); CreateNestedTestArray(root, Params.Depth, Params.ElementsPerLevel, referenceCounter); _ = root.DeepCopy(); diff --git a/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopyRCV2.cs b/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopyRCV2.cs new file mode 100644 index 0000000000..dbbef32e61 --- /dev/null +++ b/benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopyRCV2.cs @@ -0,0 +1,21 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// Benchmarks_DeepCopyRCV2.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. + +namespace Neo.VM.Benchmark +{ + public class Benchmarks_DeepCopyRCV2 : Benchmarks_DeepCopyRCV1 + { + public override IReferenceCounter CreateReferenceCounter() + { + return new ReferenceCounterV2(); + } + } +} From ae56086cb460f10e3d131c191c89aa6a641b8a1a Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Thu, 21 Nov 2024 20:24:09 +0100 Subject: [PATCH 22/36] Clean interface --- src/Neo.VM/ReferenceCounter/IReferenceCounter.cs | 2 +- src/Neo.VM/ReferenceCounter/ReferenceCounter.cs | 2 +- src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs | 9 ++------- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/Neo.VM/ReferenceCounter/IReferenceCounter.cs b/src/Neo.VM/ReferenceCounter/IReferenceCounter.cs index 40c9723ccf..75902b0940 100644 --- a/src/Neo.VM/ReferenceCounter/IReferenceCounter.cs +++ b/src/Neo.VM/ReferenceCounter/IReferenceCounter.cs @@ -18,7 +18,7 @@ namespace Neo.VM /// public interface IReferenceCounter { - RCVersion Version { get; init; } + RCVersion Version { get; } /// /// Gets the count of references. diff --git a/src/Neo.VM/ReferenceCounter/ReferenceCounter.cs b/src/Neo.VM/ReferenceCounter/ReferenceCounter.cs index 4c7ac4f352..708de0e30b 100644 --- a/src/Neo.VM/ReferenceCounter/ReferenceCounter.cs +++ b/src/Neo.VM/ReferenceCounter/ReferenceCounter.cs @@ -38,7 +38,7 @@ public sealed class ReferenceCounter : IReferenceCounter // Keeps the total count of references. private int _referencesCount = 0; - public RCVersion Version { get; init; } = RCVersion.V1; + public RCVersion Version { get; } = RCVersion.V1; /// public int Count => _referencesCount; diff --git a/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs b/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs index a16f01d249..2de6f0b338 100644 --- a/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs +++ b/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs @@ -9,14 +9,9 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.VM.StronglyConnectedComponents; using Neo.VM.Types; using System; -using System.Collections.Generic; -using System.Linq; using System.Runtime.CompilerServices; -using Array = Neo.VM.Types.Array; -using Buffer = Neo.VM.Types.Buffer; namespace Neo.VM { @@ -25,7 +20,7 @@ namespace Neo.VM /// public sealed class ReferenceCounterV2 : IReferenceCounter { - public RCVersion Version { get; init; } = RCVersion.V2; + public RCVersion Version { get; } = RCVersion.V2; private readonly ExecutionEngineLimits _limits = ExecutionEngineLimits.Default; @@ -35,7 +30,7 @@ public sealed class ReferenceCounterV2 : IReferenceCounter /// public int Count => _referencesCount; - public ReferenceCounterV2(ExecutionEngineLimits limits = null) + public ReferenceCounterV2(ExecutionEngineLimits? limits = null) { _limits = limits ?? ExecutionEngineLimits.Default; } From ce7aa880471cae9cd9b1377752c4abe8c53321a9 Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Thu, 21 Nov 2024 20:26:25 +0100 Subject: [PATCH 23/36] Clean array --- src/Neo.VM/Types/Array.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Neo.VM/Types/Array.cs b/src/Neo.VM/Types/Array.cs index c937bf0e73..5a47ac234f 100644 --- a/src/Neo.VM/Types/Array.cs +++ b/src/Neo.VM/Types/Array.cs @@ -75,7 +75,8 @@ public Array(IReferenceCounter? referenceCounter, IEnumerable? items List list => list, _ => new List(items) }; - if (referenceCounter == null || referenceCounter.Version == RCVersion.V2) return; + + if (referenceCounter?.Version != RCVersion.V1) return; foreach (var item in _array) { From 0c16261c101c318e13d5c622d30a619026d04a6e Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Thu, 21 Nov 2024 20:32:04 +0100 Subject: [PATCH 24/36] Solve HF problem --- src/Neo/SmartContract/ApplicationEngine.cs | 23 ++++++++++------------ 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/Neo/SmartContract/ApplicationEngine.cs b/src/Neo/SmartContract/ApplicationEngine.cs index ca566c8601..f7f00574c7 100644 --- a/src/Neo/SmartContract/ApplicationEngine.cs +++ b/src/Neo/SmartContract/ApplicationEngine.cs @@ -176,20 +176,12 @@ public virtual UInt160 CallingScriptHash /// 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 . + /// Reference Counter /// The jump table to be used by the . protected unsafe ApplicationEngine( TriggerType trigger, IVerifiable container, DataCache snapshotCache, Block persistingBlock, - ProtocolSettings settings, long gas, IDiagnostic diagnostic, JumpTable jumpTable = null) - : base( - // this is IsHardforkEnabled - settings is not null - ? (persistingBlock is null - ? settings.Hardforks.ContainsKey(Hardfork.HF_Echidna) - : settings.IsHardforkEnabled(Hardfork.HF_Echidna, persistingBlock.Index)) - ? new ReferenceCounterV2() - : new ReferenceCounter() - : new ReferenceCounterV2(), - jumpTable ?? DefaultJumpTable) + ProtocolSettings settings, long gas, IDiagnostic diagnostic, IReferenceCounter? referenceCounter = null, JumpTable jumpTable = null) + : base(referenceCounter ?? new ReferenceCounterV2(), jumpTable ?? DefaultJumpTable) { Trigger = trigger; ScriptContainer = container; @@ -408,11 +400,16 @@ internal override void UnloadContext(ExecutionContext context) /// The engine instance created. public static ApplicationEngine Create(TriggerType trigger, IVerifiable container, DataCache snapshot, Block persistingBlock = null, ProtocolSettings settings = null, long gas = TestModeGas, IDiagnostic diagnostic = null) { + var index = persistingBlock?.Index ?? NativeContract.Ledger.CurrentIndex(snapshot); + // Adjust jump table according persistingBlock - var jumpTable = ApplicationEngine.DefaultJumpTable; + var jumpTable = DefaultJumpTable; + IReferenceCounter referenceCounter = + settings.IsHardforkEnabled(Hardfork.HF_Echidna, index) ? + new ReferenceCounterV2() : new ReferenceCounter(); return Provider?.Create(trigger, container, snapshot, persistingBlock, settings, gas, diagnostic, jumpTable) - ?? new ApplicationEngine(trigger, container, snapshot, persistingBlock, settings, gas, diagnostic, jumpTable); + ?? new ApplicationEngine(trigger, container, snapshot, persistingBlock, settings, gas, diagnostic, referenceCounter, jumpTable); } public override void LoadContext(ExecutionContext context) From c9833da45cebc9b0f6e7b23079db395a7c8af359 Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Thu, 21 Nov 2024 20:33:29 +0100 Subject: [PATCH 25/36] Fix compile --- .../Neo.UnitTests/SmartContract/UT_ApplicationEngineProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngineProvider.cs b/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngineProvider.cs index 1d9da111e1..c739849736 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngineProvider.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngineProvider.cs @@ -60,7 +60,7 @@ public ApplicationEngine Create(TriggerType trigger, IVerifiable container, Data class TestEngine : ApplicationEngine { 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) + : base(trigger, container, snapshotCache, persistingBlock, settings, gas, diagnostic, jumpTable: jumpTable) { } } From 07e8a40c385175b0db8712fc8ae137d377148ba1 Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Thu, 21 Nov 2024 20:36:09 +0100 Subject: [PATCH 26/36] Clean code --- src/Neo/SmartContract/ApplicationEngine.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Neo/SmartContract/ApplicationEngine.cs b/src/Neo/SmartContract/ApplicationEngine.cs index f7f00574c7..90a7e9e87f 100644 --- a/src/Neo/SmartContract/ApplicationEngine.cs +++ b/src/Neo/SmartContract/ApplicationEngine.cs @@ -713,7 +713,10 @@ public void SetState(T state) public bool IsHardforkEnabled(Hardfork hardfork) { // Return true if PersistingBlock is null and Hardfork is enabled - return PersistingBlock is null ? ProtocolSettings.Hardforks.ContainsKey(hardfork) : ProtocolSettings.IsHardforkEnabled(hardfork, PersistingBlock.Index); + + return PersistingBlock is null ? + ProtocolSettings.Hardforks.ContainsKey(hardfork) : + ProtocolSettings.IsHardforkEnabled(hardfork, PersistingBlock.Index); } } } From c8346d021563e380d716aace2fbfe27b10483be4 Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Thu, 21 Nov 2024 20:40:02 +0100 Subject: [PATCH 27/36] Reduce changes --- src/Neo.VM/ExecutionEngine.cs | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/Neo.VM/ExecutionEngine.cs b/src/Neo.VM/ExecutionEngine.cs index 8f99d73871..2facf0b4bc 100644 --- a/src/Neo.VM/ExecutionEngine.cs +++ b/src/Neo.VM/ExecutionEngine.cs @@ -34,7 +34,7 @@ public class ExecutionEngine : IDisposable /// /// Used for reference counting of objects in the VM. /// - public IReferenceCounter ReferenceCounter { get; set; } + public IReferenceCounter ReferenceCounter { get; } /// /// The invocation stack of the VM. @@ -86,35 +86,24 @@ protected internal set /// The reference counter to be used. /// referenceCounter is shared cross ExecutionContexts. /// The jump table to be used. - public ExecutionEngine(IReferenceCounter referenceCounter, JumpTable? jumpTable = null) + public ExecutionEngine(IReferenceCounter? referenceCounter = null, JumpTable? jumpTable = null) : this(jumpTable, referenceCounter, ExecutionEngineLimits.Default) { } - /// - /// Initializes a new instance of the class. - /// - /// The jump table to be used. - [Obsolete("Use ExecutionEngine(IReferenceCounter) to specify the reference counter.")] - public ExecutionEngine(JumpTable? jumpTable = null) - : this(jumpTable, new ReferenceCounter(), ExecutionEngineLimits.Default) - { - - } - /// /// Initializes a new instance of the class with the specified and . /// /// The jump table to be used. /// The reference counter to be used. /// Restrictions on the VM. - protected ExecutionEngine(JumpTable? jumpTable, IReferenceCounter referenceCounter, ExecutionEngineLimits limits) + protected ExecutionEngine(JumpTable? jumpTable, IReferenceCounter? referenceCounter, ExecutionEngineLimits limits) { JumpTable = jumpTable ?? JumpTable.Default; Limits = limits; - ReferenceCounter = referenceCounter; - ResultStack = new EvaluationStack(referenceCounter); + ReferenceCounter = referenceCounter ?? new ReferenceCounterV2(); + ResultStack = new EvaluationStack(ReferenceCounter); } public virtual void Dispose() @@ -312,8 +301,8 @@ protected virtual void PostExecuteInstruction(Instruction instruction) } else { - if (ReferenceCounter.Count <= Limits.MaxStackSize) return; - throw new InvalidOperationException($"MaxStackSize exceed: {ReferenceCounter.Count}/{Limits.MaxStackSize}"); + if (ReferenceCounter.Count > Limits.MaxStackSize) + throw new InvalidOperationException($"MaxStackSize exceed: {ReferenceCounter.Count}/{Limits.MaxStackSize}"); } } From c6252806f13e9367749256736f66671d81307cb2 Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Thu, 21 Nov 2024 20:44:34 +0100 Subject: [PATCH 28/36] Reduce changes in ExecutionEngine and use the same order --- src/Neo.VM/ExecutionEngine.cs | 6 ++---- src/Neo/SmartContract/ApplicationEngine.cs | 8 ++++---- tests/Neo.VM.Tests/Types/TestEngine.cs | 2 +- tests/Neo.VM.Tests/UT_ReferenceCounter.cs | 6 +++--- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/Neo.VM/ExecutionEngine.cs b/src/Neo.VM/ExecutionEngine.cs index 2facf0b4bc..7b1ad7f4a1 100644 --- a/src/Neo.VM/ExecutionEngine.cs +++ b/src/Neo.VM/ExecutionEngine.cs @@ -83,13 +83,11 @@ protected internal set /// /// Initializes a new instance of the class. /// - /// The reference counter to be used. - /// referenceCounter is shared cross ExecutionContexts. /// The jump table to be used. - public ExecutionEngine(IReferenceCounter? referenceCounter = null, JumpTable? jumpTable = null) + /// The reference counter to be used. + public ExecutionEngine(JumpTable? jumpTable = null, IReferenceCounter? referenceCounter = null) : this(jumpTable, referenceCounter, ExecutionEngineLimits.Default) { - } /// diff --git a/src/Neo/SmartContract/ApplicationEngine.cs b/src/Neo/SmartContract/ApplicationEngine.cs index 90a7e9e87f..2dbdd184e5 100644 --- a/src/Neo/SmartContract/ApplicationEngine.cs +++ b/src/Neo/SmartContract/ApplicationEngine.cs @@ -176,12 +176,12 @@ public virtual UInt160 CallingScriptHash /// 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 . - /// Reference Counter /// The jump table to be used by the . + /// Reference Counter protected unsafe ApplicationEngine( TriggerType trigger, IVerifiable container, DataCache snapshotCache, Block persistingBlock, - ProtocolSettings settings, long gas, IDiagnostic diagnostic, IReferenceCounter? referenceCounter = null, JumpTable jumpTable = null) - : base(referenceCounter ?? new ReferenceCounterV2(), jumpTable ?? DefaultJumpTable) + ProtocolSettings settings, long gas, IDiagnostic diagnostic, JumpTable jumpTable = null, IReferenceCounter? referenceCounter = null) + : base(jumpTable ?? DefaultJumpTable, referenceCounter ?? new ReferenceCounterV2()) { Trigger = trigger; ScriptContainer = container; @@ -409,7 +409,7 @@ public static ApplicationEngine Create(TriggerType trigger, IVerifiable containe new ReferenceCounterV2() : new ReferenceCounter(); return Provider?.Create(trigger, container, snapshot, persistingBlock, settings, gas, diagnostic, jumpTable) - ?? new ApplicationEngine(trigger, container, snapshot, persistingBlock, settings, gas, diagnostic, referenceCounter, jumpTable); + ?? new ApplicationEngine(trigger, container, snapshot, persistingBlock, settings, gas, diagnostic, jumpTable, referenceCounter); } public override void LoadContext(ExecutionContext context) diff --git a/tests/Neo.VM.Tests/Types/TestEngine.cs b/tests/Neo.VM.Tests/Types/TestEngine.cs index f781990136..2602163315 100644 --- a/tests/Neo.VM.Tests/Types/TestEngine.cs +++ b/tests/Neo.VM.Tests/Types/TestEngine.cs @@ -19,7 +19,7 @@ public class TestEngine : ExecutionEngine { public Exception FaultException { get; private set; } - public TestEngine() : base(new ReferenceCounterV2(), ComposeJumpTable()) { } + public TestEngine() : base(ComposeJumpTable()) { } private static JumpTable ComposeJumpTable() { diff --git a/tests/Neo.VM.Tests/UT_ReferenceCounter.cs b/tests/Neo.VM.Tests/UT_ReferenceCounter.cs index 1acf79460c..6ce0dae21f 100644 --- a/tests/Neo.VM.Tests/UT_ReferenceCounter.cs +++ b/tests/Neo.VM.Tests/UT_ReferenceCounter.cs @@ -136,7 +136,7 @@ public void TestRemoveReferrer() sb.Emit(OpCode.DROP); //{}|{B[]}:1 sb.Emit(OpCode.RET); //{}:0 - using ExecutionEngine engine = new(new ReferenceCounterV2()); + using ExecutionEngine engine = new(); Debugger debugger = new(engine); engine.LoadScript(sb.ToArray()); Assert.AreEqual(VMState.BREAK, debugger.StepInto()); @@ -234,7 +234,7 @@ public void TestArrayNoPush() { using ScriptBuilder sb = new(); sb.Emit(OpCode.RET); - using ExecutionEngine engine = new(new ReferenceCounterV2()); + using ExecutionEngine engine = new(); engine.LoadScript(sb.ToArray()); Assert.AreEqual(0, engine.ReferenceCounter.Count); Array array = new(new StackItem[] { 1, 2, 3, 4 }); @@ -258,7 +258,7 @@ public void TestInvalidReferenceStackItem() arr.Add(arr2); - var engine = new ExecutionEngine(new ReferenceCounterV2()); + var engine = new ExecutionEngine(); engine.LoadScript(new Script((byte[])[(byte)OpCode.NOP])); engine.CurrentContext.EvaluationStack.Push(arr); From d2960fa18056afea53646c12c5e3cfd6d70c283a Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Thu, 21 Nov 2024 20:49:28 +0100 Subject: [PATCH 29/36] Fix bug and optimize --- src/Neo.VM/JumpTable/JumpTable.Compound.cs | 7 +++---- src/Neo.VM/Types/Map.cs | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/Neo.VM/JumpTable/JumpTable.Compound.cs b/src/Neo.VM/JumpTable/JumpTable.Compound.cs index 0054cc5ad1..fc96d3274f 100644 --- a/src/Neo.VM/JumpTable/JumpTable.Compound.cs +++ b/src/Neo.VM/JumpTable/JumpTable.Compound.cs @@ -542,13 +542,12 @@ public virtual void Remove(ExecutionEngine engine, Instruction instruction) engine.ReferenceCounter.RemoveStackReference(item); break; case Map map: - if (engine.ReferenceCounter.Version == RCVersion.V2) + var old = map.RemoveKey(key); + if (old != null && engine.ReferenceCounter.Version == RCVersion.V2) { engine.ReferenceCounter.RemoveStackReference(key); - engine.ReferenceCounter.RemoveStackReference(map[key]); + engine.ReferenceCounter.RemoveStackReference(old); } - - map.Remove(key); break; default: throw new InvalidOperationException($"Invalid type for {instruction.OpCode}: {x.Type}"); diff --git a/src/Neo.VM/Types/Map.cs b/src/Neo.VM/Types/Map.cs index 7f7b726d63..fddbdb2eae 100644 --- a/src/Neo.VM/Types/Map.cs +++ b/src/Neo.VM/Types/Map.cs @@ -160,6 +160,27 @@ public bool Remove(PrimitiveType key) return true; } + /// + /// Removes the element with the specified key from the map. + /// + /// The key of the element to remove. + /// + /// if the element is successfully removed; + /// otherwise, . + /// This method also returns if was not found in the original map. + /// + public StackItem? RemoveKey(PrimitiveType key) + { + if (key.Size > MaxKeySize) + throw new ArgumentException($"Can not remove key from map, MaxKeySize of {nameof(Types.Map)} is exceeded: {key.Size}/{MaxKeySize}."); + if (IsReadOnly) throw new InvalidOperationException("The map is readonly, can not remove key."); + if (!dictionary.Remove(key, out StackItem? old_value)) + return null; + ReferenceCounter?.RemoveReference(key, this); + ReferenceCounter?.RemoveReference(old_value, this); + return old_value; + } + /// /// Gets the value that is associated with the specified key. /// From a3901cbafd0a9b9e650966e88e913b95627899b7 Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Thu, 21 Nov 2024 20:51:25 +0100 Subject: [PATCH 30/36] Fix comment --- src/Neo.VM/Types/Map.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Neo.VM/Types/Map.cs b/src/Neo.VM/Types/Map.cs index fddbdb2eae..2376685716 100644 --- a/src/Neo.VM/Types/Map.cs +++ b/src/Neo.VM/Types/Map.cs @@ -165,9 +165,8 @@ public bool Remove(PrimitiveType key) /// /// The key of the element to remove. /// - /// if the element is successfully removed; - /// otherwise, . - /// This method also returns if was not found in the original map. + /// if the element is successfully removed; + /// otherwise, . /// public StackItem? RemoveKey(PrimitiveType key) { From 4a65dfd4896316c0627fdb2be261e3cb608b1297 Mon Sep 17 00:00:00 2001 From: Shargon Date: Thu, 21 Nov 2024 11:52:01 -0800 Subject: [PATCH 31/36] Update src/Neo.VM/JumpTable/JumpTable.Compound.cs --- src/Neo.VM/JumpTable/JumpTable.Compound.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Neo.VM/JumpTable/JumpTable.Compound.cs b/src/Neo.VM/JumpTable/JumpTable.Compound.cs index fc96d3274f..3dce301104 100644 --- a/src/Neo.VM/JumpTable/JumpTable.Compound.cs +++ b/src/Neo.VM/JumpTable/JumpTable.Compound.cs @@ -452,7 +452,7 @@ public virtual void SetItem(ExecutionEngine engine, Instruction instruction) engine.ReferenceCounter.RemoveStackReference(array[index]); array[index] = value; if (isRC2) - engine.ReferenceCounter.AddStackReference(array[index]); + engine.ReferenceCounter.AddStackReference(value); break; } case Map map: From 8e77783a330324a9d9be26f9076356564363e1ac Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Thu, 21 Nov 2024 21:05:26 +0100 Subject: [PATCH 32/36] Avoid exceptions if old method is called --- src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs b/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs index 2de6f0b338..f092dcd37c 100644 --- a/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs +++ b/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs @@ -35,17 +35,10 @@ public ReferenceCounterV2(ExecutionEngineLimits? limits = null) _limits = limits ?? ExecutionEngineLimits.Default; } - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool NeedTrack(StackItem item) - { - throw new NotImplementedException(); - } - /// public void AddReference(StackItem item, CompoundType parent) { - throw new NotImplementedException(); + // This call should not be made } /// @@ -74,7 +67,7 @@ public void AddStackReference(StackItem item, int count = 1) /// public void AddZeroReferred(StackItem item) { - throw new NotImplementedException(); + // This call should not be made } /// @@ -86,7 +79,7 @@ public int CheckZeroReferred() /// public void RemoveReference(StackItem item, CompoundType parent) { - throw new NotImplementedException(); + // This call should not be made } /// From 92b2873a95b4d3be628204cf5f94fa67885507cd Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Thu, 21 Nov 2024 21:09:58 +0100 Subject: [PATCH 33/36] Move logic to CheckPostExecution --- src/Neo.VM/ExecutionEngine.cs | 12 +----------- .../ReferenceCounter/IReferenceCounter.cs | 6 ++---- src/Neo.VM/ReferenceCounter/ReferenceCounter.cs | 17 ++++++++++++++++- .../ReferenceCounter/ReferenceCounterV2.cs | 8 ++++---- 4 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/Neo.VM/ExecutionEngine.cs b/src/Neo.VM/ExecutionEngine.cs index 7b1ad7f4a1..977d534466 100644 --- a/src/Neo.VM/ExecutionEngine.cs +++ b/src/Neo.VM/ExecutionEngine.cs @@ -291,17 +291,7 @@ public T Pop() where T : StackItem /// protected virtual void PostExecuteInstruction(Instruction instruction) { - if (ReferenceCounter.Version == RCVersion.V1) - { - if (ReferenceCounter.Count < Limits.MaxStackSize) return; - if (ReferenceCounter.CheckZeroReferred() > Limits.MaxStackSize) - throw new InvalidOperationException($"MaxStackSize exceed: {ReferenceCounter.Count}/{Limits.MaxStackSize}"); - } - else - { - if (ReferenceCounter.Count > Limits.MaxStackSize) - throw new InvalidOperationException($"MaxStackSize exceed: {ReferenceCounter.Count}/{Limits.MaxStackSize}"); - } + ReferenceCounter.CheckPostExecution(); } /// diff --git a/src/Neo.VM/ReferenceCounter/IReferenceCounter.cs b/src/Neo.VM/ReferenceCounter/IReferenceCounter.cs index 75902b0940..beb1715225 100644 --- a/src/Neo.VM/ReferenceCounter/IReferenceCounter.cs +++ b/src/Neo.VM/ReferenceCounter/IReferenceCounter.cs @@ -84,10 +84,8 @@ public interface IReferenceCounter void RemoveStackReference(StackItem item); /// - /// Checks and processes items that have zero references. - /// This method is used to check items in the zero-referred list and clean up those that are no longer needed. + /// Called after an instruction is executed. /// - /// The current reference count. - int CheckZeroReferred(); + void CheckPostExecution(); } } diff --git a/src/Neo.VM/ReferenceCounter/ReferenceCounter.cs b/src/Neo.VM/ReferenceCounter/ReferenceCounter.cs index 708de0e30b..8d69faa440 100644 --- a/src/Neo.VM/ReferenceCounter/ReferenceCounter.cs +++ b/src/Neo.VM/ReferenceCounter/ReferenceCounter.cs @@ -22,6 +22,8 @@ namespace Neo.VM /// public sealed class ReferenceCounter : IReferenceCounter { + private readonly ExecutionEngineLimits _limits; + // If set to true, all items will be tracked regardless of their type. private const bool TrackAllItems = false; @@ -43,6 +45,11 @@ public sealed class ReferenceCounter : IReferenceCounter /// public int Count => _referencesCount; + public ReferenceCounter(ExecutionEngineLimits? limits = null) + { + _limits = limits ?? ExecutionEngineLimits.Default; + } + /// /// Determines if an item needs to be tracked based on its type. /// @@ -123,6 +130,14 @@ public void AddZeroReferred(StackItem item) _trackedItems.Add(item); } + /// + public void CheckPostExecution() + { + if (Count < _limits.MaxStackSize) return; + if (CheckZeroReferred() > _limits.MaxStackSize) + throw new System.InvalidOperationException($"MaxStackSize exceed: {Count}/{_limits.MaxStackSize}"); + } + /// /// Checks and processes items that have zero references. /// @@ -132,7 +147,7 @@ public void AddZeroReferred(StackItem item) /// Use this method periodically to clean up items with zero references and free up memory. /// /// The current reference count. - public int CheckZeroReferred() + private int CheckZeroReferred() { // If there are items with zero references, process them. if (_zeroReferred.Count > 0) diff --git a/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs b/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs index f092dcd37c..06b2c5ea90 100644 --- a/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs +++ b/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs @@ -11,7 +11,6 @@ using Neo.VM.Types; using System; -using System.Runtime.CompilerServices; namespace Neo.VM { @@ -22,7 +21,7 @@ public sealed class ReferenceCounterV2 : IReferenceCounter { public RCVersion Version { get; } = RCVersion.V2; - private readonly ExecutionEngineLimits _limits = ExecutionEngineLimits.Default; + private readonly ExecutionEngineLimits _limits; // Keeps the total count of references. private int _referencesCount = 0; @@ -71,9 +70,10 @@ public void AddZeroReferred(StackItem item) } /// - public int CheckZeroReferred() + public void CheckPostExecution() { - throw new NotImplementedException(); + if (Count > _limits.MaxStackSize) + throw new InvalidOperationException($"MaxStackSize exceed: {Count}/{_limits.MaxStackSize}"); } /// From 6dbc1042f6c4fceaf232368f0053b728d0c1005f Mon Sep 17 00:00:00 2001 From: Shargon Date: Thu, 19 Dec 2024 05:21:37 -0800 Subject: [PATCH 34/36] Update src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs Co-authored-by: nan01ab --- src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs b/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs index 06b2c5ea90..acbf43064b 100644 --- a/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs +++ b/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs @@ -92,7 +92,7 @@ public void RemoveStackReference(StackItem item) if (item is CompoundType compoundType) { - // Increment the item's stack references by the specified count. + // Decrease the item's stack references. compoundType.StackReferences--; if (compoundType.StackReferences < 0) From 552991f951d9f92463e4ec41c3b4e014184f99a8 Mon Sep 17 00:00:00 2001 From: Shargon Date: Thu, 19 Dec 2024 05:22:02 -0800 Subject: [PATCH 35/36] Update src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs Co-authored-by: nan01ab --- src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs b/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs index acbf43064b..b3db7548cf 100644 --- a/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs +++ b/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs @@ -85,7 +85,7 @@ public void RemoveReference(StackItem item, CompoundType parent) /// public void RemoveStackReference(StackItem item) { - // Increment the reference count by the specified count. + // Decrease the reference count. _referencesCount--; if (_referencesCount < 0) throw new IndexOutOfRangeException("Circular reference detected, execution stopped."); From 95f6535c470d6736f103d231b3f282c04b9c0225 Mon Sep 17 00:00:00 2001 From: Shargon Date: Tue, 7 Jan 2025 03:48:10 -0800 Subject: [PATCH 36/36] Update src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs Co-authored-by: Hecate2 --- src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs b/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs index b3db7548cf..614dfa196d 100644 --- a/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs +++ b/src/Neo.VM/ReferenceCounter/ReferenceCounterV2.cs @@ -47,7 +47,7 @@ public void AddStackReference(StackItem item, int count = 1) _referencesCount += count; if (_referencesCount > _limits.MaxStackSize) - throw new IndexOutOfRangeException("Circular reference detected, execution stopped."); + throw new IndexOutOfRangeException("Circular reference or too many VM StackItems."); if (item is CompoundType compoundType) { // Increment the item's stack references by the specified count.