diff --git a/src/neo/SmartContract/ApplicationEngine.Runtime.cs b/src/neo/SmartContract/ApplicationEngine.Runtime.cs index a7dd969582..a000f06e34 100644 --- a/src/neo/SmartContract/ApplicationEngine.Runtime.cs +++ b/src/neo/SmartContract/ApplicationEngine.Runtime.cs @@ -157,6 +157,7 @@ internal void SendNotification(UInt160 hash, string eventName, Array state) { NotifyEventArgs notification = new NotifyEventArgs(ScriptContainer, hash, eventName, (Array)state.DeepCopy()); Notify?.Invoke(this, notification); + notifications ??= new List(); notifications.Add(notification); } diff --git a/src/neo/SmartContract/ApplicationEngine.Storage.cs b/src/neo/SmartContract/ApplicationEngine.Storage.cs index 73aace9c37..97ccb5494c 100644 --- a/src/neo/SmartContract/ApplicationEngine.Storage.cs +++ b/src/neo/SmartContract/ApplicationEngine.Storage.cs @@ -1,6 +1,7 @@ using Neo.Ledger; using Neo.SmartContract.Iterators; using System; +using System.Collections.Generic; using System.Linq; namespace Neo.SmartContract @@ -66,6 +67,7 @@ internal IIterator Find(StorageContext context, byte[] prefix) { byte[] prefix_key = StorageKey.CreateSearchPrefix(context.Id, prefix); StorageIterator iterator = new StorageIterator(Snapshot.Storages.Find(prefix_key).Where(p => p.Key.Key.AsSpan().StartsWith(prefix)).GetEnumerator()); + disposables ??= new List(); disposables.Add(iterator); return iterator; } diff --git a/src/neo/SmartContract/ApplicationEngine.cs b/src/neo/SmartContract/ApplicationEngine.cs index 30fc027be0..05f963ddb2 100644 --- a/src/neo/SmartContract/ApplicationEngine.cs +++ b/src/neo/SmartContract/ApplicationEngine.cs @@ -26,13 +26,11 @@ private class InvocationState public static event EventHandler Notify; public static event EventHandler Log; - public const long GasFree = 0; - private static Dictionary services; private readonly long gas_amount; private readonly bool testMode; - private readonly List notifications = new List(); - private readonly List disposables = new List(); + private List notifications; + private List disposables; private readonly Dictionary invocationCounter = new Dictionary(); private readonly Dictionary invocationStates = new Dictionary(); @@ -45,15 +43,15 @@ private class InvocationState public UInt160 CurrentScriptHash => CurrentContext?.GetState().ScriptHash; public UInt160 CallingScriptHash => CurrentContext?.GetState().CallingScriptHash; public UInt160 EntryScriptHash => EntryContext?.GetState().ScriptHash; - public IReadOnlyList Notifications => notifications; + public IReadOnlyList Notifications => notifications ?? (IReadOnlyList)Array.Empty(); public ApplicationEngine(TriggerType trigger, IVerifiable container, StoreView snapshot, long gas, bool testMode = false) { - this.gas_amount = GasFree + gas; - this.testMode = testMode; this.Trigger = trigger; this.ScriptContainer = container; this.Snapshot = snapshot; + this.gas_amount = gas; + this.testMode = testMode; } internal void AddGas(long gas) @@ -196,9 +194,12 @@ internal object Convert(StackItem item, InteropParameterDescriptor descriptor) public override void Dispose() { - foreach (IDisposable disposable in disposables) - disposable.Dispose(); - disposables.Clear(); + if (disposables != null) + { + foreach (IDisposable disposable in disposables) + disposable.Dispose(); + disposables = null; + } base.Dispose(); } @@ -259,20 +260,20 @@ private static InteropDescriptor Register(string name, string handler, long fixe } public static ApplicationEngine Run(byte[] script, StoreView snapshot, - IVerifiable container = null, Block persistingBlock = null, int offset = 0, bool testMode = false, long extraGAS = default) + IVerifiable container = null, Block persistingBlock = null, int offset = 0, bool testMode = false, long gas = default) { snapshot.PersistingBlock = persistingBlock ?? snapshot.PersistingBlock ?? CreateDummyBlock(snapshot); - ApplicationEngine engine = new ApplicationEngine(TriggerType.Application, container, snapshot, extraGAS, testMode); + ApplicationEngine engine = new ApplicationEngine(TriggerType.Application, container, snapshot, gas, testMode); engine.LoadScript(script).InstructionPointer = offset; engine.Execute(); return engine; } - public static ApplicationEngine Run(byte[] script, IVerifiable container = null, Block persistingBlock = null, int offset = 0, bool testMode = false, long extraGAS = default) + public static ApplicationEngine Run(byte[] script, IVerifiable container = null, Block persistingBlock = null, int offset = 0, bool testMode = false, long gas = default) { using (SnapshotView snapshot = Blockchain.Singleton.GetSnapshot()) { - return Run(script, snapshot, container, persistingBlock, offset, testMode, extraGAS); + return Run(script, snapshot, container, persistingBlock, offset, testMode, gas); } } } diff --git a/src/neo/Wallets/AssetDescriptor.cs b/src/neo/Wallets/AssetDescriptor.cs index c49712f7ec..9f6a4d4c18 100644 --- a/src/neo/Wallets/AssetDescriptor.cs +++ b/src/neo/Wallets/AssetDescriptor.cs @@ -19,7 +19,7 @@ public AssetDescriptor(UInt160 asset_id) sb.EmitAppCall(asset_id, "name"); script = sb.ToArray(); } - using ApplicationEngine engine = ApplicationEngine.Run(script, extraGAS: 3_000_000); + using ApplicationEngine engine = ApplicationEngine.Run(script, gas: 3_000_000); if (engine.State.HasFlag(VMState.FAULT)) throw new ArgumentException(); this.AssetId = asset_id; this.AssetName = engine.ResultStack.Pop().GetString(); diff --git a/src/neo/Wallets/Wallet.cs b/src/neo/Wallets/Wallet.cs index 69708cca42..d70fa23f8b 100644 --- a/src/neo/Wallets/Wallet.cs +++ b/src/neo/Wallets/Wallet.cs @@ -143,7 +143,7 @@ public BigDecimal GetBalance(UInt160 asset_id, params UInt160[] accounts) sb.EmitAppCall(asset_id, "decimals"); script = sb.ToArray(); } - using ApplicationEngine engine = ApplicationEngine.Run(script, extraGAS: 20000000L * accounts.Length); + using ApplicationEngine engine = ApplicationEngine.Run(script, gas: 20000000L * accounts.Length); if (engine.State.HasFlag(VMState.FAULT)) return new BigDecimal(0, 0); byte decimals = (byte)engine.ResultStack.Pop().GetInteger(); @@ -329,7 +329,7 @@ private Transaction MakeTransaction(StoreView snapshot, byte[] script, Transacti { if (engine.State.HasFlag(VMState.FAULT)) throw new InvalidOperationException($"Failed execution for '{script.ToHexString()}'"); - tx.SystemFee = Math.Max(engine.GasConsumed - ApplicationEngine.GasFree, 0); + tx.SystemFee = engine.GasConsumed; } UInt160[] hashes = tx.GetScriptHashesForVerifying(snapshot); diff --git a/src/neo/neo.csproj b/src/neo/neo.csproj index e3ee5b5259..d1694c67c2 100644 --- a/src/neo/neo.csproj +++ b/src/neo/neo.csproj @@ -27,7 +27,7 @@ - +